Sync with HEAD - tag prg-localcount2-base1 prg-localcount2
authorpgoyette <pgoyette@NetBSD.org>
Tue, 02 May 2017 03:19:14 +0000
branchprg-localcount2
changeset 279099 19ad2a14f697
parent 279098 f845dfac7294
child 279100 26f92c4e9760
Sync with HEAD - tag prg-localcount2-base1
bin/csh/glob.c
bin/ksh/misc.c
bin/sh/expand.c
bin/sh/expand.h
bin/sh/input.c
bin/sh/jobs.c
bin/sh/redir.c
bin/sh/redir.h
bin/sh/sh.1
bin/sh/trap.c
bin/sh/var.c
distrib/sets/lists/comp/mi
distrib/sets/lists/tests/mi
doc/3RDPARTY
doc/BRANCHES
doc/CHANGES
external/bsd/acpica/bin/iasl/Makefile
external/mit/lua/dist/Makefile
external/mit/lua/dist/README
external/mit/lua/dist/doc/contents.html
external/mit/lua/dist/doc/logo.gif
external/mit/lua/dist/doc/lua.1
external/mit/lua/dist/doc/luac.1
external/mit/lua/dist/doc/manual.html
external/mit/lua/dist/doc/readme.html
external/mit/lua/dist/src/lapi.c
external/mit/lua/dist/src/lapi.h
external/mit/lua/dist/src/lauxlib.c
external/mit/lua/dist/src/lauxlib.h
external/mit/lua/dist/src/lbaselib.c
external/mit/lua/dist/src/lbitlib.c
external/mit/lua/dist/src/lcode.c
external/mit/lua/dist/src/lcode.h
external/mit/lua/dist/src/lcorolib.c
external/mit/lua/dist/src/lctype.c
external/mit/lua/dist/src/lctype.h
external/mit/lua/dist/src/ldblib.c
external/mit/lua/dist/src/ldebug.c
external/mit/lua/dist/src/ldebug.h
external/mit/lua/dist/src/ldo.c
external/mit/lua/dist/src/ldo.h
external/mit/lua/dist/src/ldump.c
external/mit/lua/dist/src/lfunc.c
external/mit/lua/dist/src/lfunc.h
external/mit/lua/dist/src/lgc.c
external/mit/lua/dist/src/lgc.h
external/mit/lua/dist/src/linit.c
external/mit/lua/dist/src/liolib.c
external/mit/lua/dist/src/llex.c
external/mit/lua/dist/src/llex.h
external/mit/lua/dist/src/llimits.h
external/mit/lua/dist/src/lmathlib.c
external/mit/lua/dist/src/lmem.c
external/mit/lua/dist/src/lmem.h
external/mit/lua/dist/src/loadlib.c
external/mit/lua/dist/src/lobject.c
external/mit/lua/dist/src/lobject.h
external/mit/lua/dist/src/lopcodes.c
external/mit/lua/dist/src/lopcodes.h
external/mit/lua/dist/src/loslib.c
external/mit/lua/dist/src/lparser.c
external/mit/lua/dist/src/lparser.h
external/mit/lua/dist/src/lprefix.h
external/mit/lua/dist/src/lstate.c
external/mit/lua/dist/src/lstate.h
external/mit/lua/dist/src/lstring.c
external/mit/lua/dist/src/lstring.h
external/mit/lua/dist/src/lstrlib.c
external/mit/lua/dist/src/ltable.c
external/mit/lua/dist/src/ltable.h
external/mit/lua/dist/src/ltablib.c
external/mit/lua/dist/src/ltm.c
external/mit/lua/dist/src/ltm.h
external/mit/lua/dist/src/lua.c
external/mit/lua/dist/src/lua.h
external/mit/lua/dist/src/luac.c
external/mit/lua/dist/src/luaconf.h
external/mit/lua/dist/src/lualib.h
external/mit/lua/dist/src/lundump.c
external/mit/lua/dist/src/lundump.h
external/mit/lua/dist/src/lutf8lib.c
external/mit/lua/dist/src/lvm.c
external/mit/lua/dist/src/lvm.h
external/mit/lua/dist/src/lzio.c
external/mit/lua/dist/src/lzio.h
lib/libc/gen/glob.c
lib/libterminfo/termcap.c
lib/libterminfo/tputs.c
libexec/ld.elf_so/reloc.c
sbin/fsck_msdos/dir.c
sbin/nvmectl/Makefile
sbin/nvmectl/firmware.c
sbin/nvmectl/logpage.c
sbin/nvmectl/nvme.h
sbin/nvmectl/nvmectl.8
sbin/nvmectl/nvmectl.c
sbin/nvmectl/nvmectl.h
sbin/nvmectl/wdc.c
share/man/man4/midi.4
share/man/man4/nvme.4
share/man/man8/compat_freebsd.8
share/man/man9/Makefile
share/man/man9/devsw_attach.9
share/man/man9/driver.9
share/man/man9/mutex.9
sys/arch/amd64/conf/ALL
sys/arch/arm/nvidia/files.tegra
sys/arch/arm/nvidia/tegra124_car.c
sys/arch/arm/nvidia/tegra124_cpu.c
sys/arch/arm/nvidia/tegra_apbdma.c
sys/arch/arm/nvidia/tegra_apbdmareg.h
sys/arch/arm/nvidia/tegra_xusb.c
sys/arch/evbarm/conf/TEGRA
sys/arch/i386/stand/efiboot/Makefile.efiboot
sys/arch/i386/stand/efiboot/boot.c
sys/arch/i386/stand/efiboot/bootia32/efibootia32.c
sys/arch/i386/stand/efiboot/bootia32/start.S
sys/arch/i386/stand/efiboot/bootx64/efibootx64.c
sys/arch/i386/stand/efiboot/bootx64/start.S
sys/arch/i386/stand/efiboot/efiboot.h
sys/arch/i386/stand/efiboot/eficons.c
sys/arch/mips/mips/cache_r4k_subr.S
sys/arch/mips/mips/cache_r5k.c
sys/arch/next68k/dev/zs.c
sys/arch/sparc/stand/boot/Makefile
sys/arch/sparc64/dev/ffb.c
sys/arch/x86/include/i82489reg.h
sys/compat/common/vm_43.c
sys/compat/linux32/arch/amd64/linux32_exec.h
sys/compat/netbsd32/netbsd32_netbsd.c
sys/compat/sys/mman.h
sys/dev/audio.c
sys/dev/dksubr.c
sys/dev/dkvar.h
sys/dev/fdt/fdt_dma.c
sys/dev/fdt/fdt_subr.c
sys/dev/fdt/fdtbus.c
sys/dev/fdt/fdtvar.h
sys/dev/fdt/files.fdt
sys/dev/i2c/as3722.c
sys/dev/ic/ld_nvme.c
sys/dev/isa/tpm_isa.c
sys/dev/ld.c
sys/dev/ldvar.h
sys/dev/ofw/ofw_subr.c
sys/dev/ofw/openfirm.h
sys/dev/pci/com_puc.c
sys/dev/pci/hdaudio_pci.c
sys/dev/pci/if_bge.c
sys/dev/pci/if_re_pci.c
sys/dev/pci/ismt.c
sys/dev/pci/ixgbe/ixgbe.c
sys/dev/pci/lpt_puc.c
sys/dev/pci/pci_subr.c
sys/dev/pci/pcidevs
sys/dev/pci/pcidevs.h
sys/dev/pci/pcidevs_data.h
sys/dev/pci/ppb.c
sys/dev/pci/sdhc_pci.c
sys/dev/pci/uhci_pci.c
sys/dev/wscons/wsdisplay_vcons.c
sys/external/bsd/acpica/dist/changes.txt
sys/external/bsd/acpica/dist/common/adisasm.c
sys/external/bsd/acpica/dist/common/adwalk.c
sys/external/bsd/acpica/dist/common/dmextern.c
sys/external/bsd/acpica/dist/common/dmrestag.c
sys/external/bsd/acpica/dist/common/dmtables.c
sys/external/bsd/acpica/dist/common/dmtbinfo.c
sys/external/bsd/acpica/dist/compiler/aslcodegen.c
sys/external/bsd/acpica/dist/compiler/aslcompile.c
sys/external/bsd/acpica/dist/compiler/aslcompiler.h
sys/external/bsd/acpica/dist/compiler/aslcompiler.l
sys/external/bsd/acpica/dist/compiler/asldebug.c
sys/external/bsd/acpica/dist/compiler/asldefine.h
sys/external/bsd/acpica/dist/compiler/aslfiles.c
sys/external/bsd/acpica/dist/compiler/aslglobal.h
sys/external/bsd/acpica/dist/compiler/aslhelp.c
sys/external/bsd/acpica/dist/compiler/asllength.c
sys/external/bsd/acpica/dist/compiler/aslmap.c
sys/external/bsd/acpica/dist/compiler/asloffset.c
sys/external/bsd/acpica/dist/compiler/asloperands.c
sys/external/bsd/acpica/dist/compiler/asloptions.c
sys/external/bsd/acpica/dist/compiler/aslprimaries.y
sys/external/bsd/acpica/dist/compiler/aslprintf.c
sys/external/bsd/acpica/dist/compiler/aslresources.y
sys/external/bsd/acpica/dist/compiler/aslrules.y
sys/external/bsd/acpica/dist/compiler/aslstartup.c
sys/external/bsd/acpica/dist/compiler/aslsupport.l
sys/external/bsd/acpica/dist/compiler/asltree.c
sys/external/bsd/acpica/dist/compiler/asltypes.h
sys/external/bsd/acpica/dist/compiler/aslwalks.c
sys/external/bsd/acpica/dist/compiler/cvcompiler.c
sys/external/bsd/acpica/dist/compiler/cvdisasm.c
sys/external/bsd/acpica/dist/compiler/cvparser.c
sys/external/bsd/acpica/dist/compiler/dttable1.c
sys/external/bsd/acpica/dist/compiler/dttemplate.h
sys/external/bsd/acpica/dist/debugger/dbmethod.c
sys/external/bsd/acpica/dist/debugger/dbxface.c
sys/external/bsd/acpica/dist/disassembler/dmcstyle.c
sys/external/bsd/acpica/dist/disassembler/dmdeferred.c
sys/external/bsd/acpica/dist/disassembler/dmnames.c
sys/external/bsd/acpica/dist/disassembler/dmopcode.c
sys/external/bsd/acpica/dist/disassembler/dmutils.c
sys/external/bsd/acpica/dist/disassembler/dmwalk.c
sys/external/bsd/acpica/dist/dispatcher/dscontrol.c
sys/external/bsd/acpica/dist/dispatcher/dsmthdat.c
sys/external/bsd/acpica/dist/dispatcher/dsobject.c
sys/external/bsd/acpica/dist/dispatcher/dsopcode.c
sys/external/bsd/acpica/dist/dispatcher/dsutils.c
sys/external/bsd/acpica/dist/dispatcher/dswexec.c
sys/external/bsd/acpica/dist/dispatcher/dswload2.c
sys/external/bsd/acpica/dist/executer/exmisc.c
sys/external/bsd/acpica/dist/executer/exnames.c
sys/external/bsd/acpica/dist/executer/exoparg1.c
sys/external/bsd/acpica/dist/executer/exoparg2.c
sys/external/bsd/acpica/dist/executer/exoparg6.c
sys/external/bsd/acpica/dist/executer/exresolv.c
sys/external/bsd/acpica/dist/executer/exstore.c
sys/external/bsd/acpica/dist/executer/exstoren.c
sys/external/bsd/acpica/dist/generate/unix/Makefile.config
sys/external/bsd/acpica/dist/generate/unix/iasl/Makefile
sys/external/bsd/acpica/dist/hardware/hwvalid.c
sys/external/bsd/acpica/dist/include/acconfig.h
sys/external/bsd/acpica/dist/include/acconvert.h
sys/external/bsd/acpica/dist/include/acdisasm.h
sys/external/bsd/acpica/dist/include/acglobal.h
sys/external/bsd/acpica/dist/include/aclocal.h
sys/external/bsd/acpica/dist/include/acmacros.h
sys/external/bsd/acpica/dist/include/acopcode.h
sys/external/bsd/acpica/dist/include/acpixf.h
sys/external/bsd/acpica/dist/include/actbl2.h
sys/external/bsd/acpica/dist/include/amlcode.h
sys/external/bsd/acpica/dist/namespace/nsaccess.c
sys/external/bsd/acpica/dist/namespace/nsrepair.c
sys/external/bsd/acpica/dist/namespace/nsrepair2.c
sys/external/bsd/acpica/dist/namespace/nsutils.c
sys/external/bsd/acpica/dist/parser/psargs.c
sys/external/bsd/acpica/dist/parser/psloop.c
sys/external/bsd/acpica/dist/parser/psobject.c
sys/external/bsd/acpica/dist/parser/psopcode.c
sys/external/bsd/acpica/dist/parser/psopinfo.c
sys/external/bsd/acpica/dist/parser/psparse.c
sys/external/bsd/acpica/dist/parser/pstree.c
sys/external/bsd/acpica/dist/parser/psutils.c
sys/external/bsd/acpica/dist/tools/acpisrc/acpisrc.h
sys/external/bsd/acpica/dist/tools/acpisrc/astable.c
sys/external/bsd/acpica/dist/utilities/utalloc.c
sys/external/bsd/acpica/dist/utilities/utcache.c
sys/external/bsd/acpica/dist/utilities/utdebug.c
sys/external/bsd/acpica/dist/utilities/utresrc.c
sys/external/bsd/acpica/dist/utilities/utxferror.c
sys/kern/kern_event.c
sys/kern/kern_mutex.c
sys/kern/subr_localcount.c
sys/kern/subr_lockdebug.c
sys/kern/uipc_socket.c
sys/netinet/in.c
sys/netinet6/in6.c
sys/netipsec/ipsec.c
sys/netipsec/keysock.c
sys/rump/librump/rumpkern/locks.c
sys/sys/bootblock.h
sys/sys/mman.h
sys/sys/mutex.h
sys/sys/param.h
sys/uvm/pmap/pmap.c
sys/uvm/uvm_mmap.c
tests/lib/libc/gen/t_glob.c
tests/lib/libc/stdlib/t_strtoi.c
tests/net/ipsec/Makefile
tests/net/ipsec/algorithms.sh
tests/net/ipsec/t_ipsec_gif.sh
tests/net/ipsec/t_ipsec_l2tp.sh
usr.bin/man/man.c
usr.bin/sortinfo/sortinfo.1
usr.bin/sortinfo/sortinfo.c
usr.sbin/makemandb/apropos-utils.c
usr.sbin/makemandb/apropos-utils.h
usr.sbin/makemandb/apropos.c
usr.sbin/makemandb/makemandb.c
--- a/bin/csh/glob.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/csh/glob.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: glob.c,v 1.27 2013/07/16 17:47:43 christos Exp $ */
+/* $NetBSD: glob.c,v 1.27.18.1 2017/05/02 03:19:14 pgoyette Exp $ */
 
 /*-
  * Copyright (c) 1980, 1991, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)glob.c	8.1 (Berkeley) 5/31/93";
 #else
-__RCSID("$NetBSD: glob.c,v 1.27 2013/07/16 17:47:43 christos Exp $");
+__RCSID("$NetBSD: glob.c,v 1.27.18.1 2017/05/02 03:19:14 pgoyette Exp $");
 #endif
 #endif /* not lint */
 
@@ -89,7 +89,7 @@
 static Char **globexpand(Char **);
 static int globbrace(Char *, Char *, Char ***);
 static void expbrace(Char ***, Char ***, size_t);
-static int pmatch(Char *, Char *);
+static int pmatch(const Char *, const Char *);
 static void pword(void);
 static void psave(int);
 static void backeval(Char *, int);
@@ -818,56 +818,74 @@
 } 
 
 static int
-pmatch(Char *string, Char *pattern)
+pmatch(const Char *name, const Char *pat)
 {
     int match, negate_range;
-    Char patternc, rangec, stringc;
+    Char patc, namec, c;
+    const Char *nameNext, *nameStart, *nameEnd, *patNext;
+
+    nameNext = nameStart = name;
+    patNext = pat;
+    nameEnd = NULL;
 
-    for (;; ++string) {
-	stringc = *string & TRIM;
-	patternc = *pattern++;
-	switch (patternc) {
+    for (;;) {
+	namec = *name & TRIM;
+	if (namec == 0)
+	    nameEnd = name;
+	patc = *pat;
+	switch (patc) {
 	case 0:
-	    return (stringc == 0);
+	    if (namec == 0)
+		return 1;
+	    break;
 	case '?':
-	    if (stringc == 0)
-		return (0);
-	    break;
+	    if (namec == 0)
+		break;
+	    pat++;
+	    name++;
+	    continue;
 	case '*':
-	    if (!*pattern)
-		return (1);
-	    while (*string)
-		if (Gmatch(string++, pattern))
-		    return (1);
-	    return (0);
+	    while ((pat[1] & TRIM) == '*')
+		pat++;
+	    patNext = pat;
+	    nameNext = name + 1;
+	    pat++;
+	    continue;
 	case '[':
 	    match = 0;
-	    if ((negate_range = (*pattern == '^')) != 0)
-		pattern++;
-	    while ((rangec = *pattern++) != '\0') {
-		if (rangec == ']')
-		    break;
-		if (match)
-		    continue;
-		if (rangec == '-' && *(pattern-2) != '[' && *pattern  != ']') {
-		    match = (stringc <= (*pattern & TRIM) &&
-			      (*(pattern-2) & TRIM) <= stringc);
-		    pattern++;
-		}
-		else 
-		    match = (stringc == (rangec & TRIM));
+	    if (namec == 0)
+		break;
+	    pat++;
+	    name++;
+	    if ((negate_range = (*pat == '^')) != 0)
+		pat++;
+	    while ((c = *pat++) != ']') {
+		c &= TRIM;
+		if (*pat == '-') {
+		    if (c <= namec && namec <= (pat[1] & TRIM))
+			match = 1;
+		    pat += 2;
+		} else if (c == namec)
+		    match = 1;
+		else if (c == 0)
+		    stderror(ERR_NAME | ERR_MISSING, ']');
 	    }
-	    if (rangec == 0)
-		stderror(ERR_NAME | ERR_MISSING, ']');
 	    if (match == negate_range)
-		return (0);
-	    break;
+		break;
+	    continue;
 	default:
-	    if ((patternc & TRIM) != stringc)
-		return (0);
-	    break;
-
+	    if ((patc & TRIM) != namec)
+		break;
+	    pat++;
+	    name++;
+	    continue;
 	}
+	if (nameNext != nameStart && (nameEnd == NULL || nameNext <= nameEnd)) {
+	    pat = patNext;
+	    name = nameNext;
+	    continue;
+	}
+	return 0;
     }
 }
 
--- a/bin/ksh/misc.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/ksh/misc.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: misc.c,v 1.15 2011/10/16 17:12:11 joerg Exp $	*/
+/*	$NetBSD: misc.c,v 1.15.34.1 2017/05/02 03:19:14 pgoyette Exp $	*/
 
 /*
  * Miscellaneous functions
@@ -6,7 +6,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: misc.c,v 1.15 2011/10/16 17:12:11 joerg Exp $");
+__RCSID("$NetBSD: misc.c,v 1.15.34.1 2017/05/02 03:19:14 pgoyette Exp $");
 #endif
 
 
@@ -631,46 +631,50 @@
 	const unsigned char *se, *pe;
 	int isfile;
 {
-	register int sc, pc;
+	int sc, pc;
 	const unsigned char *prest, *psub, *pnext;
 	const unsigned char *srest;
+	const unsigned char *sNext, *pNext, *sStart;
 
 	if (s == NULL || p == NULL)
 		return 0;
-	while (p < pe) {
-		pc = *p++;
+	sNext = sStart = s;
+	pNext = p;
+	while (p < pe || s < se) {
+		pc = *p;
 		sc = s < se ? *s : '\0';
-		s++;
 		if (isfile) {
 			sc = FILECHCONV((unsigned char)sc);
 			pc = FILECHCONV((unsigned char)pc);
 		}
 		if (!ISMAGIC(pc)) {
 			if (sc != pc)
-				return 0;
+				goto backtrack;
+			p++;
+			s++;
 			continue;
-		}
-		switch (*p++) {
+		} else
+			pc = *++p;
+		switch (pc) {
 		  case '[':
+			p++;
+			s++;
 			if (sc == 0 || (p = cclass(p, sc)) == NULL)
-				return 0;
-			break;
+				break;
+			continue;
 
 		  case '?':
 			if (sc == 0)
-				return 0;
-			break;
+				break;
+			p++;
+			s++;
+			continue;
 
 		  case '*':
-			if (p == pe)
-				return 1;
-			s--;
-			do {
-				if (do_gmatch(s, se, p, pe, isfile))
-					return 1;
-			} while (s++ < se);
-			return 0;
-
+			pNext = p - 1;
+			sNext = s + 1;
+			p++;
+			continue;
 		  /*
 		   * [*+?@!](pattern|pattern|..)
 		   *
@@ -678,13 +682,13 @@
 		   */
 		  case 0x80|'+': /* matches one or more times */
 		  case 0x80|'*': /* matches zero or more times */
-			if (!(prest = pat_scan(p, pe, 0)))
-				return 0;
+			if (!(prest = pat_scan(++p, pe, 0)))
+				break;
 			s--;
 			/* take care of zero matches */
 			if (p[-1] == (0x80 | '*')
 			    && do_gmatch(s, se, prest, pe, isfile))
-				return 1;
+				continue;
 			for (psub = p; ; psub = pnext) {
 				pnext = pat_scan(psub, pe, 1);
 				for (srest = s; srest <= se; srest++) {
@@ -700,18 +704,18 @@
 				if (pnext == prest)
 					break;
 			}
-			return 0;
+			break;
 
 		  case 0x80|'?': /* matches zero or once */
 		  case 0x80|'@': /* matches one of the patterns */
 		  case 0x80|' ': /* simile for @ */
-			if (!(prest = pat_scan(p, pe, 0)))
-				return 0;
+			if (!(prest = pat_scan(++p, pe, 0)))
+				break;
 			s--;
 			/* Take care of zero matches */
 			if (p[-1] == (0x80 | '?')
 			    && do_gmatch(s, se, prest, pe, isfile))
-				return 1;
+				continue;
 			for (psub = p; ; psub = pnext) {
 				pnext = pat_scan(psub, pe, 1);
 				srest = prest == pe ? se : s;
@@ -720,16 +724,16 @@
 						      psub, pnext - 2, isfile)
 					    && do_gmatch(srest, se,
 							 prest, pe, isfile))
-						return 1;
+						continue;
 				}
 				if (pnext == prest)
 					break;
 			}
-			return 0;
+			break;
 
 		  case 0x80|'!': /* matches none of the patterns */
-			if (!(prest = pat_scan(p, pe, 0)))
-				return 0;
+			if (!(prest = pat_scan(++p, pe, 0)))
+				break;
 			s--;
 			for (srest = s; srest <= se; srest++) {
 				int matched = 0;
@@ -747,17 +751,25 @@
 				}
 				if (!matched && do_gmatch(srest, se,
 							  prest, pe, isfile))
-					return 1;
+					continue;
 			}
-			return 0;
+			break;
 
 		  default:
-			if (sc != p[-1])
-				return 0;
-			break;
+			if (sc != pc)
+				break;
+			p++;
+			s++;
+			continue;
 		}
+backtrack:	if (sNext != sStart && sNext <= se) {
+			p = pNext;
+			s = sNext;
+			continue;
+		}
+		return 0;
 	}
-	return s == se;
+	return 1;
 }
 
 static const unsigned char *
--- a/bin/sh/expand.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/sh/expand.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: expand.c,v 1.104 2017/03/20 11:48:01 kre Exp $	*/
+/*	$NetBSD: expand.c,v 1.104.2.1 2017/05/02 03:19:14 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)expand.c	8.5 (Berkeley) 5/15/95";
 #else
-__RCSID("$NetBSD: expand.c,v 1.104 2017/03/20 11:48:01 kre Exp $");
+__RCSID("$NetBSD: expand.c,v 1.104.2.1 2017/05/02 03:19:14 pgoyette Exp $");
 #endif
 #endif /* not lint */
 
@@ -52,6 +52,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <wctype.h>
+#include <wchar.h>
 
 /*
  * Routines to expand arguments to commands.  We have to deal with
@@ -112,8 +113,9 @@
 STATIC void addfname(char *);
 STATIC struct strlist *expsort(struct strlist *);
 STATIC struct strlist *msort(struct strlist *, int);
-STATIC int pmatch(char *, char *, int);
+STATIC int patmatch(const char *, const char *, int);
 STATIC char *cvtnum(int, char *);
+static int collate_range_cmp(wchar_t, wchar_t);
 
 /*
  * Expand shell variables and backquotes inside a here document.
@@ -129,6 +131,18 @@
 }
 
 
+static int
+collate_range_cmp(wchar_t c1, wchar_t c2)
+{
+	wchar_t s1[2], s2[2];
+
+	s1[0] = c1;
+	s1[1] = L'\0';
+	s2[0] = c2;
+	s2[1] = L'\0';
+	return (wcscoll(s1, s2));
+}
+
 /*
  * Perform variable substitution and command substitution on an argument,
  * placing the resulting list of arguments in arglist.  If EXP_FULL is true,
@@ -1399,7 +1413,7 @@
  * pointer is stored into *end.
  */
 static int
-match_charclass(char *p, wchar_t chr, char **end)
+match_charclass(const char *p, wchar_t chr, const char **end)
 {
 	char name[20];
 	char *nameend;
@@ -1427,35 +1441,29 @@
  * Returns true if the pattern matches the string.
  */
 
-int
-patmatch(char *pattern, char *string, int squoted)
+STATIC int
+patmatch(const char *pattern, const char *string, int squoted)
 {
-#ifdef notdef
-	if (pattern[0] == '!' && pattern[1] == '!')
-		return 1 - pmatch(pattern + 2, string);
-	else
-#endif
-		return pmatch(pattern, string, squoted);
-}
-
-
-STATIC int
-pmatch(char *pattern, char *string, int squoted)
-{
-	char *p, *q, *end;
+	const char *p, *q, *end;
+	const char *bt_p, *bt_q;
 	char c;
+	wchar_t wc, wc2;
 
 	p = pattern;
 	q = string;
+	bt_p = NULL;
+	bt_q = NULL;
 	for (;;) {
 		switch (c = *p++) {
 		case '\0':
-			goto breakloop;
+			if (*q != '\0')
+				goto backtrack;
+			return 1;
 		case CTLESC:
 			if (squoted && *q == CTLESC)
 				q++;
 			if (*q++ != *p++)
-				return 0;
+				goto backtrack;
 			break;
 		case CTLQUOTEMARK:
 			continue;
@@ -1482,17 +1490,19 @@
 					q++;
 				}
 			}
-			do {
-				if (pmatch(p, q, squoted))
-					return 1;
-				if (squoted && *q == CTLESC)
-					q++;
-			} while (*q++ != '\0');
-			return 0;
+			/*
+			 * First try the shortest match for the '*' that
+			 * could work. We can forget any earlier '*' since
+			 * there is no way having it match more characters
+			 * can help us, given that we are already here.
+			 */
+			bt_p = p;
+			bt_q = q;
+			break;
 		case '[': {
-			char *endp;
+			const char *savep, *saveq, *endp;
 			int invert, found;
-			char chr;
+			unsigned char chr;
 
 			endp = p;
 			if (*endp == '!')
@@ -1508,20 +1518,25 @@
 					break;
 			}
 			invert = 0;
-			if (*p == '!') {
+			savep = p, saveq = q;
+			invert = 0;
+			if (*p == '!' || *p == '^') {
 				invert++;
 				p++;
 			}
 			found = 0;
-			chr = *q++;
-			if (squoted && chr == CTLESC)
-				chr = *q++;
-			if (chr == '\0')
+			if (*q == '\0')
 				return 0;
+			chr = (unsigned char)*q++;
 			c = *p++;
 			do {
 				if (c == CTLQUOTEMARK)
 					continue;
+				if (c == '\0') {
+					p = savep, q = saveq;
+					c = '[';
+					goto dft;
+				}
 				if (c == '[' && *p == ':') {
 					found |= match_charclass(p, chr, &end);
 					if (end != NULL)
@@ -1529,36 +1544,46 @@
 				}
 				if (c == CTLESC)
 					c = *p++;
+				wc = (unsigned char)c;
 				if (*p == '-' && p[1] != ']') {
 					p++;
-					while (*p == CTLQUOTEMARK)
-						p++;
 					if (*p == CTLESC)
 						p++;
-					if (chr >= c && chr <= *p)
+					wc2 = (unsigned char)*p++;
+					if (   collate_range_cmp(chr, wc) >= 0
+					    && collate_range_cmp(chr, wc2) <= 0
+					   )
 						found = 1;
-					p++;
 				} else {
-					if (chr == c)
+					if (chr == wc)
 						found = 1;
 				}
 			} while ((c = *p++) != ']');
 			if (found == invert)
-				return 0;
+				goto backtrack;
 			break;
 		}
 dft:	        default:
 			if (squoted && *q == CTLESC)
 				q++;
-			if (*q++ != c)
+			if (*q++ == c)
+				break;
+backtrack:
+			/*
+			 * If we have a mismatch (other than hitting the end
+			 * of the string), go back to the last '*' seen and
+			 * have it match one additional character.
+			 */
+			if (bt_p == NULL)
 				return 0;
+			if (*bt_q == '\0')
+				return 0;
+			bt_q++;
+			p = bt_p;
+			q = bt_q;
 			break;
 		}
 	}
-breakloop:
-	if (*q != '\0')
-		return 0;
-	return 1;
 }
 
 
--- a/bin/sh/expand.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/sh/expand.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: expand.h,v 1.20 2017/03/20 11:26:07 kre Exp $	*/
+/*	$NetBSD: expand.h,v 1.20.2.1 2017/05/02 03:19:14 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -63,6 +63,5 @@
 void expandhere(union node *, int);
 void expandarg(union node *, struct arglist *, int);
 void expari(int);
-int patmatch(char *, char *, int);
 void rmescapes(char *);
 int casematch(union node *, char *);
--- a/bin/sh/input.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/sh/input.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: input.c,v 1.51 2016/06/01 05:11:52 kre Exp $	*/
+/*	$NetBSD: input.c,v 1.51.6.1 2017/05/02 03:19:14 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)input.c	8.3 (Berkeley) 6/9/95";
 #else
-__RCSID("$NetBSD: input.c,v 1.51 2016/06/01 05:11:52 kre Exp $");
+__RCSID("$NetBSD: input.c,v 1.51.6.1 2017/05/02 03:19:14 pgoyette Exp $");
 #endif
 #endif /* not lint */
 
@@ -428,6 +428,24 @@
 	INTON;
 }
 
+/*
+ * When a shell fd needs to be altered (when the user wants to use
+ * the same fd - rare, but happens - we need to locate the ref to
+ * the fd, and update it.  This happens via a callback.
+ * This is the callback func for fd's used for shell input
+ */
+static void
+input_fd_swap(int from, int to)
+{
+	struct parsefile *pf;
+
+	pf = parsefile;
+	while (pf != NULL) {		/* don't need to stop at basepf */
+		if (pf->fd == from)
+			pf->fd = to;
+		pf = pf->prev;
+	}
+}
 
 /*
  * Like setinputfile, but takes an open file descriptor.  Call this with
@@ -437,13 +455,14 @@
 void
 setinputfd(int fd, int push)
 {
+	register_sh_fd(fd, input_fd_swap);
 	(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
 	if (push) {
 		pushfile();
 		parsefile->buf = ckmalloc(BUFSIZ);
 	}
 	if (parsefile->fd > 0)
-		close(parsefile->fd);
+		sh_close(parsefile->fd);
 	parsefile->fd = fd;
 	if (parsefile->buf == NULL)
 		parsefile->buf = ckmalloc(BUFSIZ);
@@ -502,7 +521,7 @@
 
 	INTOFF;
 	if (pf->fd >= 0)
-		close(pf->fd);
+		sh_close(pf->fd);
 	if (pf->buf)
 		ckfree(pf->buf);
 	while (pf->strpush)
@@ -551,7 +570,7 @@
 		return;
 	popallfiles();
 	if (parsefile->fd > 0) {
-		close(parsefile->fd);
+		sh_close(parsefile->fd);
 		parsefile->fd = 0;
 	}
 }
--- a/bin/sh/jobs.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/sh/jobs.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: jobs.c,v 1.79 2016/05/07 20:07:47 kre Exp $	*/
+/*	$NetBSD: jobs.c,v 1.79.6.1 2017/05/02 03:19:14 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)jobs.c	8.5 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: jobs.c,v 1.79 2016/05/07 20:07:47 kre Exp $");
+__RCSID("$NetBSD: jobs.c,v 1.79.6.1 2017/05/02 03:19:14 pgoyette Exp $");
 #endif
 #endif /* not lint */
 
@@ -129,6 +129,13 @@
 }
 #endif
 
+static void
+ttyfd_change(int from, int to)
+{
+	if (ttyfd == from)
+		ttyfd = to;
+}
+
 /*
  * Turn job control on and off.
  *
@@ -150,10 +157,10 @@
 		return;
 	if (on) {
 #if defined(FIOCLEX) || defined(FD_CLOEXEC)
-		int err;
 		int i;
+
 		if (ttyfd != -1)
-			close(ttyfd);
+			sh_close(ttyfd);
 		if ((ttyfd = open("/dev/tty", O_RDWR)) == -1) {
 			for (i = 0; i < 3; i++) {
 				if (isatty(i) && (ttyfd = dup(i)) != -1)
@@ -163,24 +170,14 @@
 				goto out;
 		}
 		ttyfd = to_upper_fd(ttyfd);	/* Move to a high fd */
-#ifdef FIOCLEX
-		err = ioctl(ttyfd, FIOCLEX, 0);
-#elif FD_CLOEXEC
-		err = fcntl(ttyfd, F_SETFD,
-		    fcntl(ttyfd, F_GETFD, 0) | FD_CLOEXEC);
-#endif
-		if (err == -1) {
-			close(ttyfd);
-			ttyfd = -1;
-			goto out;
-		}
+		register_sh_fd(ttyfd, ttyfd_change);
 #else
 		out2str("sh: Need FIOCLEX or FD_CLOEXEC to support job control");
 		goto out;
 #endif
 		do { /* while we are in the background */
 			if ((initialpgrp = tcgetpgrp(ttyfd)) < 0) {
-out:
+ out:
 				out2str("sh: can't access tty; job control turned off\n");
 				mflag = 0;
 				return;
@@ -217,7 +214,7 @@
 		if (tcsetpgrp(ttyfd, initialpgrp) == -1)
 			error("Cannot set tty process group (%s) at %d",
 			    strerror(errno), __LINE__);
-		close(ttyfd);
+		sh_close(ttyfd);
 		ttyfd = -1;
 		setsignal(SIGTSTP, 0);
 		setsignal(SIGTTOU, 0);
@@ -1312,7 +1309,7 @@
 		goto until;
 	case NUNTIL:
 		cmdputs("until ");
-until:
+ until:
 		cmdtxt(n->nbinary.ch1);
 		cmdputs("; do ");
 		cmdtxt(n->nbinary.ch2);
@@ -1366,7 +1363,7 @@
 		p = "<&";  i = 0;  goto redir;
 	case NFROMTO:
 		p = "<>";  i = 0;  goto redir;
-redir:
+ redir:
 		if (n->nfile.fd != i)
 			cmdputi(n->nfile.fd);
 		cmdputs(p);
--- a/bin/sh/redir.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/sh/redir.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: redir.c,v 1.53 2017/04/22 16:02:39 kre Exp $	*/
+/*	$NetBSD: redir.c,v 1.53.2.1 2017/05/02 03:19:14 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)redir.c	8.2 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: redir.c,v 1.53 2017/04/22 16:02:39 kre Exp $");
+__RCSID("$NetBSD: redir.c,v 1.53.2.1 2017/05/02 03:19:14 pgoyette Exp $");
 #endif
 #endif /* not lint */
 
@@ -115,6 +115,18 @@
 STATIC int copyfd(int, int, int);
 STATIC void find_big_fd(void);
 
+
+struct shell_fds {		/* keep track of internal shell fds */
+	struct shell_fds *nxt;
+	void (*cb)(int, int);
+	int fd;
+};
+
+STATIC struct shell_fds *sh_fd_list;
+
+STATIC void renumber_sh_fd(struct shell_fds *);
+STATIC struct shell_fds *sh_fd(int);
+
 STATIC const struct renamelist *
 is_renamed(const struct renamelist *rl, int fd)
 {
@@ -191,6 +203,7 @@
 		fd = n->nfile.fd;
 		if (fd > max_user_fd)
 			max_user_fd = fd;
+		renumber_sh_fd(sh_fd(fd));
 		if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
 		    n->ndup.dupfd == fd) {
 			/* redirect from/to same file descriptor */
@@ -505,8 +518,12 @@
 find_big_fd(void)
 {
 	int i, fd;
+	static int last_start = 6;
 
-	for (i = (1 << 10); i >= 10; i >>= 1) {
+	if (last_start < 10)
+		last_start++;
+
+	for (i = (1 << last_start); i >= 10; i >>= 1) {
 		if ((fd = fcntl(0, F_DUPFD, i - 1)) >= 0) {
 			close(fd);
 			break;
@@ -514,9 +531,7 @@
 	}
 
 	fd = (i / 5) * 4;
-	if ((i - fd) > 100)
-		fd = i - 100;
-	else if (fd < 10)
+	if (fd < 10)
 		fd = 10;
 
 	big_sh_fd = fd;
@@ -543,7 +558,7 @@
 				close(fd);
 			return i;
 		}
-		if (errno != EMFILE)
+		if (errno != EMFILE && errno != EINVAL)
 			break;
 		find_big_fd();
 	} while (big_sh_fd > 10);
@@ -557,6 +572,85 @@
 	return fd;
 }
 
+void
+register_sh_fd(int fd, void (*cb)(int, int))
+{
+	struct shell_fds *fp;
+
+	fp = ckmalloc(sizeof (struct shell_fds));
+	if (fp != NULL) {
+		fp->nxt = sh_fd_list;
+		sh_fd_list = fp;
+
+		fp->fd = fd;
+		fp->cb = cb;
+	}
+}
+
+void
+sh_close(int fd)
+{
+	struct shell_fds **fpp, *fp;
+
+	fpp = &sh_fd_list;
+	while ((fp = *fpp) != NULL) {
+		if (fp->fd == fd) {
+			*fpp = fp->nxt;
+			ckfree(fp);
+			break;
+		}
+		fpp = &fp->nxt;
+	}
+	(void)close(fd);
+}
+
+STATIC struct shell_fds *
+sh_fd(int fd)
+{
+	struct shell_fds *fp;
+
+	for (fp = sh_fd_list; fp != NULL; fp = fp->nxt)
+		if (fp->fd == fd)
+			return fp;
+	return NULL;
+}
+
+STATIC void
+renumber_sh_fd(struct shell_fds *fp)
+{
+	int to;
+
+	if (fp == NULL)
+		return;
+
+#ifndef	F_DUPFD_CLOEXEC
+#define	F_DUPFD_CLOEXEC	F_DUPFD
+#define	CLOEXEC(fd)	(fcntl((fd), F_SETFD, fcntl((fd),F_GETFD) | FD_CLOEXEC))
+#else
+#define	CLOEXEC(fd)
+#endif
+
+	to = fcntl(fp->fd, F_DUPFD_CLOEXEC, big_sh_fd);
+	if (to == -1)
+		to = fcntl(fp->fd, F_DUPFD_CLOEXEC, big_sh_fd/2);
+	if (to == -1)
+		to = fcntl(fp->fd, F_DUPFD_CLOEXEC, fp->fd + 1);
+	if (to == -1)
+		to = fcntl(fp->fd, F_DUPFD_CLOEXEC, 10);
+	if (to == -1)
+		to = fcntl(fp->fd, F_DUPFD_CLOEXEC, 3);
+	if (to == -1)
+		error("insufficient file descriptors available");
+	CLOEXEC(to);
+
+	if (fp->fd == to)	/* impossible? */
+		return;
+
+	(*fp->cb)(fp->fd, to);
+	(void)close(fp->fd);
+	fp->fd = to;
+}
+
 static const struct flgnames {
 	const char *name;
 	uint32_t value;
@@ -604,6 +698,13 @@
 {
 	int c, f;
 
+	if (sh_fd(fd) != NULL) {
+		if (!p)
+			return -1;
+		error("Can't get status for fd=%d (%s)", fd,
+		    "Bad file descriptor");			/*XXX*/
+	}
+
 	if ((c = fcntl(fd, F_GETFD)) == -1) {
 		if (!p)
 			return -1;
--- a/bin/sh/redir.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/sh/redir.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: redir.h,v 1.22 2017/04/22 16:02:39 kre Exp $	*/
+/*	$NetBSD: redir.h,v 1.22.2.1 2017/05/02 03:19:14 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -47,5 +47,7 @@
 void clearredir(int);
 int movefd(int, int);
 int to_upper_fd(int);
+void register_sh_fd(int, void (*)(int, int));
+void sh_close(int);
 
 int max_user_fd;		/* highest fd used by user */
--- a/bin/sh/sh.1	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/sh/sh.1	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-.\"	$NetBSD: sh.1,v 1.131 2017/04/14 08:48:01 abhinav Exp $
+.\"	$NetBSD: sh.1,v 1.131.2.1 2017/05/02 03:19:14 pgoyette Exp $
 .\" Copyright (c) 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
 .\"
@@ -31,7 +31,7 @@
 .\"
 .\"	@(#)sh.1	8.6 (Berkeley) 5/4/95
 .\"
-.Dd March 20, 2017
+.Dd April 29, 2017
 .Dt SH 1
 .ds flags abCEeFfhnuvxIimpqV
 .Os
@@ -334,7 +334,7 @@
 the file system is searched for commands each time the function is invoked.
 (Not implemented.)
 .It Fl p Em nopriv
-Do not attempt to reset effective uid if it does not match uid.
+Do not attempt to reset effective UID if it does not match UID.
 This is not set by default to help avoid incorrect usage by setuid
 root programs via
 .Xr system 3
@@ -2037,7 +2037,8 @@
 .Dq $# )
 before the shift.
 .It trap Oo Fl l Oc
-.It trap Oo Ar action Oc Ar signal ...
+.It trap Ar action signal ...
+.It trap Ar N signal ...
 Cause the shell to parse and execute action when any of the specified
 signals are received.
 The signals are specified by signal number or as the name of the signal.
@@ -2051,9 +2052,20 @@
 may be null, which cause the specified signals to be ignored.
 With
 .Ar action
-omitted or set to
+set to
 .Sq -
 the specified signals are set to their default action.
+If the first
+.Ar signal
+is specified in its numeric form, then
+.Ar action
+can be omitted to achieve the same effect.
+This archaic,
+but still standard,
+form should not be relied upon, use the explicit
+.Sq -
+action.
+.Pp
 When the shell forks off a subshell, it resets trapped (but not ignored)
 signals to the default action.
 On non-interactive shells, the
@@ -2077,21 +2089,31 @@
 .Pp
 .Dl trap
 .Pp
-List trapped signals and their corresponding action
+List trapped signals and their corresponding action.
 .Pp
 .Dl trap -l
 .Pp
-Print a list of valid signals
+Print a list of valid signals.
 .Pp
 .Dl trap '' INT QUIT tstp 30
 .Pp
-Ignore signals INT QUIT TSTP USR1
+Ignore signals INT QUIT TSTP USR1.
 .Pp
 .Dl trap date INT
 .Pp
 Run the
 .Dq date
-command (print the date) upon receiving signal INT
+command (print the date) upon receiving signal INT.
+.Pp
+.Dl trap HUP INT
+.Pp
+Run the
+.Dq HUP
+command upon receiving signal INT.
+.Pp
+.Dl trap 1 2
+.Pp
+Reset the actions for signals 1 (HUP) and 2 (INT) to their defaults.
 .It type Op Ar name ...
 Interpret each name as a command and print the resolution of the command
 search.
--- a/bin/sh/trap.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/sh/trap.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: trap.c,v 1.37 2015/08/22 12:12:47 christos Exp $	*/
+/*	$NetBSD: trap.c,v 1.37.6.1 2017/05/02 03:19:14 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)trap.c	8.5 (Berkeley) 6/5/95";
 #else
-__RCSID("$NetBSD: trap.c,v 1.37 2015/08/22 12:12:47 christos Exp $");
+__RCSID("$NetBSD: trap.c,v 1.37.6.1 2017/05/02 03:19:14 pgoyette Exp $");
 #endif
 #endif /* not lint */
 
@@ -136,6 +136,19 @@
 	char *action;
 	char **ap;
 	int signo;
+	int errs = 0;
+
+	ap = argv + 1;
+
+	if (argc == 2 && strcmp(*ap, "-l") == 0) {
+		printsignals();
+		return 0;
+	}
+
+	if (argc > 1 && strcmp(*ap, "--") == 0) {
+		argc--;
+		ap++;
+	}
 
 	if (argc <= 1) {
 		for (signo = 0 ; signo <= NSIG ; signo++)
@@ -147,37 +160,33 @@
 			}
 		return 0;
 	}
-	ap = argv + 1;
 
 	action = NULL;
 
-	if (strcmp(*ap, "--") == 0)
-		if (*++ap == NULL)
-			return 0;
-
-	if (signame_to_signum(*ap) == -1) {
-		if ((*ap)[0] == '-') {
-			if ((*ap)[1] == '\0')
-				ap++;
-			else if ((*ap)[1] == 'l' && (*ap)[2] == '\0') {
-				printsignals();
-				return 0;
-			}
-			else
-				error("bad option %s\n", *ap);
-		}
+	if (!is_number(*ap)) {
+		if ((*ap)[0] == '-' && (*ap)[1] == '\0')
+			ap++;			/* reset to default */
 		else
-			action = *ap++;
+			action = *ap++;		/* can be '' for "ignore" */
+		argc--;
 	}
 
+	if (argc < 2) {		/* there must be at least 1 condition */
+		out2str("Usage: trap [-l]\n"
+			"       trap action condition ...\n"
+			"       trap N condition ...\n");
+		return 2;
+	}
+
+
 	while (*ap) {
-		if (is_number(*ap))
-			signo = number(*ap);
-		else
-			signo = signame_to_signum(*ap);
+		signo = signame_to_signum(*ap);
 
-		if (signo < 0 || signo > NSIG)
-			error("%s: bad trap", *ap);
+		if (signo < 0 || signo > NSIG) {
+			/* This is not a fatal error, so sayeth posix */
+			outfmt(out2, "trap: '%s' bad condition\n", *ap);
+			errs = 1;
+		}
 
 		INTOFF;
 		if (action)
@@ -193,7 +202,7 @@
 		INTON;
 		ap++;
 	}
-	return 0;
+	return errs;
 }
 
 
@@ -404,6 +413,7 @@
 {
 	int i;
 	int savestatus;
+	char *tr;
 
 	for (;;) {
 		for (i = 1 ; ; i++) {
@@ -414,7 +424,9 @@
 		}
 		gotsig[i - 1] = 0;
 		savestatus=exitstatus;
-		evalstring(trap[i], 0);
+		tr = savestr(trap[i]);		/* trap code may free trap[i] */
+		evalstring(tr, 0);
+		ckfree(tr);
 		exitstatus=savestatus;
 	}
 done:
--- a/bin/sh/var.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/bin/sh/var.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.49 2016/03/31 16:16:35 christos Exp $	*/
+/*	$NetBSD: var.c,v 1.49.6.1 2017/05/02 03:19:14 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)var.c	8.3 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: var.c,v 1.49 2016/03/31 16:16:35 christos Exp $");
+__RCSID("$NetBSD: var.c,v 1.49.6.1 2017/05/02 03:19:14 pgoyette Exp $");
 #endif
 #endif /* not lint */
 
@@ -497,6 +497,10 @@
 {
 	const char *q;
 
+	if (p[0] == '\0') {
+		out1fmt("''");
+		return;
+	}
 	if (strcspn(p, "|&;<>()$`\\\"' \t\n*?[]#~=%") == strlen(p)) {
 		out1fmt("%s", p);
 		return;
--- a/distrib/sets/lists/comp/mi	Sun Apr 30 10:27:16 2017 +0000
+++ b/distrib/sets/lists/comp/mi	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-#	$NetBSD: mi,v 1.2125.2.3 2017/04/30 04:56:55 pgoyette Exp $
+#	$NetBSD: mi,v 1.2125.2.4 2017/05/02 03:19:14 pgoyette Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 ./etc/mtree/set.comp				comp-sys-root
@@ -5126,7 +5126,7 @@
 ./usr/share/man/cat3/archive_entry_free.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_gid.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_gname.0	comp-c-catman		.cat
-./usr/share/man/cat3/archive_entry_gname_w.0	comp-obsolete		obsolete
+./usr/share/man/cat3/archive_entry_gname_w.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_hardlink.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_hardlink_w.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_ino.0	comp-c-catman		.cat
@@ -5170,7 +5170,7 @@
 ./usr/share/man/cat3/archive_entry_set_nlink.0	comp-obsolete		obsolete
 ./usr/share/man/cat3/archive_entry_set_pathname.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_set_perm.0	comp-c-catman		.cat
-./usr/share/man/cat3/archive_entry_set_rdev.0	comp-obsolete		obsolete
+./usr/share/man/cat3/archive_entry_set_rdev.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_set_rdevmajor.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_set_rdevminor.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_set_size.0	comp-c-catman		.cat
@@ -5187,7 +5187,7 @@
 ./usr/share/man/cat3/archive_entry_time.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_uid.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_uname.0	comp-c-catman		.cat
-./usr/share/man/cat3/archive_entry_uname_w.0	comp-obsolete		obsolete
+./usr/share/man/cat3/archive_entry_uname_w.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_unset_atime.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_unset_birthtime.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_entry_unset_ctime.0	comp-c-catman		.cat
@@ -5325,7 +5325,7 @@
 ./usr/share/man/cat3/archive_write_finish_entry.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_write_format.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_write_free.0	comp-c-catman		.cat
-./usr/share/man/cat3/archive_write_get_bytes_in_last_block.0	comp-obsolete		obsolete
+./usr/share/man/cat3/archive_write_get_bytes_in_last_block.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_write_get_bytes_per_block.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_write_header.0	comp-c-catman		.cat
 ./usr/share/man/cat3/archive_write_new.0	comp-c-catman		.cat
@@ -10428,6 +10428,7 @@
 ./usr/share/man/cat9/deviter_init.0		comp-sys-catman		.cat
 ./usr/share/man/cat9/deviter_next.0		comp-sys-catman		.cat
 ./usr/share/man/cat9/deviter_release.0		comp-sys-catman		.cat
+./usr/share/man/cat9/devsw.0			comp-sys-catman		.cat
 ./usr/share/man/cat9/devsw_attach.0		comp-sys-catman		.cat
 ./usr/share/man/cat9/devsw_detach.0		comp-sys-catman		.cat
 ./usr/share/man/cat9/disk.0			comp-sys-catman		.cat
@@ -12749,7 +12750,7 @@
 ./usr/share/man/html3/archive_entry_free.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_gid.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_gname.html	comp-c-htmlman		html
-./usr/share/man/html3/archive_entry_gname_w.html	comp-obsolete		obsolete
+./usr/share/man/html3/archive_entry_gname_w.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_hardlink.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_hardlink_w.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_ino.html	comp-c-htmlman		html
@@ -12793,7 +12794,7 @@
 ./usr/share/man/html3/archive_entry_set_nlink.html	comp-obsolete		obsolete
 ./usr/share/man/html3/archive_entry_set_pathname.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_set_perm.html	comp-c-htmlman		html
-./usr/share/man/html3/archive_entry_set_rdev.html	comp-obsolete		obsolete
+./usr/share/man/html3/archive_entry_set_rdev.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_set_rdevmajor.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_set_rdevminor.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_set_size.html	comp-c-htmlman		html
@@ -12810,7 +12811,7 @@
 ./usr/share/man/html3/archive_entry_time.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_uid.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_uname.html	comp-c-htmlman		html
-./usr/share/man/html3/archive_entry_uname_w.html	comp-obsolete		obsolete
+./usr/share/man/html3/archive_entry_uname_w.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_unset_atime.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_unset_birthtime.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_entry_unset_ctime.html	comp-c-htmlman		html
@@ -12948,7 +12949,7 @@
 ./usr/share/man/html3/archive_write_finish_entry.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_write_format.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_write_free.html	comp-c-htmlman		html
-./usr/share/man/html3/archive_write_get_bytes_in_last_block.html	comp-obsolete		obsolete
+./usr/share/man/html3/archive_write_get_bytes_in_last_block.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_write_get_bytes_per_block.html	comp-c-htmlman		html
 ./usr/share/man/html3/archive_write_header.html comp-c-htmlman		html
 ./usr/share/man/html3/archive_write_new.html	comp-c-htmlman		html
@@ -17879,6 +17880,7 @@
 ./usr/share/man/html9/deviter_init.html		comp-sys-htmlman	html
 ./usr/share/man/html9/deviter_next.html		comp-sys-htmlman	html
 ./usr/share/man/html9/deviter_release.html	comp-sys-htmlman	html
+./usr/share/man/html9/devsw.html		comp-sys-htmlman	html
 ./usr/share/man/html9/devsw_attach.html		comp-sys-htmlman	html
 ./usr/share/man/html9/devsw_detach.html		comp-sys-htmlman	html
 ./usr/share/man/html9/disk.html			comp-sys-htmlman	html
@@ -20173,7 +20175,7 @@
 ./usr/share/man/man3/archive_entry_free.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_gid.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_gname.3	comp-c-man		.man
-./usr/share/man/man3/archive_entry_gname_w.3	comp-obsolete		obsolete
+./usr/share/man/man3/archive_entry_gname_w.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_hardlink.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_hardlink_w.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_ino.3	comp-c-man		.man
@@ -20217,7 +20219,7 @@
 ./usr/share/man/man3/archive_entry_set_nlink.3	comp-obsolete		obsolete
 ./usr/share/man/man3/archive_entry_set_pathname.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_set_perm.3	comp-c-man		.man
-./usr/share/man/man3/archive_entry_set_rdev.3	comp-obsolete		obsolete
+./usr/share/man/man3/archive_entry_set_rdev.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_set_rdevmajor.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_set_rdevminor.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_set_size.3	comp-c-man		.man
@@ -20234,7 +20236,7 @@
 ./usr/share/man/man3/archive_entry_time.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_uid.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_uname.3	comp-c-man		.man
-./usr/share/man/man3/archive_entry_uname_w.3	comp-obsolete		obsolete
+./usr/share/man/man3/archive_entry_uname_w.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_unset_atime.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_unset_birthtime.3	comp-c-man		.man
 ./usr/share/man/man3/archive_entry_unset_ctime.3	comp-c-man		.man
@@ -20372,7 +20374,7 @@
 ./usr/share/man/man3/archive_write_finish_entry.3	comp-c-man		.man
 ./usr/share/man/man3/archive_write_format.3	comp-c-man		.man
 ./usr/share/man/man3/archive_write_free.3	comp-c-man		.man
-./usr/share/man/man3/archive_write_get_bytes_in_last_block.3	comp-obsolete		obsolete
+./usr/share/man/man3/archive_write_get_bytes_in_last_block.3	comp-c-man		.man
 ./usr/share/man/man3/archive_write_get_bytes_per_block.3	comp-c-man		.man
 ./usr/share/man/man3/archive_write_header.3	comp-c-man		.man
 ./usr/share/man/man3/archive_write_new.3	comp-c-man		.man
@@ -25470,6 +25472,7 @@
 ./usr/share/man/man9/deviter_init.9		comp-sys-man		.man
 ./usr/share/man/man9/deviter_next.9		comp-sys-man		.man
 ./usr/share/man/man9/deviter_release.9		comp-sys-man		.man
+./usr/share/man/man9/devsw.9			comp-sys-man		.man
 ./usr/share/man/man9/devsw_attach.9		comp-sys-man		.man
 ./usr/share/man/man9/devsw_detach.9		comp-sys-man		.man
 ./usr/share/man/man9/disk.9			comp-sys-man		.man
--- a/distrib/sets/lists/tests/mi	Sun Apr 30 10:27:16 2017 +0000
+++ b/distrib/sets/lists/tests/mi	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.735 2017/04/17 09:06:55 knakahara Exp $
+# $NetBSD: mi,v 1.735.2.1 2017/05/02 03:19:15 pgoyette Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -3303,6 +3303,8 @@
 ./usr/tests/net/ipsec/t_ipsec_sysctl		tests-net-tests		atf,rump
 ./usr/tests/net/ipsec/t_ipsec_transport		tests-net-tests		atf,rump
 ./usr/tests/net/ipsec/t_ipsec_tunnel		tests-net-tests		atf,rump
+./usr/tests/net/ipsec/t_ipsec_gif		tests-net-tests		atf,rump
+./usr/tests/net/ipsec/t_ipsec_l2tp		tests-net-tests		atf,rump
 ./usr/tests/net/mcast				tests-net-tests		compattestfile,atf
 ./usr/tests/net/mcast/Atffile			tests-net-tests		atf,rump
 ./usr/tests/net/mcast/Kyuafile			tests-net-tests		atf,rump,kyua
--- a/doc/3RDPARTY	Sun Apr 30 10:27:16 2017 +0000
+++ b/doc/3RDPARTY	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-#	$NetBSD: 3RDPARTY,v 1.1438 2017/04/25 13:20:41 christos Exp $
+#	$NetBSD: 3RDPARTY,v 1.1438.2.1 2017/05/02 03:19:15 pgoyette Exp $
 #
 # This file contains a list of the software that has been integrated into
 # NetBSD where we are not the primary maintainer.
@@ -40,8 +40,8 @@
 #
 
 Package:	acpica
-Version:	20170119
-Current Vers:	20170119
+Version:	20170303
+Current Vers:	20170303
 Maintainer:	Intel
 Archive Site:	http://www.acpica.org/downloads/
 Home Page:	http://www.acpica.org/
@@ -807,7 +807,7 @@
 into inetd. The provided libwrap2netbsd script handles just libwrap.
 
 Package:	Lua
-Version:	Lua 5.3.3
+Version:	Lua 5.3.4
 Current Vers:	Lua 5.3.4
 Maintainer:	PUC Rio
 Home Page:	http://www.lua.org/
--- a/doc/BRANCHES	Sun Apr 30 10:27:16 2017 +0000
+++ b/doc/BRANCHES	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-#	$NetBSD: BRANCHES,v 1.339 2017/04/26 07:51:23 pgoyette Exp $
+#	$NetBSD: BRANCHES,v 1.339.2.1 2017/05/02 03:19:15 pgoyette Exp $
 #
 # This file contains a list of branches that exist in the NetBSD CVS
 # tree and their current state.
@@ -876,6 +876,22 @@
 Notes:		Used as experiment sandbox and if successful hopefully one day
 		to be integrated.
 
+Branch:		prg-localcount2
+Description:	Implement localcount reference counting as proposed by
+		riastradh@ - supersedes abandonded pgoyette-localcount
+Status:		Active
+Start Date:	Wed Apr 26 2017
+End Date:	
+Base Tag:	prg-localcount2-base
+Maintainer:	pgoyette
+Scope:		src/sys/
+Notes:		
+
+
+########################################################################
+# Individual developers' branches (Terminated):
+########################################################################
+
 Branch:		pgoyette-localcount
 Description:	Implement localcount reference counting as proposed by
 		riastradh@
@@ -892,11 +908,6 @@
 		The work will be salvaged as much as possible, and
 		applied to a new clean branch.
 
-
-########################################################################
-# Individual developers' branches (Terminated):
-########################################################################
-
 Branch:		bouyer-scsipi
 Description:	Integration of atapi support
 Status:		Terminated
--- a/doc/CHANGES	Sun Apr 30 10:27:16 2017 +0000
+++ b/doc/CHANGES	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-# LIST OF CHANGES FROM LAST RELEASE:			<$Revision: 1.2277 $>
+# LIST OF CHANGES FROM LAST RELEASE:			<$Revision: 1.2277.2.1 $>
 #
 #
 # [Note: This file does not mention every change made to the NetBSD source tree.
@@ -503,3 +503,5 @@
 	OpenSSH: Imported 7.5. [christos 20170418]
 	tmux(1): Import of tmux 2.4 [christos 20170423]
 	libc: Update to tzcode2017b. [christos 20170425]
+	lua: Updated to Lua 5.3.4. [mbalmer 20170426]
+	acpi(4): Updated ACPICA to 20170303. [christos 20170430]
--- a/external/bsd/acpica/bin/iasl/Makefile	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/bsd/acpica/bin/iasl/Makefile	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.13 2016/11/11 21:09:21 christos Exp $
+# $NetBSD: Makefile,v 1.13.4.1 2017/05/02 03:19:15 pgoyette Exp $
 
 .if (${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "x86_64")
 PROG=	iasl
@@ -81,6 +81,9 @@
 	aslwalks.c \
 	aslxref.c \
 	aslxrefout.c \
+	cvcompiler.c \
+	cvdisasm.c \
+	cvparser.c \
 	dtcompile.c \
 	dtexpress.c \
 	dtfield.c \
@@ -234,7 +237,6 @@
 	utosi.c \
 	utownerid.c \
 	utpredef.c \
-	utprint.c \
 	utresrc.c \
 	utstate.c \
 	utstring.c \
@@ -243,6 +245,8 @@
 	utxface.c \
 	utxferror.c
 
+#	utprint.c 
+
 .PATH: ${TOPDIR}/../os_specific/service_layers
 SRCS+=	osunixxf.c
 
--- a/external/mit/lua/dist/Makefile	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/Makefile	Tue May 02 03:19:14 2017 +0000
@@ -46,7 +46,7 @@
 
 # Lua version and release.
 V= 5.3
-R= $V.3
+R= $V.4
 
 # Targets start here.
 all:	$(PLAT)
--- a/external/mit/lua/dist/README	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/README	Tue May 02 03:19:14 2017 +0000
@@ -1,5 +1,5 @@
 
-This is Lua 5.3.3, released on 30 May 2016.
+This is Lua 5.3.4, released on 12 Jan 2017.
 
 For installation instructions, license details, and
 further information about Lua, see doc/readme.html.
--- a/external/mit/lua/dist/doc/contents.html	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/doc/contents.html	Tue May 02 03:19:14 2017 +0000
@@ -32,7 +32,7 @@
 
 <P>
 <SMALL>
-Copyright &copy; 2015&ndash;2016 Lua.org, PUC-Rio.
+Copyright &copy; 2015&ndash;2017 Lua.org, PUC-Rio.
 Freely available under the terms of the
 <A HREF="http://www.lua.org/license.html">Lua license</A>.
 </SMALL>
@@ -512,6 +512,7 @@
 <A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR>
 <A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR>
 <A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR>
+<A HREF="manual.html#luaL_opt">luaL_opt</A><BR>
 <A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR>
 <A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR>
 <A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR>
@@ -608,10 +609,10 @@
 
 <P CLASS="footer">
 Last update:
-Thu Jan 14 10:14:28 BRST 2016
+Thu Dec 22 18:29:39 BRST 2016
 </P>
 <!--
-Last change: revised for Lua 5.3.3
+Last change: revised for Lua 5.3.4
 -->
 
 </BODY>
Binary file external/mit/lua/dist/doc/logo.gif has changed
--- a/external/mit/lua/dist/doc/lua.1	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/doc/lua.1	Tue May 02 03:19:14 2017 +0000
@@ -1,6 +1,7 @@
-.\"	$NetBSD: lua.1,v 1.5 2016/09/08 02:21:31 salazar Exp $
+.\"	$NetBSD: lua.1,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $
 .\"
-.TH LUA 1 "Date: 2014/12/10 15:55:45 "
+.\" Id: lua.man,v 1.14 2016/10/17 15:43:50 lhf Exp 
+.TH LUA 1 "Date: 2016/10/17 15:43:50 "
 .SH NAME
 lua \- Lua interpreter
 .SH SYNOPSIS
--- a/external/mit/lua/dist/doc/luac.1	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/doc/luac.1	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-.\"	$NetBSD: luac.1,v 1.4 2016/09/08 02:21:31 salazar Exp $
+.\"	$NetBSD: luac.1,v 1.4.4.1 2017/05/02 03:19:15 pgoyette Exp $
 .\"
 .\" Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp 
 .TH LUAC 1 "Date: 2011/11/16 13:53:40 "
--- a/external/mit/lua/dist/doc/manual.html	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/doc/manual.html	Tue May 02 03:19:14 2017 +0000
@@ -19,7 +19,7 @@
 
 <P>
 <SMALL>
-Copyright &copy; 2015&ndash;2016 Lua.org, PUC-Rio.
+Copyright &copy; 2015&ndash;2017 Lua.org, PUC-Rio.
 Freely available under the terms of the
 <a href="http://www.lua.org/license.html">Lua license</a>.
 </SMALL>
@@ -35,7 +35,7 @@
 <!-- ====================================================================== -->
 <p>
 
-<!-- Id: manual.of,v 1.162 2016/05/30 15:57:03 roberto Exp  -->
+<!-- Id: manual.of,v 1.167 2017/01/09 15:18:11 roberto Exp  -->
 
 
 
@@ -216,7 +216,7 @@
 
 <p>
 Tables are the sole data-structuring mechanism in Lua;
-they can be used to represent ordinary arrays, sequences,
+they can be used to represent ordinary arrays, lists,
 symbol tables, sets, records, graphs, trees, etc.
 To represent records, Lua uses the field name as an index.
 The language supports this representation by
@@ -226,13 +226,6 @@
 
 
 <p>
-We use the term <em>sequence</em> to denote a table where
-the set of all positive numeric keys is equal to {1..<em>n</em>}
-for some non-negative integer <em>n</em>,
-which is called the length of the sequence (see <a href="#3.4.7">&sect;3.4.7</a>).
-
-
-<p>
 Like indices,
 the values of table fields can be of any type.
 In particular,
@@ -378,6 +371,9 @@
 will call the message handler again.
 If this loop goes on for too long,
 Lua breaks it and returns an appropriate message.
+(The message handler is called only for regular runtime errors.
+It is not called for memory-allocation errors
+nor for errors while running finalizers.)
 
 
 
@@ -873,7 +869,7 @@
 <p>
 Only objects that have an explicit construction
 are removed from weak tables.
-Values, such as numbers and light C functions,
+Values, such as numbers and light C&nbsp;functions,
 are not subject to garbage collection,
 and therefore are not removed from weak tables
 (unless their associated values are collected).
@@ -1084,7 +1080,7 @@
 <code>and</code> is a reserved word, but <code>And</code> and <code>AND</code>
 are two different, valid names.
 As a convention,
-programs should avoid creating 
+programs should avoid creating
 names that start with an underscore followed by
 one or more uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>).
 
@@ -1101,7 +1097,7 @@
 </pre>
 
 <p>
-<em>Literal strings</em>
+A <em>short literal string</em>
 can be delimited by matching single or double quotes,
 and can contain the following C-like escape sequences:
 '<code>\a</code>' (bell),
@@ -1114,7 +1110,7 @@
 '<code>\\</code>' (backslash),
 '<code>\"</code>' (quotation mark [double quote]),
 and '<code>\'</code>' (apostrophe [single quote]).
-A backslash followed by a real newline
+A backslash followed by a line break
 results in a newline in the string.
 The escape sequence '<code>\z</code>' skips the following span
 of white-space characters,
@@ -1122,13 +1118,13 @@
 it is particularly useful to break and indent a long literal string
 into multiple lines without adding the newlines and spaces
 into the string contents.
-
-
-<p>
-Strings in Lua can contain any 8-bit value, including embedded zeros,
-which can be specified as '<code>\0</code>'.
-More generally,
-we can specify any byte in a literal string by its numeric value.
+A short literal string cannot contain unescaped line breaks
+nor escapes not forming a valid escape sequence.
+
+
+<p>
+We can specify any byte in a short literal string by its numeric value
+(including embedded zeros).
 This can be done
 with the escape sequence <code>\x<em>XX</em></code>,
 where <em>XX</em> is a sequence of exactly two hexadecimal digits,
@@ -1172,17 +1168,6 @@
 
 
 <p>
-Any byte in a literal string not
-explicitly affected by the previous rules represents itself.
-However, Lua opens files for parsing in text mode,
-and the system file functions may have problems with
-some control characters.
-So, it is safer to represent
-non-text data as a quoted literal with
-explicit escape sequences for the non-text characters.
-
-
-<p>
 For convenience,
 when the opening long bracket is immediately followed by a newline,
 the newline is not included in the string.
@@ -1203,6 +1188,17 @@
 </pre>
 
 <p>
+Any byte in a literal string not
+explicitly affected by the previous rules represents itself.
+However, Lua opens files for parsing in text mode,
+and the system file functions may have problems with
+some control characters.
+So, it is safer to represent
+non-text data as a quoted literal with
+explicit escape sequences for the non-text characters.
+
+
+<p>
 A <em>numeric constant</em> (or <em>numeral</em>)
 can be written with an optional fractional part
 and an optional decimal exponent,
@@ -1212,7 +1208,7 @@
 Hexadecimal constants also accept an optional fractional part
 plus an optional binary exponent,
 marked by a letter '<code>p</code>' or '<code>P</code>'.
-A numeric constant with a radix point or an exponent 
+A numeric constant with a radix point or an exponent
 denotes a float;
 otherwise,
 if its value fits in an integer,
@@ -1897,7 +1893,7 @@
 
 
 <p>
-Floor division (<code>//</code>) is a division 
+Floor division (<code>//</code>) is a division
 that rounds the quotient towards minus infinity,
 that is, the floor of the division of its operands.
 
@@ -1959,7 +1955,7 @@
 The C API also converts both integers to floats and
 floats to integers, as needed.
 Moreover, string concatenation accepts numbers as arguments,
-besides strings. 
+besides strings.
 
 
 <p>
@@ -1997,7 +1993,7 @@
 
 
 <p>
-All conversions from strings to numbers 
+All conversions from strings to numbers
 accept both a dot and the current locale mark
 as the radix character.
 (The Lua lexer, however, accepts only a dot.)
@@ -2140,37 +2136,66 @@
 
 <p>
 The length operator is denoted by the unary prefix operator <code>#</code>.
+
+
+<p>
 The length of a string is its number of bytes
 (that is, the usual meaning of string length when each
 character is one byte).
 
 
 <p>
+The length operator applied on a table
+returns a border in that table.
+A <em>border</em> in a table <code>t</code> is any natural number
+that satisfies the following condition:
+
+<pre>
+     (border == 0 or t[border] ~= nil) and t[border + 1] == nil
+</pre><p>
+In words,
+a border is any (natural) index in a table
+where a non-nil value is followed by a nil value
+(or zero, when index 1 is nil).
+
+
+<p>
+A table with exactly one border is called a <em>sequence</em>.
+For instance, the table <code>{10, 20, 30, 40, 50}</code> is a sequence,
+as it has only one border (5).
+The table <code>{10, 20, 30, nil, 50}</code> has two borders (3 and 5),
+and therefore it is not a sequence.
+The table <code>{nil, 20, 30, nil, nil, 60, nil}</code>
+has three borders (0, 3, and 6),
+so it is not a sequence, too.
+The table <code>{}</code> is a sequence with border 0.
+Note that non-natural keys do not interfere
+with whether a table is a sequence.
+
+
+<p>
+When <code>t</code> is a sequence,
+<code>#t</code> returns its only border,
+which corresponds to the intuitive notion of the length of the sequence.
+When <code>t</code> is not a sequence,
+<code>#t</code> can return any of its borders.
+(The exact one depends on details of
+the internal representation of the table,
+which in turn can depend on how the table was populated and
+the memory addresses of its non-numeric keys.)
+
+
+<p>
+The computation of the length of a table
+has a guaranteed worst time of <em>O(log n)</em>,
+where <em>n</em> is the largest natural key in the table.
+
+
+<p>
 A program can modify the behavior of the length operator for
 any value but strings through the <code>__len</code> metamethod (see <a href="#2.4">&sect;2.4</a>).
 
 
-<p>
-Unless a <code>__len</code> metamethod is given,
-the length of a table <code>t</code> is only defined if the
-table is a <em>sequence</em>,
-that is,
-the set of its positive numeric keys is equal to <em>{1..n}</em>
-for some non-negative integer <em>n</em>.
-In that case, <em>n</em> is its length.
-Note that a table like
-
-<pre>
-     {10, 20, nil, 40}
-</pre><p>
-is not a sequence, because it has the key <code>4</code>
-but does not have the key <code>3</code>.
-(So, there is no <em>n</em> such that the set <em>{1..n}</em> is equal
-to the set of positive numeric keys of that table.)
-Note, however, that non-numeric keys do not interfere
-with whether a table is a sequence.
-
-
 
 
 
@@ -2585,6 +2610,28 @@
 with the macro <a name="pdf-LUA_USE_APICHECK"><code>LUA_USE_APICHECK</code></a> defined.
 
 
+<p>
+The Lua library is fully reentrant:
+it has no global variables.
+It keeps all information it needs in a dynamic structure,
+called the <em>Lua state</em>.
+
+
+<p>
+Each Lua state has one or more threads,
+which correspond to independent, cooperative lines of execution.
+The type <a href="#lua_State"><code>lua_State</code></a> (despite its name) refers to a thread.
+(Indirectly, through the thread, it also refers to the
+Lua state associated to the thread.)
+
+
+<p>
+A pointer to a thread must be passed as the first argument to
+every function in the library, except to <a href="#lua_newstate"><code>lua_newstate</code></a>,
+which creates a Lua state from scratch and returns a pointer
+to the <em>main thread</em> in the new state.
+
+
 
 <h2>4.1 &ndash; <a name="4.1">The Stack</a></h2>
 
@@ -2592,6 +2639,8 @@
 Lua uses a <em>virtual stack</em> to pass values to and from C.
 Each element in this stack represents a Lua value
 (<b>nil</b>, number, string, etc.).
+Functions in the API can access this stack through the
+Lua state parameter that they receive.
 
 
 <p>
@@ -2599,7 +2648,8 @@
 which is independent of previous stacks and of stacks of
 C&nbsp;functions that are still active.
 This stack initially contains any arguments to the C&nbsp;function
-and it is where the C&nbsp;function pushes its results
+and it is where the C&nbsp;function can store temporary
+Lua values and must push its results
 to be returned to the caller (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
 
 
@@ -2791,8 +2841,7 @@
 (Lua will use exceptions if you compile it as C++;
 search for <code>LUAI_THROW</code> in the source code for details.)
 When Lua faces any error
-(such as a memory allocation error, type errors, syntax errors,
-and runtime errors)
+(such as a memory allocation error or a type error)
 it <em>raises</em> an error;
 that is, it does a long jump.
 A <em>protected environment</em> uses <code>setjmp</code>
@@ -2801,6 +2850,17 @@
 
 
 <p>
+Inside a C&nbsp;function you can raise an error by calling <a href="#lua_error"><code>lua_error</code></a>.
+
+
+<p>
+Most functions in the API can raise an error,
+for instance due to a memory allocation error.
+The documentation for each function indicates whether
+it can raise errors.
+
+
+<p>
 If an error happens outside any protected environment,
 Lua calls a <em>panic function</em> (see <a href="#lua_atpanic"><code>lua_atpanic</code></a>)
 and then calls <code>abort</code>,
@@ -2811,6 +2871,23 @@
 
 
 <p>
+The panic function,
+as its name implies,
+is a mechanism of last resort.
+Programs should avoid it.
+As a general rule,
+when a C&nbsp;function is called by Lua with a Lua state,
+it can do whatever it wants on that Lua state,
+as it should be already protected.
+However,
+when C code operates on other Lua states
+(e.g., a Lua parameter to the function,
+a Lua state stored in the registry, or
+the result of <a href="#lua_newthread"><code>lua_newthread</code></a>),
+it should use them only in API calls that cannot raise errors.
+
+
+<p>
 The panic function runs as if it were a message handler (see <a href="#2.3">&sect;2.3</a>);
 in particular, the error object is at the top of the stack.
 However, there is no guarantee about stack space.
@@ -2818,17 +2895,6 @@
 the panic function must first check the available space (see <a href="#4.2">&sect;4.2</a>).
 
 
-<p>
-Most functions in the API can raise an error,
-for instance due to a memory allocation error.
-The documentation for each function indicates whether
-it can raise errors.
-
-
-<p>
-Inside a C&nbsp;function you can raise an error by calling <a href="#lua_error"><code>lua_error</code></a>.
-
-
 
 
 
@@ -2836,7 +2902,7 @@
 
 <p>
 Internally, Lua uses the C <code>longjmp</code> facility to yield a coroutine.
-Therefore, if a C function <code>foo</code> calls an API function
+Therefore, if a C&nbsp;function <code>foo</code> calls an API function
 and this API function yields
 (directly or indirectly by calling another function that yields),
 Lua cannot return to <code>foo</code> any more,
@@ -2854,7 +2920,7 @@
 
 <p>
 We need to set some terminology to explain continuations.
-We have a C function called from Lua which we will call
+We have a C&nbsp;function called from Lua which we will call
 the <em>original function</em>.
 This original function then calls one of those three functions in the C API,
 which we will call the <em>callee function</em>,
@@ -3169,7 +3235,7 @@
 The function results are pushed onto the stack when the function returns.
 The number of results is adjusted to <code>nresults</code>,
 unless <code>nresults</code> is <a name="pdf-LUA_MULTRET"><code>LUA_MULTRET</code></a>.
-In this case, all results from the function are pushed.
+In this case, all results from the function are pushed;
 Lua takes care that the returned values fit into the stack space,
 but it does not ensure any extra space in the stack.
 The function results are pushed onto the stack in direct order
@@ -3655,7 +3721,7 @@
 <pre>int lua_getuservalue (lua_State *L, int index);</pre>
 
 <p>
-Pushes onto the stack the Lua value associated with the userdata
+Pushes onto the stack the Lua value associated with the full userdata
 at the given index.
 
 
@@ -3998,7 +4064,8 @@
 Returns <code>NULL</code> if it cannot create the thread or the state
 (due to lack of memory).
 The argument <code>f</code> is the allocator function;
-Lua does all memory allocation for this state through this function.
+Lua does all memory allocation for this state
+through this function (see <a href="#lua_Alloc"><code>lua_Alloc</code></a>).
 The second argument, <code>ud</code>, is an opaque pointer that Lua
 passes to the allocator in every call.
 
@@ -4202,7 +4269,9 @@
 
 <li><b><a name="pdf-LUA_ERRGCMM"><code>LUA_ERRGCMM</code></a>: </b>
 error while running a <code>__gc</code> metamethod.
-(This error typically has no relation with the function being called.)
+For such errors, Lua does not call the message handler
+(as this kind of error typically has no relation
+with the function being called).
 </li>
 
 </ul>
@@ -4278,7 +4347,7 @@
 
 <p>
 When <code>n</code> is zero,
-this function creates a <em>light C function</em>,
+this function creates a <em>light C&nbsp;function</em>,
 which is just a pointer to the C&nbsp;function.
 In that case, it never raises a memory error.
 
@@ -4292,7 +4361,7 @@
 
 <p>
 Pushes a C&nbsp;function onto the stack.
-This function receives a pointer to a C function
+This function receives a pointer to a C&nbsp;function
 and pushes onto the stack a Lua value of type <code>function</code> that,
 when called, invokes the corresponding C&nbsp;function.
 
@@ -4667,7 +4736,7 @@
 <pre>void lua_register (lua_State *L, const char *name, lua_CFunction f);</pre>
 
 <p>
-Sets the C function <code>f</code> as the new value of global <code>name</code>.
+Sets the C&nbsp;function <code>f</code> as the new value of global <code>name</code>.
 It is defined as a macro:
 
 <pre>
@@ -4888,7 +4957,7 @@
 
 <p>
 Pops a value from the stack and sets it as
-the new value associated to the userdata at the given index.
+the new value associated to the full userdata at the given index.
 
 
 
@@ -5302,7 +5371,7 @@
 <p>
 When the coroutine is resumed again,
 Lua calls the given continuation function <code>k</code> to continue
-the execution of the C function that yielded (see <a href="#4.7">&sect;4.7</a>).
+the execution of the C&nbsp;function that yielded (see <a href="#4.7">&sect;4.7</a>).
 This continuation function receives the same stack
 from the previous function,
 with the <code>n</code> results removed and
@@ -6013,7 +6082,7 @@
 
 <p>
 Raises an error reporting a problem with argument <code>arg</code>
-of the C function that called it,
+of the C&nbsp;function that called it,
 using a standard message
 that includes <code>extramsg</code> as a comment:
 
@@ -6534,7 +6603,8 @@
 <p>
 This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>,
 but it has an extra error code <a name="pdf-LUA_ERRFILE"><code>LUA_ERRFILE</code></a>
-if it cannot open/read the file or the file has a wrong mode.
+for file-related errors
+(e.g., it cannot open or read the file).
 
 
 <p>
@@ -6727,6 +6797,11 @@
 its length is considered zero.
 
 
+<p>
+This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result,
+so all conversions and caveats of that function apply here.
+
+
 
 
 
@@ -7674,7 +7749,7 @@
 
 <p>
 A running coroutine is yieldable if it is not the main thread and
-it is not inside a non-yieldable C function.
+it is not inside a non-yieldable C&nbsp;function.
 
 
 
@@ -7876,8 +7951,8 @@
 <p>
 Lua initializes the C&nbsp;path <a href="#pdf-package.cpath"><code>package.cpath</code></a> in the same way
 it initializes the Lua path <a href="#pdf-package.path"><code>package.path</code></a>,
-using the environment variable <a name="pdf-LUA_CPATH_5_3"><code>LUA_CPATH_5_3</code></a>
-or the environment variable <a name="pdf-LUA_CPATH"><code>LUA_CPATH</code></a>
+using the environment variable <a name="pdf-LUA_CPATH_5_3"><code>LUA_CPATH_5_3</code></a>,
+or the environment variable <a name="pdf-LUA_CPATH"><code>LUA_CPATH</code></a>,
 or a default path defined in <code>luaconf.h</code>.
 
 
@@ -8434,7 +8509,7 @@
 <p>
 Returns a binary string containing the values <code>v1</code>, <code>v2</code>, etc.
 packed (that is, serialized in binary form)
-according to the format string <code>fmt</code> (see <a href="#6.4.2">&sect;6.4.2</a>). 
+according to the format string <code>fmt</code> (see <a href="#6.4.2">&sect;6.4.2</a>).
 
 
 
@@ -8485,7 +8560,8 @@
 In particular,
 the call <code>string.sub(s,1,j)</code> returns a prefix of <code>s</code>
 with length <code>j</code>,
-and <code>string.sub(s, -i)</code> returns a suffix of <code>s</code>
+and <code>string.sub(s, -i)</code> (for a positive <code>i</code>)
+returns a suffix of <code>s</code>
 with length <code>i</code>.
 
 
@@ -8902,7 +8978,7 @@
 that start between positions <code>i</code> and <code>j</code> (both inclusive).
 The default for <code>i</code> is 1 and for <code>j</code> is -1.
 If it finds any invalid byte sequence,
-returns a false value plus the position of the first invalid byte. 
+returns a false value plus the position of the first invalid byte.
 
 
 
@@ -8946,8 +9022,7 @@
 
 <p>
 Remember that, whenever an operation needs the length of a table,
-the table must be a proper sequence
-or have a <code>__len</code> metamethod (see <a href="#3.4.7">&sect;3.4.7</a>).
+all caveats about the length operator apply (see <a href="#3.4.7">&sect;3.4.7</a>).
 All functions ignore non-numeric keys
 in the tables given as arguments.
 
@@ -9063,9 +9138,8 @@
 
 
 <p>
-The sort algorithm is not stable;
-that is, elements not comparable by the given order
-(e.g., equal elements)
+The sort algorithm is not stable:
+elements considered equal by the given order
 may have their relative positions changed by the sort.
 
 
@@ -9401,7 +9475,7 @@
 
 <p>
 Returns a boolean,
-true if integer <code>m</code> is below integer <code>n</code> when
+true if and only if integer <code>m</code> is below integer <code>n</code> when
 they are compared as unsigned integers.
 
 
@@ -9987,6 +10061,7 @@
 with the given name.
 If this function fails, it returns <b>nil</b>,
 plus a string describing the error and the error code.
+Otherwise, it returns true.
 
 
 
@@ -9996,9 +10071,10 @@
 
 
 <p>
-Renames file or directory named <code>oldname</code> to <code>newname</code>.
+Renames the file or directory named <code>oldname</code> to <code>newname</code>.
 If this function fails, it returns <b>nil</b>,
 plus a string describing the error and the error code.
+Otherwise, it returns true.
 
 
 
@@ -10291,7 +10367,7 @@
 
 <p>
 Returns the Lua value associated to <code>u</code>.
-If <code>u</code> is not a userdata,
+If <code>u</code> is not a full userdata,
 returns <b>nil</b>.
 
 
@@ -10490,7 +10566,7 @@
 
 
 <p>
-When called without option <code>-E</code>, 
+When called without option <code>-E</code>,
 the interpreter checks for an environment variable <a name="pdf-LUA_INIT_5_3"><code>LUA_INIT_5_3</code></a>
 (or <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a> if the versioned name is not defined)
 before running any argument.
@@ -10582,7 +10658,7 @@
 <p>
 In case of unprotected errors in the script,
 the interpreter reports the error to the standard error stream.
-If the error object is not a string but 
+If the error object is not a string but
 has a metamethod <code>__tostring</code>,
 the interpreter calls this metamethod to produce the final message.
 Otherwise, the interpreter converts the error object to a string
@@ -10897,13 +10973,12 @@
 
 
 
-
 <P CLASS="footer">
 Last update:
-Mon May 30 13:11:08 BRT 2016
+Mon Jan  9 13:30:53 BRST 2017
 </P>
 <!--
-Last change: revised for Lua 5.3.3
+Last change: revised for Lua 5.3.4
 -->
 
 </body></html>
--- a/external/mit/lua/dist/doc/readme.html	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/doc/readme.html	Tue May 02 03:19:14 2017 +0000
@@ -328,7 +328,7 @@
 <A HREF="http://www.lua.org/license.html">this</A>.
 
 <BLOCKQUOTE STYLE="padding-bottom: 0em">
-Copyright &copy; 1994&ndash;2016 Lua.org, PUC-Rio.
+Copyright &copy; 1994&ndash;2017 Lua.org, PUC-Rio.
 
 <P>
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -355,10 +355,10 @@
 
 <P CLASS="footer">
 Last update:
-Tue Feb  2 22:25:27 BRST 2016
+Thu Dec 22 18:22:57 BRST 2016
 </P>
 <!--
-Last change: revised for Lua 5.3.3
+Last change: revised for Lua 5.3.4
 -->
 
 </BODY>
--- a/external/mit/lua/dist/src/lapi.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lapi.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lapi.c,v 1.7 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lapi.c,v 1.7.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lapi.c,v 2.259 2016/02/29 14:27:14 roberto Exp 
--- a/external/mit/lua/dist/src/lapi.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lapi.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lapi.h,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lapi.h,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp 
--- a/external/mit/lua/dist/src/lauxlib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lauxlib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lauxlib.c,v 1.7 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lauxlib.c,v 1.7.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lauxlib.c,v 1.286 2016/01/08 15:33:09 roberto Exp 
+** Id: lauxlib.c,v 1.289 2016/12/20 18:37:00 roberto Exp 
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -75,12 +75,11 @@
 
 /*
 ** Search for a name for a function in all loaded modules
-** (registry._LOADED).
 */
 static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
   int top = lua_gettop(L);
   lua_getinfo(L, "f", ar);  /* push function */
-  lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+  lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
   if (findfield(L, top + 1, 2)) {
     const char *name = lua_tostring(L, -1);
     if (strncmp(name, "_G.", 3) == 0) {  /* name start with '_G.'? */
@@ -823,13 +822,21 @@
 
 
 LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
-  if (!luaL_callmeta(L, idx, "__tostring")) {  /* no metafield? */
+  if (luaL_callmeta(L, idx, "__tostring")) {  /* metafield? */
+    if (!lua_isstring(L, -1))
+      luaL_error(L, "'__tostring' must return a string");
+  }
+  else {
     switch (lua_type(L, idx)) {
       case LUA_TNUMBER: {
+#ifndef _KERNEL
         if (lua_isinteger(L, idx))
-          lua_pushfstring(L, "%I", lua_tointeger(L, idx));
+#endif
+          lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx));
+#ifndef _KERNEL
         else
-          lua_pushfstring(L, "%f", lua_tonumber(L, idx));
+          lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx));
+#endif
         break;
       }
       case LUA_TSTRING:
@@ -841,10 +848,15 @@
       case LUA_TNIL:
         lua_pushliteral(L, "nil");
         break;
-      default:
-        lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
-                                            lua_topointer(L, idx));
+      default: {
+        int tt = luaL_getmetafield(L, idx, "__name");  /* try name */
+        const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) :
+                                                 luaL_typename(L, idx);
+        lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx));
+        if (tt != LUA_TNIL)
+          lua_remove(L, -2);  /* remove '__name' */
         break;
+      }
     }
   }
   return lua_tolstring(L, -1, len);
@@ -896,23 +908,23 @@
 
 /*
 ** Find or create a module table with a given name. The function
-** first looks at the _LOADED table and, if that fails, try a
+** first looks at the LOADED table and, if that fails, try a
 ** global variable with that name. In any case, leaves on the stack
 ** the module table.
 */
 LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
                                  int sizehint) {
-  luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);  /* get _LOADED table */
-  if (lua_getfield(L, -1, modname) != LUA_TTABLE) {  /* no _LOADED[modname]? */
+  luaL_findtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE, 1);
+  if (lua_getfield(L, -1, modname) != LUA_TTABLE) {  /* no LOADED[modname]? */
     lua_pop(L, 1);  /* remove previous result */
     /* try global variable (and create one if it does not exist) */
     lua_pushglobaltable(L);
     if (luaL_findtable(L, 0, modname, sizehint) != NULL)
       luaL_error(L, "name conflict for module '%s'", modname);
     lua_pushvalue(L, -1);
-    lua_setfield(L, -3, modname);  /* _LOADED[modname] = new table */
+    lua_setfield(L, -3, modname);  /* LOADED[modname] = new table */
   }
-  lua_remove(L, -2);  /* remove _LOADED table */
+  lua_remove(L, -2);  /* remove LOADED table */
 }
 
 
@@ -976,17 +988,17 @@
 */
 LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
                                lua_CFunction openf, int glb) {
-  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
-  lua_getfield(L, -1, modname);  /* _LOADED[modname] */
+  luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
+  lua_getfield(L, -1, modname);  /* LOADED[modname] */
   if (!lua_toboolean(L, -1)) {  /* package not already loaded? */
     lua_pop(L, 1);  /* remove field */
     lua_pushcfunction(L, openf);
     lua_pushstring(L, modname);  /* argument to open function */
     lua_call(L, 1, 1);  /* call 'openf' to open module */
     lua_pushvalue(L, -1);  /* make copy of module (call result) */
-    lua_setfield(L, -3, modname);  /* _LOADED[modname] = module */
+    lua_setfield(L, -3, modname);  /* LOADED[modname] = module */
   }
-  lua_remove(L, -2);  /* remove _LOADED table */
+  lua_remove(L, -2);  /* remove LOADED table */
   if (glb) {
     lua_pushvalue(L, -1);  /* copy of module */
     lua_setglobal(L, modname);  /* _G[modname] = module */
@@ -1044,8 +1056,10 @@
     luaL_error(L, "core and library have incompatible numeric types");
   if (v != lua_version(NULL))
     luaL_error(L, "multiple Lua VMs detected");
+#ifndef _KERNEL
   else if (*v != ver)
     luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
-                  ver, *v);
+                  (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)*v);
+#endif
 }
 
--- a/external/mit/lua/dist/src/lauxlib.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lauxlib.h	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lauxlib.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lauxlib.h,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lauxlib.h,v 1.129 2015/11/23 11:29:43 roberto Exp 
+** Id: lauxlib.h,v 1.131 2016/12/06 14:54:31 roberto Exp 
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -20,10 +20,18 @@
 
 
 
-/* extra error code for 'luaL_load' */
+/* extra error code for 'luaL_loadfilex' */
 #define LUA_ERRFILE     (LUA_ERRERR+1)
 
 
+/* key, in the registry, for table of loaded modules */
+#define LUA_LOADED_TABLE	"_LOADED"
+
+
+/* key, in the registry, for table of preloaded loaders */
+#define LUA_PRELOAD_TABLE	"_PRELOAD"
+
+
 typedef struct luaL_Reg {
   const char *name;
   lua_CFunction func;
--- a/external/mit/lua/dist/src/lbaselib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lbaselib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lbaselib.c,v 1.7 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lbaselib.c,v 1.7.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lbaselib.c,v 1.313 2016/04/11 19:18:40 roberto Exp 
+** Id: lbaselib.c,v 1.314 2016/09/05 19:06:34 roberto Exp 
 ** Basic library
 ** See Copyright Notice in lua.h
 */
@@ -212,8 +212,8 @@
 
 static int pairsmeta (lua_State *L, const char *method, int iszero,
                       lua_CFunction iter) {
+  luaL_checkany(L, 1);
   if (luaL_getmetafield(L, 1, method) == LUA_TNIL) {  /* no metamethod? */
-    luaL_checktype(L, 1, LUA_TTABLE);  /* argument must be a table */
     lua_pushcfunction(L, iter);  /* will return generator, */
     lua_pushvalue(L, 1);  /* state, */
     if (iszero) lua_pushinteger(L, 0);  /* and initial value */
--- a/external/mit/lua/dist/src/lbitlib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lbitlib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lbitlib.c,v 1.4 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lbitlib.c,v 1.4.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lbitlib.c,v 1.30 2015/11/11 19:08:09 roberto Exp 
--- a/external/mit/lua/dist/src/lcode.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lcode.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lcode.c,v 1.8 2016/09/08 20:57:20 salazar Exp $	*/
+/*	$NetBSD: lcode.c,v 1.8.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lcode.c,v 2.109 2016/05/13 19:09:21 roberto Exp 
+** Id: lcode.c,v 2.112 2016/12/22 13:08:50 roberto Exp 
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -44,7 +44,7 @@
 ** If expression is a numeric constant, fills 'v' with its value
 ** and returns 1. Otherwise, returns 0.
 */
-static int tonumeral(expdesc *e, TValue *v) {
+static int tonumeral(const expdesc *e, TValue *v) {
   if (hasjumps(e))
     return 0;  /* not a numeral */
   switch (e->k) {
@@ -92,7 +92,7 @@
 /*
 ** Gets the destination address of a jump instruction. Used to traverse
 ** a list of jumps.
-*/ 
+*/
 static int getjump (FuncState *fs, int pc) {
   int offset = GETARG_sBx(fs->f->code[pc]);
   if (offset == NO_JUMP)  /* point to itself represents end of list */
@@ -765,7 +765,7 @@
 ** (that is, it is either in a register or in 'k' with an index
 ** in the range of R/K indices).
 ** Returns R/K index.
-*/  
+*/
 int luaK_exp2RK (FuncState *fs, expdesc *e) {
   luaK_exp2val(fs, e);
   switch (e->k) {  /* move constants to 'k' */
@@ -1000,7 +1000,8 @@
 ** Try to "constant-fold" an operation; return 1 iff successful.
 ** (In this case, 'e1' has the final result.)
 */
-static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
+static int constfolding (FuncState *fs, int op, expdesc *e1,
+                                                const expdesc *e2) {
   TValue v1, v2, res;
   if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
     return 0;  /* non-numeric operands or not safe to fold */
@@ -1043,6 +1044,9 @@
 ** (everything but logical operators 'and'/'or' and comparison
 ** operators).
 ** Expression to produce final result will be encoded in 'e1'.
+** Because 'luaK_exp2RK' can free registers, its calls must be
+** in "stack order" (that is, first on 'e2', which may have more
+** recent registers to be released).
 */
 static void codebinexpval (FuncState *fs, OpCode op,
                            expdesc *e1, expdesc *e2, int line) {
@@ -1089,9 +1093,9 @@
 ** Aplly prefix operation 'op' to expression 'e'.
 */
 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
-  static expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};  /* fake 2nd operand */
+  static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
   switch (op) {
-    case OPR_MINUS: case OPR_BNOT:
+    case OPR_MINUS: case OPR_BNOT:  /* use 'ef' as fake 2nd operand */
       if (constfolding(fs, op + LUA_OPUNM, e, &ef))
         break;
       /* FALLTHROUGH */
--- a/external/mit/lua/dist/src/lcode.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lcode.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lcode.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lcode.h,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lcode.h,v 1.64 2016/01/05 16:22:37 roberto Exp 
--- a/external/mit/lua/dist/src/lcorolib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lcorolib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lcorolib.c,v 1.4 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lcorolib.c,v 1.4.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lcorolib.c,v 1.10 2016/04/11 19:19:55 roberto Exp 
--- a/external/mit/lua/dist/src/lctype.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lctype.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lctype.c,v 1.4 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lctype.c,v 1.4.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp 
--- a/external/mit/lua/dist/src/lctype.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lctype.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lctype.h,v 1.4 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lctype.h,v 1.4.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp 
--- a/external/mit/lua/dist/src/ldblib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ldblib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: ldblib.c,v 1.8 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ldblib.c,v 1.8.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: ldblib.c,v 1.151 2015/11/23 11:29:43 roberto Exp 
--- a/external/mit/lua/dist/src/ldebug.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ldebug.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: ldebug.c,v 1.7 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ldebug.c,v 1.7.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: ldebug.c,v 2.120 2016/03/31 19:01:21 roberto Exp 
+** Id: ldebug.c,v 2.121 2016/10/19 12:32:10 roberto Exp 
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -42,7 +42,8 @@
 #define ci_func(ci)		(clLvalue((ci)->func))
 
 
-static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
+static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
+                                    const char **name);
 
 
 static int currentpc (CallInfo *ci) {
@@ -248,6 +249,20 @@
 }
 
 
+static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
+  if (ci == NULL)  /* no 'ci'? */
+    return NULL;  /* no info */
+  else if (ci->callstatus & CIST_FIN) {  /* is this a finalizer? */
+    *name = "__gc";
+    return "metamethod";  /* report it as such */
+  }
+  /* calling function is a known Lua function? */
+  else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
+    return funcnamefromcode(L, ci->previous, name);
+  else return NULL;  /* no way to find a name */
+}
+
+
 static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
                        Closure *f, CallInfo *ci) {
   int status = 1;
@@ -278,11 +293,7 @@
         break;
       }
       case 'n': {
-        /* calling function is a known Lua function? */
-        if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
-          ar->namewhat = getfuncname(L, ci->previous, &ar->name);
-        else
-          ar->namewhat = NULL;
+        ar->namewhat = getfuncname(L, ci, &ar->name);
         if (ar->namewhat == NULL) {
           ar->namewhat = "";  /* not found */
           ar->name = NULL;
@@ -475,8 +486,15 @@
 }
 
 
-static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
-  TMS tm = (TMS)0;  /* to avoid warnings */
+/*
+** Try to find a name for a function based on the code that called it.
+** (Only works when function was called by a Lua function.)
+** Returns what the name is (e.g., "for iterator", "method",
+** "metamethod") and sets '*name' to point to the name.
+*/
+static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
+                                     const char **name) {
+  TMS tm = (TMS)0;  /* (initial value avoids warnings) */
   Proto *p = ci_func(ci)->p;  /* calling function */
   int pc = currentpc(ci);  /* calling instruction index */
   Instruction i = p->code[pc];  /* calling instruction */
@@ -486,13 +504,13 @@
   }
   switch (GET_OPCODE(i)) {
     case OP_CALL:
-    case OP_TAILCALL:  /* get function name */
-      return getobjname(p, pc, GETARG_A(i), name);
+    case OP_TAILCALL:
+      return getobjname(p, pc, GETARG_A(i), name);  /* get function name */
     case OP_TFORCALL: {  /* for iterator */
       *name = "for iterator";
        return "for iterator";
     }
-    /* all other instructions can call only through metamethods */
+    /* other instructions can do calls through metamethods */
     case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
       tm = TM_INDEX;
       break;
@@ -517,7 +535,8 @@
     case OP_EQ: tm = TM_EQ; break;
     case OP_LT: tm = TM_LT; break;
     case OP_LE: tm = TM_LE; break;
-    default: lua_assert(0);  /* other instructions cannot call a function */
+    default:
+      return NULL;  /* cannot find a reasonable name */
   }
   *name = getstr(G(L)->tmname[tm]);
   return "metamethod";
--- a/external/mit/lua/dist/src/ldebug.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ldebug.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: ldebug.h,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ldebug.h,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp 
--- a/external/mit/lua/dist/src/ldo.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ldo.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: ldo.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ldo.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: ldo.c,v 2.151 2015/12/16 16:40:07 roberto Exp 
+** Id: ldo.c,v 2.157 2016/12/13 15:52:21 roberto Exp 
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -215,9 +215,9 @@
   CallInfo *ci;
   StkId lim = L->top;
   for (ci = L->ci; ci != NULL; ci = ci->previous) {
-    lua_assert(ci->top <= L->stack_last);
     if (lim < ci->top) lim = ci->top;
   }
+  lua_assert(lim <= L->stack_last);
   return cast_int(lim - L->stack) + 1;  /* part of stack in use */
 }
 
@@ -225,16 +225,19 @@
 void luaD_shrinkstack (lua_State *L) {
   int inuse = stackinuse(L);
   int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
-  if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
-  if (L->stacksize > LUAI_MAXSTACK)  /* was handling stack overflow? */
+  if (goodsize > LUAI_MAXSTACK)
+    goodsize = LUAI_MAXSTACK;  /* respect stack limit */
+  if (L->stacksize > LUAI_MAXSTACK)  /* had been handling stack overflow? */
     luaE_freeCI(L);  /* free all CIs (list grew because of an error) */
   else
     luaE_shrinkCI(L);  /* shrink list */
-  if (inuse <= LUAI_MAXSTACK &&  /* not handling stack overflow? */
-      goodsize < L->stacksize)  /* trying to shrink? */
-    luaD_reallocstack(L, goodsize);  /* shrink it */
-  else
-    condmovestack(L,,);  /* don't change stack (change only for debugging) */
+  /* if thread is currently not handling a stack overflow and its
+     good size is smaller than current size, shrink its stack */
+  if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
+      goodsize < L->stacksize)
+    luaD_reallocstack(L, goodsize);
+  else  /* don't change stack */
+    condmovestack(L,{},{});  /* (change only for debugging) */
 }
 
 
@@ -326,86 +329,6 @@
 }
 
 
-
-#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
-
-
-/* macro to check stack size, preserving 'p' */
-#define checkstackp(L,n,p)  \
-  luaD_checkstackaux(L, n, \
-    ptrdiff_t t__ = savestack(L, p);  /* save 'p' */ \
-    luaC_checkGC(L),  /* stack grow uses memory */ \
-    p = restorestack(L, t__))  /* 'pos' part: restore 'p' */
-
-
-/*
-** Prepares a function call: checks the stack, creates a new CallInfo
-** entry, fills in the relevant information, calls hook if needed.
-** If function is a C function, does the call, too. (Otherwise, leave
-** the execution ('luaV_execute') to the caller, to allow stackless
-** calls.) Returns true iff function has been executed (C function).
-*/
-int luaD_precall (lua_State *L, StkId func, int nresults) {
-  lua_CFunction f;
-  CallInfo *ci;
-  switch (ttype(func)) {
-    case LUA_TCCL:  /* C closure */
-      f = clCvalue(func)->f;
-      goto Cfunc;
-    case LUA_TLCF:  /* light C function */
-      f = fvalue(func);
-     Cfunc: {
-      int n;  /* number of returns */
-      checkstackp(L, LUA_MINSTACK, func);  /* ensure minimum stack size */
-      ci = next_ci(L);  /* now 'enter' new function */
-      ci->nresults = nresults;
-      ci->func = func;
-      ci->top = L->top + LUA_MINSTACK;
-      lua_assert(ci->top <= L->stack_last);
-      ci->callstatus = 0;
-      if (L->hookmask & LUA_MASKCALL)
-        luaD_hook(L, LUA_HOOKCALL, -1);
-      lua_unlock(L);
-      n = (*f)(L);  /* do the actual call */
-      lua_lock(L);
-      api_checknelems(L, n);
-      luaD_poscall(L, ci, L->top - n, n);
-      return 1;
-    }
-    case LUA_TLCL: {  /* Lua function: prepare its call */
-      StkId base;
-      Proto *p = clLvalue(func)->p;
-      int n = cast_int(L->top - func) - 1;  /* number of real arguments */
-      int fsize = p->maxstacksize;  /* frame size */
-      checkstackp(L, fsize, func);
-      if (p->is_vararg != 1) {  /* do not use vararg? */
-        for (; n < p->numparams; n++)
-          setnilvalue(L->top++);  /* complete missing arguments */
-        base = func + 1;
-      }
-      else
-        base = adjust_varargs(L, p, n);
-      ci = next_ci(L);  /* now 'enter' new function */
-      ci->nresults = nresults;
-      ci->func = func;
-      ci->u.l.base = base;
-      L->top = ci->top = base + fsize;
-      lua_assert(ci->top <= L->stack_last);
-      ci->u.l.savedpc = p->code;  /* starting point */
-      ci->callstatus = CIST_LUA;
-      if (L->hookmask & LUA_MASKCALL)
-        callhook(L, ci);
-      return 0;
-    }
-    default: {  /* not a function */
-      checkstackp(L, 1, func);  /* ensure space for metamethod */
-      tryfuncTM(L, func);  /* try to get '__call' metamethod */
-      return luaD_precall(L, func, nresults);  /* now it must be a function */
-    }
-  }
-}
-
-
 /*
 ** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'.
 ** Handle most typical cases (zero results for commands, one result for
@@ -472,6 +395,86 @@
 }
 
 
+
+#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
+
+
+/* macro to check stack size, preserving 'p' */
+#define checkstackp(L,n,p)  \
+  luaD_checkstackaux(L, n, \
+    ptrdiff_t t__ = savestack(L, p);  /* save 'p' */ \
+    luaC_checkGC(L),  /* stack grow uses memory */ \
+    p = restorestack(L, t__))  /* 'pos' part: restore 'p' */
+
+
+/*
+** Prepares a function call: checks the stack, creates a new CallInfo
+** entry, fills in the relevant information, calls hook if needed.
+** If function is a C function, does the call, too. (Otherwise, leave
+** the execution ('luaV_execute') to the caller, to allow stackless
+** calls.) Returns true iff function has been executed (C function).
+*/
+int luaD_precall (lua_State *L, StkId func, int nresults) {
+  lua_CFunction f;
+  CallInfo *ci;
+  switch (ttype(func)) {
+    case LUA_TCCL:  /* C closure */
+      f = clCvalue(func)->f;
+      goto Cfunc;
+    case LUA_TLCF:  /* light C function */
+      f = fvalue(func);
+     Cfunc: {
+      int n;  /* number of returns */
+      checkstackp(L, LUA_MINSTACK, func);  /* ensure minimum stack size */
+      ci = next_ci(L);  /* now 'enter' new function */
+      ci->nresults = nresults;
+      ci->func = func;
+      ci->top = L->top + LUA_MINSTACK;
+      lua_assert(ci->top <= L->stack_last);
+      ci->callstatus = 0;
+      if (L->hookmask & LUA_MASKCALL)
+        luaD_hook(L, LUA_HOOKCALL, -1);
+      lua_unlock(L);
+      n = (*f)(L);  /* do the actual call */
+      lua_lock(L);
+      api_checknelems(L, n);
+      luaD_poscall(L, ci, L->top - n, n);
+      return 1;
+    }
+    case LUA_TLCL: {  /* Lua function: prepare its call */
+      StkId base;
+      Proto *p = clLvalue(func)->p;
+      int n = cast_int(L->top - func) - 1;  /* number of real arguments */
+      int fsize = p->maxstacksize;  /* frame size */
+      checkstackp(L, fsize, func);
+      if (p->is_vararg)
+        base = adjust_varargs(L, p, n);
+      else {  /* non vararg function */
+        for (; n < p->numparams; n++)
+          setnilvalue(L->top++);  /* complete missing arguments */
+        base = func + 1;
+      }
+      ci = next_ci(L);  /* now 'enter' new function */
+      ci->nresults = nresults;
+      ci->func = func;
+      ci->u.l.base = base;
+      L->top = ci->top = base + fsize;
+      lua_assert(ci->top <= L->stack_last);
+      ci->u.l.savedpc = p->code;  /* starting point */
+      ci->callstatus = CIST_LUA;
+      if (L->hookmask & LUA_MASKCALL)
+        callhook(L, ci);
+      return 0;
+    }
+    default: {  /* not a function */
+      checkstackp(L, 1, func);  /* ensure space for metamethod */
+      tryfuncTM(L, func);  /* try to get '__call' metamethod */
+      return luaD_precall(L, func, nresults);  /* now it must be a function */
+    }
+  }
+}
+
+
 /*
 ** Check appropriate error for stack overflow ("regular" overflow or
 ** overflow while handling stack overflow). If 'nCalls' is larger than
@@ -524,19 +527,17 @@
   /* error status can only happen in a protected call */
   lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
   if (ci->callstatus & CIST_YPCALL) {  /* was inside a pcall? */
-    ci->callstatus &= ~CIST_YPCALL;  /* finish 'lua_pcall' */
-    L->errfunc = ci->u.c.old_errfunc;
+    ci->callstatus &= ~CIST_YPCALL;  /* continuation is also inside it */
+    L->errfunc = ci->u.c.old_errfunc;  /* with the same error function */
   }
   /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
      handled */
   adjustresults(L, ci->nresults);
-  /* call continuation function */
   lua_unlock(L);
-  n = (*ci->u.c.k)(L, status, ci->u.c.ctx);
+  n = (*ci->u.c.k)(L, status, ci->u.c.ctx);  /* call continuation function */
   lua_lock(L);
   api_checknelems(L, n);
-  /* finish 'luaD_precall' */
-  luaD_poscall(L, ci, L->top - n, n);
+  luaD_poscall(L, ci, L->top - n, n);  /* finish 'luaD_precall' */
 }
 
 
@@ -599,15 +600,16 @@
 
 
 /*
-** signal an error in the call to 'resume', not in the execution of the
-** coroutine itself. (Such errors should not be handled by any coroutine
-** error handler and should not kill the coroutine.)
+** Signal an error in the call to 'lua_resume', not in the execution
+** of the coroutine itself. (Such errors should not be handled by any
+** coroutine error handler and should not kill the coroutine.)
 */
-static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
-  L->top = firstArg;  /* remove args from the stack */
+static int resume_error (lua_State *L, const char *msg, int narg) {
+  L->top -= narg;  /* remove args from the stack */
   setsvalue2s(L, L->top, luaS_new(L, msg));  /* push error message */
   api_incr_top(L);
-  luaD_throw(L, -1);  /* jump back to 'lua_resume' */
+  lua_unlock(L);
+  return LUA_ERRRUN;
 }
 
 
@@ -619,22 +621,15 @@
 ** coroutine.
 */
 static void resume (lua_State *L, void *ud) {
-  int nCcalls = L->nCcalls;
   int n = *(cast(int*, ud));  /* number of arguments */
   StkId firstArg = L->top - n;  /* first argument */
   CallInfo *ci = L->ci;
-  if (nCcalls >= LUAI_MAXCCALLS)
-    resume_error(L, "C stack overflow", firstArg);
-  if (L->status == LUA_OK) {  /* may be starting a coroutine */
-    if (ci != &L->base_ci)  /* not in base level? */
-      resume_error(L, "cannot resume non-suspended coroutine", firstArg);
-    /* coroutine is in base level; start running it */
+  if (L->status == LUA_OK) {  /* starting a coroutine? */
     if (!luaD_precall(L, firstArg - 1, LUA_MULTRET))  /* Lua function? */
       luaV_execute(L);  /* call it */
   }
-  else if (L->status != LUA_YIELD)
-    resume_error(L, "cannot resume dead coroutine", firstArg);
   else {  /* resuming from previous yield */
+    lua_assert(L->status == LUA_YIELD);
     L->status = LUA_OK;  /* mark that it is running (again) */
     ci->func = restorestack(L, ci->extra);
     if (isLua(ci))  /* yielded inside a hook? */
@@ -651,7 +646,6 @@
     }
     unroll(L, NULL);  /* run continuation */
   }
-  lua_assert(nCcalls == L->nCcalls);
 }
 
 
@@ -659,8 +653,16 @@
   int status;
   unsigned short oldnny = L->nny;  /* save "number of non-yieldable" calls */
   lua_lock(L);
+  if (L->status == LUA_OK) {  /* may be starting a coroutine */
+    if (L->ci != &L->base_ci)  /* not in base level? */
+      return resume_error(L, "cannot resume non-suspended coroutine", nargs);
+  }
+  else if (L->status != LUA_YIELD)
+    return resume_error(L, "cannot resume dead coroutine", nargs);
+  L->nCcalls = (from) ? from->nCcalls + 1 : 1;
+  if (L->nCcalls >= LUAI_MAXCCALLS)
+    return resume_error(L, "C stack overflow", nargs);
   luai_userstateresume(L, nargs);
-  L->nCcalls = (from) ? from->nCcalls + 1 : 1;
   L->nny = 0;  /* allow yields */
   api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
   status = luaD_rawrunprotected(L, resume, &nargs);
--- a/external/mit/lua/dist/src/ldo.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ldo.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: ldo.h,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ldo.h,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp 
--- a/external/mit/lua/dist/src/ldump.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ldump.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: ldump.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ldump.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: ldump.c,v 2.37 2015/10/08 15:53:49 roberto Exp 
--- a/external/mit/lua/dist/src/lfunc.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lfunc.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lfunc.c,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lfunc.c,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lfunc.c,v 2.45 2014/11/02 19:19:04 roberto Exp 
--- a/external/mit/lua/dist/src/lfunc.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lfunc.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lfunc.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lfunc.h,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp 
--- a/external/mit/lua/dist/src/lgc.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lgc.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lgc.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lgc.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lgc.c,v 2.212 2016/03/31 19:02:03 roberto Exp 
+** Id: lgc.c,v 2.215 2016/12/22 13:08:50 roberto Exp 
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -471,7 +471,7 @@
   else  /* not weak */
     traversestrongtable(g, h);
   return sizeof(Table) + sizeof(TValue) * h->sizearray +
-                         sizeof(Node) * cast(size_t, sizenode(h));
+                         sizeof(Node) * cast(size_t, allocsizenode(h));
 }
 
 
@@ -543,7 +543,7 @@
     StkId lim = th->stack + th->stacksize;  /* real end of stack */
     for (; o < lim; o++)  /* clear not-marked stack slice */
       setnilvalue(o);
-    /* 'remarkupvals' may have removed thread from 'twups' list */ 
+    /* 'remarkupvals' may have removed thread from 'twups' list */
     if (!isintwups(th) && th->openupval != NULL) {
       th->twups = g->twups;  /* link it back to the list */
       g->twups = th;
@@ -822,7 +822,9 @@
     setobj2s(L, L->top, tm);  /* push finalizer... */
     setobj2s(L, L->top + 1, &v);  /* ... and its argument */
     L->top += 2;  /* and (next line) call the finalizer */
+    L->ci->callstatus |= CIST_FIN;  /* will run a finalizer */
     status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
+    L->ci->callstatus &= ~CIST_FIN;  /* not running a finalizer anymore */
     L->allowhook = oldah;  /* restore hooks */
     g->gcrunning = running;  /* restore state */
     if (status != LUA_OK && propagateerrors) {  /* error while running __gc? */
--- a/external/mit/lua/dist/src/lgc.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lgc.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lgc.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lgc.h,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lgc.h,v 2.91 2015/12/21 13:02:14 roberto Exp 
--- a/external/mit/lua/dist/src/linit.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/linit.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: linit.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: linit.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: linit.c,v 1.38 2015/01/05 13:48:33 roberto Exp 
+** Id: linit.c,v 1.39 2016/12/04 20:17:24 roberto Exp 
 ** Initialization of libraries for lua.c and other clients
 ** See Copyright Notice in lua.h
 */
@@ -20,10 +20,10 @@
 ** open the library, which is already linked to the application.
 ** For that, do the following code:
 **
-**  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
+**  luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
 **  lua_pushcfunction(L, luaopen_modname);
 **  lua_setfield(L, -2, modname);
-**  lua_pop(L, 1);  // remove _PRELOAD table
+**  lua_pop(L, 1);  // remove PRELOAD table
 */
 
 #include "lprefix.h"
--- a/external/mit/lua/dist/src/liolib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/liolib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: liolib.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: liolib.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: liolib.c,v 2.149 2016/05/02 14:03:19 roberto Exp 
+** Id: liolib.c,v 2.151 2016/12/20 18:37:00 roberto Exp 
 ** Standard I/O (and system) library
 ** See Copyright Notice in lua.h
 */
@@ -39,10 +39,11 @@
 #endif
 
 /* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */
-#define l_checkmode(mode) \
-	(*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&	\
-	(*mode != '+' || (++mode, 1)) &&  /* skip if char is '+' */	\
-	(strspn(mode, L_MODEEXT) == strlen(mode)))
+static int l_checkmode (const char *mode) {
+  return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&
+         (*mode != '+' || (++mode, 1)) &&  /* skip if char is '+' */
+         (strspn(mode, L_MODEEXT) == strlen(mode)));  /* check extensions */
+}
 
 #endif
 
@@ -620,8 +621,10 @@
     if (lua_type(L, arg) == LUA_TNUMBER) {
       /* optimization: could be done exactly as for strings */
       int len = lua_isinteger(L, arg)
-                ? fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg))
-                : fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg));
+                ? fprintf(f, LUA_INTEGER_FMT,
+                             (LUAI_UACINT)lua_tointeger(L, arg))
+                : fprintf(f, LUA_NUMBER_FMT,
+                             (LUAI_UACNUMBER)lua_tonumber(L, arg));
       status = status && (len > 0);
     }
     else {
--- a/external/mit/lua/dist/src/llex.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/llex.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: llex.c,v 1.9 2016/09/08 20:57:20 salazar Exp $	*/
+/*	$NetBSD: llex.c,v 1.9.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: llex.c,v 2.96 2016/05/02 14:02:12 roberto Exp 
--- a/external/mit/lua/dist/src/llex.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/llex.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: llex.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: llex.h,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: llex.h,v 1.79 2016/05/02 14:02:12 roberto Exp 
--- a/external/mit/lua/dist/src/llimits.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/llimits.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: llimits.h,v 1.7 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: llimits.h,v 1.7.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: llimits.h,v 1.141 2015/11/19 19:16:22 roberto Exp 
--- a/external/mit/lua/dist/src/lmathlib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lmathlib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lmathlib.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lmathlib.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lmathlib.c,v 1.117 2015/10/02 15:39:23 roberto Exp 
+** Id: lmathlib.c,v 1.119 2016/12/22 13:08:50 roberto Exp 
 ** Standard mathematical library
 ** See Copyright Notice in lua.h
 */
@@ -186,10 +186,13 @@
   else {
     lua_Number base = luaL_checknumber(L, 2);
 #if !defined(LUA_USE_C89)
-    if (base == 2.0) res = l_mathop(log2)(x); else
+    if (base == l_mathop(2.0))
+      res = l_mathop(log2)(x); else
 #endif
-    if (base == 10.0) res = l_mathop(log10)(x);
-    else res = l_mathop(log)(x)/l_mathop(log)(base);
+    if (base == l_mathop(10.0))
+      res = l_mathop(log10)(x);
+    else
+      res = l_mathop(log)(x)/l_mathop(log)(base);
   }
   lua_pushnumber(L, res);
   return 1;
@@ -264,7 +267,7 @@
     default: return luaL_error(L, "wrong number of arguments");
   }
   /* random integer in the interval [low, up] */
-  luaL_argcheck(L, low <= up, 1, "interval is empty"); 
+  luaL_argcheck(L, low <= up, 1, "interval is empty");
   luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1,
                    "interval too large");
   r *= (double)(up - low) + 1.0;
@@ -283,9 +286,9 @@
 static int math_type (lua_State *L) {
   if (lua_type(L, 1) == LUA_TNUMBER) {
       if (lua_isinteger(L, 1))
-        lua_pushliteral(L, "integer"); 
+        lua_pushliteral(L, "integer");
       else
-        lua_pushliteral(L, "float"); 
+        lua_pushliteral(L, "float");
   }
   else {
     luaL_checkany(L, 1);
--- a/external/mit/lua/dist/src/lmem.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lmem.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lmem.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lmem.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp 
--- a/external/mit/lua/dist/src/lmem.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lmem.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lmem.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lmem.h,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp 
--- a/external/mit/lua/dist/src/loadlib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/loadlib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: loadlib.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: loadlib.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: loadlib.c,v 1.127 2015/11/23 11:30:45 roberto Exp 
+** Id: loadlib.c,v 1.130 2017/01/12 17:14:26 roberto Exp 
 ** Dynamic library loader for Lua
 ** See Copyright Notice in lua.h
 **
@@ -27,40 +27,9 @@
 
 
 /*
-** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
-** variables that Lua check to set its paths.
-*/
-#if !defined(LUA_PATH_VAR)
-#define LUA_PATH_VAR	"LUA_PATH"
-#endif
-
-#if !defined(LUA_CPATH_VAR)
-#define LUA_CPATH_VAR	"LUA_CPATH"
-#endif
-
-#define LUA_PATHSUFFIX		"_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
-
-#define LUA_PATHVARVERSION		LUA_PATH_VAR LUA_PATHSUFFIX
-#define LUA_CPATHVARVERSION		LUA_CPATH_VAR LUA_PATHSUFFIX
-
-/*
-** LUA_PATH_SEP is the character that separates templates in a path.
-** LUA_PATH_MARK is the string that marks the substitution points in a
-** template.
-** LUA_EXEC_DIR in a Windows path is replaced by the executable's
-** directory.
 ** LUA_IGMARK is a mark to ignore all before it when building the
 ** luaopen_ function name.
 */
-#if !defined (LUA_PATH_SEP)
-#define LUA_PATH_SEP		";"
-#endif
-#if !defined (LUA_PATH_MARK)
-#define LUA_PATH_MARK		"?"
-#endif
-#if !defined (LUA_EXEC_DIR)
-#define LUA_EXEC_DIR		"!"
-#endif
 #if !defined (LUA_IGMARK)
 #define LUA_IGMARK		"-"
 #endif
@@ -96,7 +65,8 @@
 
 #define LIB_FAIL	"open"
 
-#define setprogdir(L)		((void)0)
+
+#define setprogdir(L)           ((void)0)
 
 
 /*
@@ -181,7 +151,6 @@
 
 #include <windows.h>
 
-#undef setprogdir
 
 /*
 ** optional flags for LoadLibraryEx
@@ -191,21 +160,30 @@
 #endif
 
 
+#undef setprogdir
+
+
+/*
+** Replace in the path (on the top of the stack) any occurrence
+** of LUA_EXEC_DIR with the executable's path.
+*/
 static void setprogdir (lua_State *L) {
   char buff[MAX_PATH + 1];
   char *lb;
   DWORD nsize = sizeof(buff)/sizeof(char);
-  DWORD n = GetModuleFileNameA(NULL, buff, nsize);
+  DWORD n = GetModuleFileNameA(NULL, buff, nsize);  /* get exec. name */
   if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
     luaL_error(L, "unable to get ModuleFileName");
   else {
-    *lb = '\0';
+    *lb = '\0';  /* cut name on the last '\\' to get the path */
     luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
     lua_remove(L, -2);  /* remove original string */
   }
 }
 
 
+
+
 static void pusherror (lua_State *L) {
   int error = GetLastError();
   char buffer[128];
@@ -275,6 +253,67 @@
 
 
 /*
+** {==================================================================
+** Set Paths
+** ===================================================================
+*/
+
+/*
+** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
+** variables that Lua check to set its paths.
+*/
+#if !defined(LUA_PATH_VAR)
+#define LUA_PATH_VAR    "LUA_PATH"
+#endif
+
+#if !defined(LUA_CPATH_VAR)
+#define LUA_CPATH_VAR   "LUA_CPATH"
+#endif
+
+
+#define AUXMARK         "\1"	/* auxiliary mark */
+
+
+/*
+** return registry.LUA_NOENV as a boolean
+*/
+static int noenv (lua_State *L) {
+  int b;
+  lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
+  b = lua_toboolean(L, -1);
+  lua_pop(L, 1);  /* remove value */
+  return b;
+}
+
+
+/*
+** Set a path
+*/
+static void setpath (lua_State *L, const char *fieldname,
+                                   const char *envname,
+                                   const char *dft) {
+  const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX);
+  const char *path = getenv(nver);  /* use versioned name */
+  if (path == NULL)  /* no environment variable? */
+    path = getenv(envname);  /* try unversioned name */
+  if (path == NULL || noenv(L))  /* no environment variable? */
+    lua_pushstring(L, dft);  /* use default */
+  else {
+    /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
+    path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
+                              LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
+    luaL_gsub(L, path, AUXMARK, dft);
+    lua_remove(L, -2); /* remove result from 1st 'gsub' */
+  }
+  setprogdir(L);
+  lua_setfield(L, -3, fieldname);  /* package[fieldname] = path value */
+  lua_pop(L, 1);  /* pop versioned variable name */
+}
+
+/* }================================================================== */
+
+
+/*
 ** return registry.CLIBS[path]
 */
 static void *checkclib (lua_State *L, const char *path) {
@@ -522,7 +561,7 @@
 
 static int searcher_preload (lua_State *L) {
   const char *name = luaL_checkstring(L, 1);
-  lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
+  lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
   if (lua_getfield(L, -1, name) == LUA_TNIL)  /* not found? */
     lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
   return 1;
@@ -559,9 +598,9 @@
 
 static int ll_require (lua_State *L) {
   const char *name = luaL_checkstring(L, 1);
-  lua_settop(L, 1);  /* _LOADED table will be at index 2 */
-  lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
-  lua_getfield(L, 2, name);  /* _LOADED[name] */
+  lua_settop(L, 1);  /* LOADED table will be at index 2 */
+  lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
+  lua_getfield(L, 2, name);  /* LOADED[name] */
   if (lua_toboolean(L, -1))  /* is it there? */
     return 1;  /* package is already loaded */
   /* else must load package */
@@ -571,11 +610,11 @@
   lua_insert(L, -2);  /* name is 1st argument (before search data) */
   lua_call(L, 2, 1);  /* run loader to load module */
   if (!lua_isnil(L, -1))  /* non-nil return? */
-    lua_setfield(L, 2, name);  /* _LOADED[name] = returned value */
+    lua_setfield(L, 2, name);  /* LOADED[name] = returned value */
   if (lua_getfield(L, 2, name) == LUA_TNIL) {   /* module set no value? */
     lua_pushboolean(L, 1);  /* use true as result */
     lua_pushvalue(L, -1);  /* extra copy to be returned */
-    lua_setfield(L, 2, name);  /* _LOADED[name] = true */
+    lua_setfield(L, 2, name);  /* LOADED[name] = true */
   }
   return 1;
 }
@@ -668,41 +707,6 @@
 
 
 
-/* auxiliary mark (for internal use) */
-#define AUXMARK		"\1"
-
-
-/*
-** return registry.LUA_NOENV as a boolean
-*/
-static int noenv (lua_State *L) {
-  int b;
-  lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
-  b = lua_toboolean(L, -1);
-  lua_pop(L, 1);  /* remove value */
-  return b;
-}
-
-
-static void setpath (lua_State *L, const char *fieldname, const char *envname1,
-                                   const char *envname2, const char *def) {
-  const char *path = getenv(envname1);
-  if (path == NULL)  /* no environment variable? */
-    path = getenv(envname2);  /* try alternative name */
-  if (path == NULL || noenv(L))  /* no environment variable? */
-    lua_pushstring(L, def);  /* use default */
-  else {
-    /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
-    path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
-                              LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
-    luaL_gsub(L, path, AUXMARK, def);
-    lua_remove(L, -2);
-  }
-  setprogdir(L);
-  lua_setfield(L, -2, fieldname);
-}
-
-
 static const luaL_Reg pk_funcs[] = {
   {"loadlib", ll_loadlib},
   {"searchpath", ll_searchpath},
@@ -766,19 +770,18 @@
   createclibstable(L);
   luaL_newlib(L, pk_funcs);  /* create 'package' table */
   createsearcherstable(L);
-  /* set field 'path' */
-  setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
-  /* set field 'cpath' */
-  setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
+  /* set paths */
+  setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT);
+  setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
   /* store config information */
   lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
                      LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
   lua_setfield(L, -2, "config");
   /* set field 'loaded' */
-  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
+  luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
   lua_setfield(L, -2, "loaded");
   /* set field 'preload' */
-  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
+  luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
   lua_setfield(L, -2, "preload");
   lua_pushglobaltable(L);
   lua_pushvalue(L, -2);  /* set 'package' as upvalue for next lib */
--- a/external/mit/lua/dist/src/lobject.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lobject.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lobject.c,v 1.9 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lobject.c,v 1.9.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lobject.c,v 2.111 2016/05/20 14:07:48 roberto Exp 
+** Id: lobject.c,v 2.113 2016/12/22 13:08:50 roberto Exp 
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -297,7 +297,7 @@
   endptr = l_str2dloc(s, result, mode);  /* try to convert */
   if (endptr == NULL) {  /* failed? may be a different locale */
     char buff[L_MAXLENNUM + 1];
-    char *pdot = strchr(s, '.');
+    const char *pdot = strchr(s, '.');
     if (strlen(s) > L_MAXLENNUM || pdot == NULL)
       return NULL;  /* string too long or no dot; fail */
     strcpy(buff, s);  /* copy string to buffer */
@@ -423,7 +423,7 @@
 
 
 /*
-** this function handles only '%d', '%c', '%f', '%p', and '%s' 
+** this function handles only '%d', '%c', '%f', '%p', and '%s'
    conventional formats, plus Lua-specific '%I' and '%U'
 */
 const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
--- a/external/mit/lua/dist/src/lobject.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lobject.h	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lobject.h,v 1.7 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lobject.h,v 1.7.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lobject.h,v 2.116 2015/11/03 18:33:10 roberto Exp 
+** Id: lobject.h,v 2.117 2016/08/01 19:51:24 roberto Exp 
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -421,7 +421,7 @@
 typedef struct Proto {
   CommonHeader;
   lu_byte numparams;  /* number of fixed parameters */
-  lu_byte is_vararg;  /* 2: declared vararg; 1: uses vararg */
+  lu_byte is_vararg;
   lu_byte maxstacksize;  /* number of registers needed by this function */
   int sizeupvalues;  /* size of 'upvalues' */
   int sizek;  /* size of 'k' */
--- a/external/mit/lua/dist/src/lopcodes.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lopcodes.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lopcodes.c,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lopcodes.c,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lopcodes.c,v 1.55 2015/01/05 13:48:33 roberto Exp 
--- a/external/mit/lua/dist/src/lopcodes.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lopcodes.h	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lopcodes.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lopcodes.h,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lopcodes.h,v 1.148 2014/10/25 11:50:46 roberto Exp 
+** Id: lopcodes.h,v 1.149 2016/07/19 17:12:21 roberto Exp 
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -141,7 +141,9 @@
 /* gets the index of the constant */
 #define INDEXK(r)	((int)(r) & ~BITRK)
 
+#if !defined(MAXINDEXRK)  /* (for debugging only) */
 #define MAXINDEXRK	(BITRK - 1)
+#endif
 
 /* code a constant index as a RK value */
 #define RKASK(x)	((x) | BITRK)
--- a/external/mit/lua/dist/src/loslib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/loslib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: loslib.c,v 1.8 2016/09/08 21:19:44 salazar Exp $	*/
+/*	$NetBSD: loslib.c,v 1.8.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: loslib.c,v 1.64 2016/04/18 13:06:55 roberto Exp 
+** Id: loslib.c,v 1.65 2016/07/18 17:58:58 roberto Exp 
 ** Standard Operating System library
 ** See Copyright Notice in lua.h
 */
@@ -32,16 +32,16 @@
 */
 #if !defined(LUA_STRFTIMEOPTIONS)	/* { */
 
-/* options for ANSI C 89 */
+/* options for ANSI C 89 (only 1-char options) */
 #define L_STRFTIMEC89		"aAbBcdHIjmMpSUwWxXyYZ%"
 
 /* options for ISO C 99 and POSIX */
 #define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
-	"||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy"
+    "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy"  /* two-char options */
 
 /* options for Windows */
 #define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
-	"||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"
+    "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"  /* two-char options */
 
 #if defined(LUA_USE_WINDOWS)
 #define LUA_STRFTIMEOPTIONS	L_STRFTIMEWIN
@@ -259,13 +259,13 @@
 }
 
 
-static const char *checkoption (lua_State *L, const char *conv, char *buff) {
-  const char *option;
-  int oplen = 1;
-  int convlen = (int)strlen(conv);
-  for (option = LUA_STRFTIMEOPTIONS; *option != '\0' && oplen <= convlen; option += oplen) {
+static const char *checkoption (lua_State *L, const char *conv,
+                                ptrdiff_t convlen, char *buff) {
+  const char *option = LUA_STRFTIMEOPTIONS;
+  int oplen = 1;  /* length of options being checked */
+  for (; *option != '\0' && oplen <= convlen; option += oplen) {
     if (*option == '|')  /* next block? */
-      oplen++;  /* next length */
+      oplen++;  /* will check options with next length (+1) */
     else if (memcmp(conv, option, oplen) == 0) {  /* match? */
       memcpy(buff, conv, oplen);  /* copy valid option to buffer */
       buff[oplen] = '\0';
@@ -283,8 +283,10 @@
 
 
 static int os_date (lua_State *L) {
-  const char *s = luaL_optstring(L, 1, "%c");
+  size_t slen;
+  const char *s = luaL_optlstring(L, 1, "%c", &slen);
   time_t t = luaL_opt(L, l_checktime, 2, time(NULL));
+  const char *se = s + slen;  /* 's' end */
   struct tm tmr, *stm;
   if (*s == '!') {  /* UTC? */
     stm = l_gmtime(&t, &tmr);
@@ -303,13 +305,14 @@
     luaL_Buffer b;
     cc[0] = '%';
     luaL_buffinit(L, &b);
-    while (*s) {
+    while (s < se) {
       if (*s != '%')  /* not a conversion specifier? */
         luaL_addchar(&b, *s++);
       else {
         size_t reslen;
         char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
-        s = checkoption(L, s + 1, cc + 1);  /* copy specifier to 'cc' */
+        s++;  /* skip '%' */
+        s = checkoption(L, s, se - s, cc + 1);  /* copy specifier to 'cc' */
         reslen = strftime(buff, SIZETIMEFMT, cc, stm);
         luaL_addsize(&b, reslen);
       }
--- a/external/mit/lua/dist/src/lparser.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lparser.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lparser.c,v 1.7 2016/09/08 02:53:39 salazar Exp $	*/
+/*	$NetBSD: lparser.c,v 1.7.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lparser.c,v 2.153 2016/05/13 19:10:16 roberto Exp 
+** Id: lparser.c,v 2.155 2016/08/01 19:51:24 roberto Exp 
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -770,7 +770,7 @@
         }
         case TK_DOTS: {  /* param -> '...' */
           luaX_next(ls);
-          f->is_vararg = 2;  /* declared vararg */
+          f->is_vararg = 1;  /* declared vararg */
           break;
         }
         default: luaX_syntaxerror(ls, "<name> or '...' expected");
@@ -968,7 +968,6 @@
       FuncState *fs = ls->fs;
       check_condition(ls, fs->f->is_vararg,
                       "cannot use '...' outside a vararg function");
-      fs->f->is_vararg = 1;  /* function actually uses vararg */
       init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
       break;
     }
@@ -1628,7 +1627,7 @@
   BlockCnt bl;
   expdesc v;
   open_func(ls, fs, &bl);
-  fs->f->is_vararg = 2;  /* main function is always declared vararg */
+  fs->f->is_vararg = 1;  /* main function is always declared vararg */
   init_exp(&v, VLOCAL, 0);  /* create and... */
   newupvalue(fs, ls->envn, &v);  /* ...set environment upvalue */
   luaX_next(ls);  /* read first token */
--- a/external/mit/lua/dist/src/lparser.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lparser.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lparser.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lparser.h,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lparser.h,v 1.76 2015/12/30 18:16:13 roberto Exp 
--- a/external/mit/lua/dist/src/lprefix.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lprefix.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lprefix.h,v 1.4 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lprefix.h,v 1.4.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp 
--- a/external/mit/lua/dist/src/lstate.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lstate.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lstate.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lstate.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lstate.c,v 2.133 2015/11/13 12:16:51 roberto Exp 
--- a/external/mit/lua/dist/src/lstate.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lstate.h	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lstate.h,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lstate.h,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lstate.h,v 2.130 2015/12/16 16:39:38 roberto Exp 
+** Id: lstate.h,v 2.133 2016/12/22 13:08:50 roberto Exp 
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -25,7 +25,7 @@
 **
 ** 'allgc': all objects not marked for finalization;
 ** 'finobj': all objects marked for finalization;
-** 'tobefnz': all objects ready to be finalized; 
+** 'tobefnz': all objects ready to be finalized;
 ** 'fixedgc': all objects that are not to be collected (currently
 ** only small strings, such as reserved words).
 
@@ -36,7 +36,7 @@
 
 
 /*
-** Atomic type (relative to signals) to better ensure that 'lua_sethook' 
+** Atomic type (relative to signals) to better ensure that 'lua_sethook'
 ** is thread safe
 */
 #if !defined(l_signalT)
@@ -68,7 +68,7 @@
 ** Information about a call.
 ** When a thread yields, 'func' is adjusted to pretend that the
 ** top function has only the yielded values in its stack; in that
-** case, the actual 'func' value is saved in field 'extra'. 
+** case, the actual 'func' value is saved in field 'extra'.
 ** When a function calls another with a continuation, 'extra' keeps
 ** the function index so that, in case of errors, the continuation
 ** function can be called with the correct top.
@@ -90,7 +90,7 @@
   } u;
   ptrdiff_t extra;
   short nresults;  /* expected number of results from this function */
-  lu_byte callstatus;
+  unsigned short callstatus;
 } CallInfo;
 
 
@@ -106,6 +106,7 @@
 #define CIST_TAIL	(1<<5)	/* call was tail called */
 #define CIST_HOOKYIELD	(1<<6)	/* last hook called yielded */
 #define CIST_LEQ	(1<<7)  /* using __lt for __le */
+#define CIST_FIN	(1<<8)  /* call is running a finalizer */
 
 #define isLua(ci)	((ci)->callstatus & CIST_LUA)
 
--- a/external/mit/lua/dist/src/lstring.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lstring.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lstring.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lstring.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lstring.c,v 2.56 2015/11/23 11:32:51 roberto Exp 
--- a/external/mit/lua/dist/src/lstring.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lstring.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lstring.h,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lstring.h,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: lstring.h,v 1.61 2015/11/03 15:36:01 roberto Exp 
--- a/external/mit/lua/dist/src/lstrlib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lstrlib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lstrlib.c,v 1.15 2016/09/08 20:57:20 salazar Exp $	*/
+/*	$NetBSD: lstrlib.c,v 1.15.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: lstrlib.c,v 1.251 2016/05/20 14:13:21 roberto Exp 
+** Id: lstrlib.c,v 1.254 2016/12/22 13:08:50 roberto Exp 
 ** Standard library for string operations and pattern-matching
 ** See Copyright Notice in lua.h
 */
@@ -843,11 +843,12 @@
 
 
 static int num2straux (char *buff, int sz, lua_Number x) {
-  if (x != x || x == HUGE_VAL || x == -HUGE_VAL)  /* inf or NaN? */
-    return l_sprintf(buff, sz, LUA_NUMBER_FMT, x);  /* equal to '%g' */
+  /* if 'inf' or 'NaN', format it like '%g' */
+  if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL)
+    return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x);
   else if (x == 0) {  /* can be -0... */
     /* create "0" or "-0" followed by exponent */
-    return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", x);
+    return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x);
   }
   else {
     int e;
@@ -938,7 +939,7 @@
 static void checkdp (char *buff, int nb) {
   if (memchr(buff, '.', nb) == NULL) {  /* no dot? */
     char point = lua_getlocaledecpoint();  /* try locale point */
-    char *ppoint = memchr(buff, point, nb);
+    char *ppoint = (char *)memchr(buff, point, nb);
     if (ppoint) *ppoint = '.';  /* change it to a dot */
   }
 }
@@ -968,7 +969,7 @@
         const char *format = (n == LUA_MININTEGER)  /* corner case? */
                            ? "0x%" LUA_INTEGER_FRMLEN "x"  /* use hexa */
                            : LUA_INTEGER_FMT;  /* else use default format */
-        nb = l_sprintf(buff, MAX_ITEM, format, n);
+        nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n);
       }
       luaL_addsize(b, nb);
       break;
@@ -1049,7 +1050,7 @@
         case 'o': case 'u': case 'x': case 'X': {
           lua_Integer n = luaL_checkinteger(L, arg);
           addlenmod(form, LUA_INTEGER_FRMLEN);
-          nb = l_sprintf(buff, MAX_ITEM, form, n);
+          nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n);
           break;
         }
 #ifndef _KERNEL
@@ -1060,8 +1061,9 @@
           break;
         case 'e': case 'E': case 'f':
         case 'g': case 'G': {
+          lua_Number n = luaL_checknumber(L, arg);
           addlenmod(form, LUA_NUMBER_FRMLEN);
-          nb = l_sprintf(buff, MAX_ITEM, form, luaL_checknumber(L, arg));
+          nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n);
           break;
         }
 #endif /* _KERNEL */
@@ -1281,7 +1283,7 @@
 ** 'psize' is filled with option's size, 'notoalign' with its
 ** alignment requirements.
 ** Local variable 'size' gets the size to be aligned. (Kpadal option
-** always gets its full alignment, other options are limited by 
+** always gets its full alignment, other options are limited by
 ** the maximum alignment ('maxalign'). Kchar option needs no alignment
 ** despite its size.
 */
--- a/external/mit/lua/dist/src/ltable.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ltable.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: ltable.c,v 1.7 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ltable.c,v 1.7.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: ltable.c,v 2.117 2015/11/19 19:16:22 roberto Exp 
+** Id: ltable.c,v 2.118 2016/11/07 12:38:35 roberto Exp 
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -78,8 +78,6 @@
 
 #define dummynode		(&dummynode_)
 
-#define isdummy(n)		((n) == dummynode)
-
 static const Node dummynode_ = {
   {NILCONSTANT},  /* value */
   {{NILCONSTANT, 0}}  /* key */
@@ -316,14 +314,14 @@
 
 
 static void setnodevector (lua_State *L, Table *t, unsigned int size) {
-  int lsize;
   if (size == 0) {  /* no elements to hash part? */
     t->node = cast(Node *, dummynode);  /* use common 'dummynode' */
-    lsize = 0;
+    t->lsizenode = 0;
+    t->lastfree = NULL;  /* signal that it is using dummy node */
   }
   else {
     int i;
-    lsize = luaO_ceillog2(size);
+    int lsize = luaO_ceillog2(size);
     if (lsize > MAXHBITS)
       luaG_runerror(L, "table overflow");
     size = twoto(lsize);
@@ -334,9 +332,9 @@
       setnilvalue(wgkey(n));
       setnilvalue(gval(n));
     }
+    t->lsizenode = cast_byte(lsize);
+    t->lastfree = gnode(t, size);  /* all positions are free */
   }
-  t->lsizenode = cast_byte(lsize);
-  t->lastfree = gnode(t, size);  /* all positions are free */
 }
 
 
@@ -345,7 +343,7 @@
   unsigned int i;
   int j;
   unsigned int oldasize = t->sizearray;
-  int oldhsize = t->lsizenode;
+  int oldhsize = allocsizenode(t);
   Node *nold = t->node;  /* save old hash ... */
   if (nasize > oldasize)  /* array part must grow? */
     setarrayvector(L, t, nasize);
@@ -362,7 +360,7 @@
     luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
   }
   /* re-insert elements from hash part */
-  for (j = twoto(oldhsize) - 1; j >= 0; j--) {
+  for (j = oldhsize - 1; j >= 0; j--) {
     Node *old = nold + j;
     if (!ttisnil(gval(old))) {
       /* doesn't need barrier/invalidate cache, as entry was
@@ -370,13 +368,13 @@
       setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
     }
   }
-  if (!isdummy(nold))
-    luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old hash */
+  if (oldhsize > 0)  /* not the dummy node? */
+    luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */
 }
 
 
 void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
-  int nsize = isdummy(t->node) ? 0 : sizenode(t);
+  int nsize = allocsizenode(t);
   luaH_resize(L, t, nasize, nsize);
 }
 
@@ -422,7 +420,7 @@
 
 
 void luaH_free (lua_State *L, Table *t) {
-  if (!isdummy(t->node))
+  if (!isdummy(t))
     luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
   luaM_freearray(L, t->array, t->sizearray);
   luaM_free(L, t);
@@ -430,10 +428,12 @@
 
 
 static Node *getfreepos (Table *t) {
-  while (t->lastfree > t->node) {
-    t->lastfree--;
-    if (ttisnil(gkey(t->lastfree)))
-      return t->lastfree;
+  if (!isdummy(t)) {
+    while (t->lastfree > t->node) {
+      t->lastfree--;
+      if (ttisnil(gkey(t->lastfree)))
+        return t->lastfree;
+    }
   }
   return NULL;  /* could not find a free place */
 }
@@ -456,7 +456,7 @@
 #ifndef _KERNEL
   else if (ttisfloat(key)) {
     lua_Integer k;
-    if (luaV_tointeger(key, &k, 0)) {  /* index is int? */
+    if (luaV_tointeger(key, &k, 0)) {  /* does index fit in an integer? */
       setivalue(&aux, k);
       key = &aux;  /* insert it as an integer */
     }
@@ -465,7 +465,7 @@
   }
 #endif /* _KERNEL */
   mp = mainposition(t, key);
-  if (!ttisnil(gval(mp)) || isdummy(mp)) {  /* main position is taken? */
+  if (!ttisnil(gval(mp)) || isdummy(t)) {  /* main position is taken? */
     Node *othern;
     Node *f = getfreepos(t);  /* get a free place */
     if (f == NULL) {  /* cannot find a free place? */
@@ -473,7 +473,7 @@
       /* whatever called 'newkey' takes care of TM cache */
       return luaH_set(L, t, key);  /* insert key into grown table */
     }
-    lua_assert(!isdummy(f));
+    lua_assert(!isdummy(t));
     othern = mainposition(t, gkey(mp));
     if (othern != mp) {  /* is colliding node out of its main position? */
       /* yes; move colliding node into free position */
@@ -665,7 +665,7 @@
     return i;
   }
   /* else must find a boundary in hash part */
-  else if (isdummy(t->node))  /* hash part is empty? */
+  else if (isdummy(t))  /* hash part is empty? */
     return j;  /* that is easy... */
   else return unbound_search(t, j);
 }
@@ -678,6 +678,6 @@
   return mainposition(t, key);
 }
 
-int luaH_isdummy (Node *n) { return isdummy(n); }
+int luaH_isdummy (const Table *t) { return isdummy(t); }
 
 #endif
--- a/external/mit/lua/dist/src/ltable.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ltable.h	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: ltable.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ltable.h,v 1.5.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
-** Id: ltable.h,v 2.21 2015/11/03 15:47:30 roberto Exp 
+** Id: ltable.h,v 2.23 2016/12/22 13:08:50 roberto Exp 
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -17,7 +17,7 @@
 #define gnext(n)	((n)->i_key.nk.next)
 
 
-/* 'const' to avoid wrong writings that can mess up field 'next' */ 
+/* 'const' to avoid wrong writings that can mess up field 'next' */
 #define gkey(n)		cast(const TValue*, (&(n)->i_key.tvk))
 
 /*
@@ -29,6 +29,14 @@
 #define invalidateTMcache(t)	((t)->flags = 0)
 
 
+/* true when 't' is using 'dummynode' as its hash part */
+#define isdummy(t)		((t)->lastfree == NULL)
+
+
+/* allocated size for hash nodes */
+#define allocsizenode(t)	(isdummy(t) ? 0 : sizenode(t))
+
+
 /* returns the key, given the value of a table entry */
 #define keyfromval(v) \
   (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
@@ -53,7 +61,7 @@
 
 #if defined(LUA_DEBUG)
 LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
-LUAI_FUNC int luaH_isdummy (Node *n);
+LUAI_FUNC int luaH_isdummy (const Table *t);
 #endif
 
 
--- a/external/mit/lua/dist/src/ltablib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ltablib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: ltablib.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ltablib.c,v 1.6.4.1 2017/05/02 03:19:15 pgoyette Exp $	*/
 
 /*
 ** Id: ltablib.c,v 1.93 2016/02/25 19:41:54 roberto Exp 
--- a/external/mit/lua/dist/src/ltm.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ltm.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: ltm.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ltm.c,v 1.6.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
-** Id: ltm.c,v 2.37 2016/02/26 19:20:15 roberto Exp 
+** Id: ltm.c,v 2.38 2016/12/22 13:08:50 roberto Exp 
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -19,7 +19,7 @@
 #include "lua.h"
 
 #include "ldebug.h"
-#include "ldo.h" 
+#include "ldo.h"
 #include "lobject.h"
 #include "lstate.h"
 #include "lstring.h"
--- a/external/mit/lua/dist/src/ltm.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/ltm.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: ltm.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: ltm.h,v 1.5.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
 ** Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp 
--- a/external/mit/lua/dist/src/lua.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lua.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lua.c,v 1.6 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lua.c,v 1.6.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
-** Id: lua.c,v 1.226 2015/08/14 19:11:20 roberto Exp 
+** Id: lua.c,v 1.230 2017/01/12 17:14:26 roberto Exp 
 ** Lua stand-alone interpreter
 ** See Copyright Notice in lua.h
 */
@@ -22,6 +22,7 @@
 #include "lualib.h"
 
 
+
 #if !defined(LUA_PROMPT)
 #define LUA_PROMPT		"> "
 #define LUA_PROMPT2		">> "
@@ -39,8 +40,7 @@
 #define LUA_INIT_VAR		"LUA_INIT"
 #endif
 
-#define LUA_INITVARVERSION  \
-	LUA_INIT_VAR "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
+#define LUA_INITVARVERSION	LUA_INIT_VAR LUA_VERSUFFIX
 
 
 /*
@@ -57,6 +57,8 @@
 #elif defined(LUA_USE_WINDOWS)	/* }{ */
 
 #include <io.h>
+#include <windows.h>
+
 #define lua_stdin_is_tty()	_isatty(_fileno(stdin))
 
 #else				/* }{ */
@@ -459,7 +461,7 @@
 /*
 ** Traverses all arguments from 'argv', returning a mask with those
 ** needed before running any Lua code (or an error code if it finds
-** any invalid argument). 'first' returns the first not-handled argument 
+** any invalid argument). 'first' returns the first not-handled argument
 ** (either the script name or a bad argument in case of error).
 */
 static int collectargs (char **argv, int *first) {
@@ -483,7 +485,7 @@
         args |= has_E;
         break;
       case 'i':
-        args |= has_i;  /* (-i implies -v) *//* FALLTHROUGH */ 
+        args |= has_i;  /* (-i implies -v) *//* FALLTHROUGH */
       case 'v':
         if (argv[i][2] != '\0')  /* extra characters after 1st? */
           return has_error;  /* invalid option */
@@ -531,6 +533,7 @@
 }
 
 
+
 static int handle_luainit (lua_State *L) {
   const char *name = "=" LUA_INITVARVERSION;
   const char *init = getenv(name + 1);
--- a/external/mit/lua/dist/src/lua.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lua.h	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lua.h,v 1.7 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lua.h,v 1.7.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
-** Id: lua.h,v 1.331 2016/05/30 15:53:28 roberto Exp 
+** Id: lua.h,v 1.332 2016/12/22 15:51:20 roberto Exp 
 ** Lua - A Scripting Language
 ** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
 ** See Copyright Notice at the end of this file
@@ -24,19 +24,19 @@
 #define LUA_VERSION_MINOR	"3"
 #define LUA_VERSION_NUM		503
 #ifndef _KERNEL
-#define LUA_VERSION_RELEASE	"3"
+#define LUA_VERSION_RELEASE	"4"
 #else /* _KERNEL */
-#define LUA_VERSION_RELEASE	"3 (kernel)"
+#define LUA_VERSION_RELEASE	"4 (kernel)"
 #endif /* _KERNEL */
 
 #define LUA_VERSION	"Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
 #define LUA_RELEASE	LUA_VERSION "." LUA_VERSION_RELEASE
 #ifndef _KERNEL
-#define LUA_COPYRIGHT	LUA_RELEASE "  Copyright (C) 1994-2016 Lua.org, PUC-Rio"
+#define LUA_COPYRIGHT	LUA_RELEASE "  Copyright (C) 1994-2017 Lua.org, PUC-Rio"
 #else /* _KERNEL */
 #define LUA_COPYRIGHT	LUA_RELEASE \
 	"  Copyright (c) 2016-2016, Lourival Vieira Neto <lneto@NetBSD.org>." \
-	"  Copyright (C) 1994-2016 Lua.org, PUC-Rio"
+	"  Copyright (C) 1994-2017 Lua.org, PUC-Rio"
 #endif /* _KERNEL */
 #define LUA_AUTHORS	"R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
 
@@ -494,9 +494,9 @@
 
 /******************************************************************************
 #ifdef _KERNEL
-* Copyright (c) 2016-2016, Lourival Vieira Neto <lneto@NetBSD.org>.
+* Copyright (c) 2016-2017, Lourival Vieira Neto <lneto@NetBSD.org>.
 #endif
-* Copyright (C) 1994-2016 Lua.org, PUC-Rio.
+* Copyright (C) 1994-2017 Lua.org, PUC-Rio.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
--- a/external/mit/lua/dist/src/luac.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/luac.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: luac.c,v 1.7 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: luac.c,v 1.7.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
 ** Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp 
--- a/external/mit/lua/dist/src/luaconf.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/luaconf.h	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: luaconf.h,v 1.19 2016/09/10 09:31:24 mbalmer Exp $	*/
+/*	$NetBSD: luaconf.h,v 1.19.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
-** Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp 
+** Id: luaconf.h,v 1.259 2016/12/22 13:08:50 roberto Exp 
 ** Configuration file for Lua
 ** See Copyright Notice in lua.h
 */
@@ -166,6 +166,18 @@
 */
 
 /*
+** LUA_PATH_SEP is the character that separates templates in a path.
+** LUA_PATH_MARK is the string that marks the substitution points in a
+** template.
+** LUA_EXEC_DIR in a Windows path is replaced by the executable's
+** directory.
+*/
+#define LUA_PATH_SEP            ";"
+#define LUA_PATH_MARK           "?"
+#define LUA_EXEC_DIR            "!"
+
+
+/*
 @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
 ** Lua libraries.
 @@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
@@ -412,7 +424,7 @@
 #ifndef _KERNEL
 /*
 @@ LUA_NUMBER is the floating-point type used by Lua.
-@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
+@@ LUAI_UACNUMBER is the result of a 'default argument promotion'
 @@ over a floating number.
 @@ l_mathlim(x) corrects limit name 'x' to the proper float type
 ** by prefixing it with one of FLT/DBL/LDBL.
@@ -429,7 +441,8 @@
 
 #define l_floor(x)		(l_mathop(floor)(x))
 
-#define lua_number2str(s,sz,n)	l_sprintf((s), sz, LUA_NUMBER_FMT, (n))
+#define lua_number2str(s,sz,n)  \
+	l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n))
 
 /*
 @@ lua_numbertointeger converts a float number to an integer, or
@@ -507,7 +520,7 @@
 **
 @@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
 **
-@@ LUAI_UACINT is the result of an 'usual argument conversion'
+@@ LUAI_UACINT is the result of a 'default argument promotion'
 @@ over a lUA_INTEGER.
 @@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
 @@ LUA_INTEGER_FMT is the format for writing integers.
@@ -520,10 +533,12 @@
 /* The following definitions are good for most cases here */
 
 #define LUA_INTEGER_FMT		"%" LUA_INTEGER_FRMLEN "d"
-#define lua_integer2str(s,sz,n)	l_sprintf((s), sz, LUA_INTEGER_FMT, (n))
 
 #define LUAI_UACINT		LUA_INTEGER
 
+#define lua_integer2str(s,sz,n)  \
+	l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n))
+
 /*
 ** use LUAI_UACINT here to avoid problems with promotions (which
 ** can turn a comparison between unsigneds into a signed comparison)
@@ -615,13 +630,14 @@
 
 
 /*
-@@ lua_number2strx converts a float to an hexadecimal numeric string. 
+@@ lua_number2strx converts a float to an hexadecimal numeric string.
 ** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
 ** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
 ** provide its own implementation.
 */
 #if !defined(LUA_USE_C89)
-#define lua_number2strx(L,b,sz,f,n)	((void)L, l_sprintf(b,sz,f,n))
+#define lua_number2strx(L,b,sz,f,n)  \
+	((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n)))
 #endif
 
 
@@ -737,11 +753,11 @@
 /*
 @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
 ** CHANGE it if it uses too much C-stack space. (For long double,
-** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a
+** 'string.format("%.99f", -1e4932)' needs 5034 bytes, so a
 ** smaller buffer would force a memory allocation for each call to
 ** 'string.format'.)
 */
-#if defined(LUA_FLOAT_LONGDOUBLE)
+#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
 #define LUAL_BUFFERSIZE		8192
 #else
 #define LUAL_BUFFERSIZE   ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
--- a/external/mit/lua/dist/src/lualib.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lualib.h	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lualib.h,v 1.4 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lualib.h,v 1.4.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
-** Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp 
+** Id: lualib.h,v 1.45 2017/01/12 17:14:26 roberto Exp 
 ** Lua standard libraries
 ** See Copyright Notice in lua.h
 */
@@ -13,6 +13,9 @@
 #include "lua.h"
 
 
+/* version suffix for environment variable names */
+#define LUA_VERSUFFIX          "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
+
 
 LUAMOD_API int (luaopen_base) (lua_State *L);
 
--- a/external/mit/lua/dist/src/lundump.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lundump.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lundump.c,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lundump.c,v 1.5.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
 ** Id: lundump.c,v 2.44 2015/11/02 16:09:30 roberto Exp 
--- a/external/mit/lua/dist/src/lundump.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lundump.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lundump.h,v 1.4 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lundump.h,v 1.4.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
 ** Id: lundump.h,v 1.45 2015/09/08 15:41:05 roberto Exp 
--- a/external/mit/lua/dist/src/lutf8lib.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lutf8lib.c	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lutf8lib.c,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lutf8lib.c,v 1.5.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
-** Id: lutf8lib.c,v 1.15 2015/03/28 19:16:55 roberto Exp 
+** Id: lutf8lib.c,v 1.16 2016/12/22 13:08:50 roberto Exp 
 ** Standard library for UTF-8 manipulation
 ** See Copyright Notice in lua.h
 */
@@ -198,7 +198,7 @@
     lua_pushinteger(L, posi + 1);
   else  /* no such character */
     lua_pushnil(L);
-  return 1;  
+  return 1;
 }
 
 
--- a/external/mit/lua/dist/src/lvm.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lvm.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lvm.c,v 1.11 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lvm.c,v 1.11.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
 ** Id: lvm.c,v 2.268 2016/02/05 19:59:14 roberto Exp 
--- a/external/mit/lua/dist/src/lvm.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lvm.h	Tue May 02 03:19:14 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: lvm.h,v 1.7 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lvm.h,v 1.7.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
-** Id: lvm.h,v 2.40 2016/01/05 16:07:21 roberto Exp 
+** Id: lvm.h,v 2.41 2016/12/22 13:08:50 roberto Exp 
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -96,7 +96,7 @@
 #define luaV_settable(L,t,k,v) { const TValue *slot; \
   if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \
     luaV_finishset(L,t,k,v,slot); }
-  
+
 
 
 LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
--- a/external/mit/lua/dist/src/lzio.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lzio.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lzio.c,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lzio.c,v 1.5.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
 ** Id: lzio.c,v 1.37 2015/09/08 15:41:05 roberto Exp 
--- a/external/mit/lua/dist/src/lzio.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/external/mit/lua/dist/src/lzio.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: lzio.h,v 1.5 2016/09/08 02:21:31 salazar Exp $	*/
+/*	$NetBSD: lzio.h,v 1.5.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
 ** Id: lzio.h,v 1.31 2015/09/08 15:41:05 roberto Exp 
--- a/lib/libc/gen/glob.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/lib/libc/gen/glob.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: glob.c,v 1.36 2016/09/04 18:27:08 joerg Exp $	*/
+/*	$NetBSD: glob.c,v 1.36.4.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)glob.c	8.3 (Berkeley) 10/13/93";
 #else
-__RCSID("$NetBSD: glob.c,v 1.36 2016/09/04 18:27:08 joerg Exp $");
+__RCSID("$NetBSD: glob.c,v 1.36.4.1 2017/05/02 03:19:16 pgoyette Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -936,39 +936,45 @@
 
 
 /*
- * pattern matching function for filenames.  Each occurrence of the *
- * pattern causes a recursion level.
+ * pattern matching function for filenames.
  */
 static int
 match(const Char *name, const Char *pat, const Char *patend)
 {
 	int ok, negate_range;
 	Char c, k;
+	const Char *patNext, *nameNext, *nameStart, *nameEnd;
 
 	_DIAGASSERT(name != NULL);
 	_DIAGASSERT(pat != NULL);
 	_DIAGASSERT(patend != NULL);
+	patNext = pat;
+	nameStart = nameNext = name;
+	nameEnd = NULL;
 
-	while (pat < patend) {
-		c = *pat++;
+	while (pat < patend || *name) {
+		c = *pat;
+		if (*name == EOS)
+			nameEnd = name;
 		switch (c & M_MASK) {
 		case M_ALL:
-			while (pat < patend && (*pat & M_MASK) == M_ALL)
-				pat++;	/* eat consecutive '*' */
-			if (pat == patend)
-				return 1;
-			for (; !match(name, pat, patend); name++)
-				if (*name == EOS)
-					return 0;
-			return 1;
+			while (pat[1] == '*') pat++;
+			patNext = pat;
+			nameNext = name + 1;
+			pat++;
+			continue;
 		case M_ONE:
-			if (*name++ == EOS)
-				return 0;
-			break;
+			if (*name == EOS)
+				break;
+			pat++;
+			name++;
+			continue;
 		case M_SET:
 			ok = 0;
-			if ((k = *name++) == EOS)
-				return 0;
+			if ((k = *name) == EOS)
+				break;
+			pat++;
+			name++;
 			if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
 				++pat;
 			while (((c = *pat++) & M_MASK) != M_END)
@@ -979,15 +985,24 @@
 				} else if (c == k)
 					ok = 1;
 			if (ok == negate_range)
-				return 0;
-			break;
+				break;
+			continue;
 		default:
-			if (*name++ != c)
-				return 0;
-			break;
+			if (*name != c)
+				break;
+			pat++;
+			name++;
+			continue;
 		}
+		if (nameNext != nameStart
+		    && (nameEnd == NULL || nameNext <= nameEnd)) {
+			pat = patNext;
+			name = nameNext;
+			continue;
+		}
+		return 0;
 	}
-	return *name == EOS;
+	return 1;
 }
 
 /* Free allocated data belonging to a glob_t structure. */
--- a/lib/libterminfo/termcap.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/lib/libterminfo/termcap.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: termcap.c,v 1.20 2017/01/11 20:53:52 roy Exp $ */
+/* $NetBSD: termcap.c,v 1.20.4.1 2017/05/02 03:19:16 pgoyette Exp $ */
 
 /*
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: termcap.c,v 1.20 2017/01/11 20:53:52 roy Exp $");
+__RCSID("$NetBSD: termcap.c,v 1.20.4.1 2017/05/02 03:19:16 pgoyette Exp $");
 
 #include <assert.h>
 #include <ctype.h>
@@ -200,7 +200,7 @@
 	uint32_t idx;
 
 	idx = _t_numhash((const unsigned char *)key, strlen(key));
-	if (idx < __arraycount(_ti_cap_numids) && 
+	if (idx < __arraycount(_ti_cap_numids) &&
 	    strcmp(key, _ti_cap_numids[idx].id) == 0)
 		return _ti_numid(_ti_cap_numids[idx].ti);
 	return key;
@@ -254,7 +254,7 @@
 		case '2':
 		case '3':
 			v = 0;
-			while (isdigit((unsigned char) **src))	
+			while (isdigit((unsigned char) **src))
 				v = 8 * v + ((unsigned char) *(*src)++ - '0');
 			(*src)--;
 			break;
--- a/lib/libterminfo/tputs.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/lib/libterminfo/tputs.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tputs.c,v 1.3 2013/06/07 13:16:18 roy Exp $ */
+/* $NetBSD: tputs.c,v 1.3.18.1 2017/05/02 03:19:16 pgoyette Exp $ */
 
 /*
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: tputs.c,v 1.3 2013/06/07 13:16:18 roy Exp $");
+__RCSID("$NetBSD: tputs.c,v 1.3.18.1 2017/05/02 03:19:16 pgoyette Exp $");
 
 #include <assert.h>
 #include <ctype.h>
@@ -93,7 +93,7 @@
 }
 
 static int
-_ti_puts(int dodelay, int os, int pc,
+_ti_puts(int dodelay, short os, char pc,
     const char *str, int affcnt, int (*outc)(int, void *), void *args)
 {
 	int taildelay, delay, mand;
--- a/libexec/ld.elf_so/reloc.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/libexec/ld.elf_so/reloc.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: reloc.c,v 1.109 2016/06/14 13:06:41 christos Exp $	 */
+/*	$NetBSD: reloc.c,v 1.109.6.1 2017/05/02 03:19:16 pgoyette Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.109 2016/06/14 13:06:41 christos Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.109.6.1 2017/05/02 03:19:16 pgoyette Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -73,6 +73,22 @@
 	const Elf_Sym  *srcsym = NULL;
 	Obj_Entry      *srcobj;
 
+	if (__predict_false(size == 0)) {
+#if defined(__powerpc__) && !defined(__LP64) /* PR port-macppc/47464 */
+		if (strcmp(name, "_SDA_BASE_") == 0
+		    || strcmp(name, "_SDA2_BASE_") == 0)
+		{
+			rdbg(("COPY %s %s --> ignoring old binutils bug",
+			      dstobj->path, name));
+			return 0;
+		}
+#endif
+#if 0 /* shall we warn? */
+		xwarnx("%s: zero size COPY relocation for \"%s\"",
+		       dstobj->path, name);
+#endif
+	}
+
 	for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next) {
 		srcsym = _rtld_symlook_obj(name, hash, srcobj, 0,
 		    _rtld_fetch_ventry(dstobj, ELF_R_SYM(rela->r_info)));
--- a/sbin/fsck_msdos/dir.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sbin/fsck_msdos/dir.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: dir.c,v 1.28 2016/03/07 14:47:25 christos Exp $	*/
+/*	$NetBSD: dir.c,v 1.28.6.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
@@ -30,7 +30,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: dir.c,v 1.28 2016/03/07 14:47:25 christos Exp $");
+__RCSID("$NetBSD: dir.c,v 1.28.6.1 2017/05/02 03:19:16 pgoyette Exp $");
 #endif /* not lint */
 
 #include <stdio.h>
@@ -623,7 +623,7 @@
 			dirent.name[8] = '\0';
 			for (k = 7; k >= 0 && dirent.name[k] == ' '; k--)
 				dirent.name[k] = '\0';
-			if (dirent.name[k] != '\0')
+			if (k < 0 || dirent.name[k] != '\0')
 				k++;
 			if (dirent.name[0] == SLOT_E5)
 				dirent.name[0] = 0xe5;
--- a/sbin/nvmectl/Makefile	Sun Apr 30 10:27:16 2017 +0000
+++ b/sbin/nvmectl/Makefile	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.2 2017/02/13 11:16:46 nonaka Exp $
+#	$NetBSD: Makefile,v 1.2.2.1 2017/05/02 03:19:16 pgoyette Exp $
 
 .include <bsd.own.mk>
 
@@ -11,6 +11,7 @@
 SRCS+=	perftest.c
 SRCS+=	power.c
 SRCS+=	reset.c
+SRCS+=	wdc.c
 SRCS+=	bignum.c
 SRCS+=	humanize_bignum.c
 MAN=	nvmectl.8
--- a/sbin/nvmectl/firmware.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sbin/nvmectl/firmware.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: firmware.c,v 1.1 2016/06/04 16:29:35 nonaka Exp $	*/
+/*	$NetBSD: firmware.c,v 1.1.6.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2013 EMC Corp.
@@ -31,9 +31,9 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: firmware.c,v 1.1 2016/06/04 16:29:35 nonaka Exp $");
+__RCSID("$NetBSD: firmware.c,v 1.1.6.1 2017/05/02 03:19:16 pgoyette Exp $");
 #if 0
-__FBSDID("$FreeBSD: head/sbin/nvmecontrol/firmware.c 258071 2013-11-12 21:14:19Z jimharris $");
+__FBSDID("$FreeBSD: head/sbin/nvmecontrol/firmware.c 313188 2017-02-04 05:52:50Z imp $");
 #endif
 #endif
 
@@ -121,7 +121,7 @@
 	off = 0;
 	resid = payload_size;
 
-	if ((chunk = malloc(NVME_MAX_XFER_SIZE)) == NULL)
+	if ((chunk = aligned_alloc(PAGE_SIZE, NVME_MAX_XFER_SIZE)) == NULL)
 		errx(1, "unable to malloc %d bytes", NVME_MAX_XFER_SIZE);
 
 	while (resid > 0) {
--- a/sbin/nvmectl/logpage.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sbin/nvmectl/logpage.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: logpage.c,v 1.3 2017/02/13 11:16:46 nonaka Exp $	*/
+/*	$NetBSD: logpage.c,v 1.3.2.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2013 EMC Corp.
@@ -31,14 +31,15 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: logpage.c,v 1.3 2017/02/13 11:16:46 nonaka Exp $");
+__RCSID("$NetBSD: logpage.c,v 1.3.2.1 2017/05/02 03:19:16 pgoyette Exp $");
 #if 0
-__FBSDID("$FreeBSD: head/sbin/nvmecontrol/logpage.c 285796 2015-07-22 16:10:29Z jimharris $");
+__FBSDID("$FreeBSD: head/sbin/nvmecontrol/logpage.c 314230 2017-02-25 00:09:16Z imp $");
 #endif
 #endif
 
 #include <sys/param.h>
 #include <sys/ioccom.h>
+#include <sys/endian.h>
 
 #include <ctype.h>
 #include <err.h>
@@ -58,6 +59,39 @@
 
 typedef void (*print_fn_t)(void *buf, uint32_t size);
 
+struct kv_name {
+	uint32_t key;
+	const char *name;
+};
+
+static const char *
+kv_lookup(const struct kv_name *kv, size_t kv_count, uint32_t key)
+{
+	static char bad[32];
+	size_t i;
+
+	for (i = 0; i < kv_count; i++, kv++)
+		if (kv->key == key)
+			return kv->name;
+	snprintf(bad, sizeof(bad), "Attribute %#x", key);
+	return bad;
+}
+
+static void
+print_bin(void *data, uint32_t length)
+{
+	write(STDOUT_FILENO, data, length);
+}
+
+/* "Missing" from endian.h */
+static __inline uint64_t
+le48dec(const void *pp)
+{
+	uint8_t const *p = (uint8_t const *)pp;
+
+	return (((uint64_t)le16dec(p + 4) << 32) | le32dec(p));
+}
+
 static void *
 get_log_buffer(uint32_t size)
 {
@@ -178,10 +212,17 @@
 }
 
 static void
+print_temp(uint16_t t)
+{
+	printf("%u K, %2.2f C, %3.2f F\n", t, (float)t - 273.15,
+	    (float)t * 9 / 5 - 459.67);
+}
+
+static void
 print_log_health(void *buf, uint32_t size __unused)
 {
 	struct nvme_health_information_page *health = buf;
-	float composite_temperature = health->composite_temperature;
+	int i;
 
 	printf("SMART/Health Information Log\n");
 	printf("============================\n");
@@ -203,10 +244,8 @@
 	printf(" Volatile memory backup:        %d\n",
 	    (uint8_t)__SHIFTOUT(health->critical_warning,
 	      NVME_HEALTH_PAGE_CW_VOLATILE_MEMORY_BACKUP));
-	printf("Temperature:                    %u K, %2.2f C, %3.2f F\n",
-	    health->composite_temperature,
-	    composite_temperature - (float)273.15,
-	    (composite_temperature * (float)9/5) - (float)459.67);
+	printf("Temperature:                    ");
+	print_temp(health->composite_temperature);
 	printf("Available spare:                %u\n",
 	    health->available_spare);
 	printf("Available spare threshold:      %u\n",
@@ -214,26 +253,28 @@
 	printf("Percentage used:                %u\n",
 	    health->percentage_used);
 
-	print_bignum("Data units (512 byte) read:",
-	    health->data_units_read, "");
-	print_bignum("Data units (512 byte) written:",
-	    health->data_units_written, "");
-	print_bignum("Host read commands:",
-	    health->host_read_commands, "");
-	print_bignum("Host write commands:",
-	    health->host_write_commands, "");
-	print_bignum("Controller busy time (minutes):",
-	    health->controller_busy_time, "");
-	print_bignum("Power cycles:",
-	    health->power_cycles, "");
-	print_bignum("Power on hours:",
-	    health->power_on_hours, "");
-	print_bignum("Unsafe shutdowns:",
-	    health->unsafe_shutdowns, "");
-	print_bignum("Media errors:",
-	    health->media_errors, "");
+	print_bignum("Data units (512 byte) read:", health->data_units_read, "");
+	print_bignum("Data units (512 byte) written:", health->data_units_written,
+	    "");
+	print_bignum("Host read commands:", health->host_read_commands, "");
+	print_bignum("Host write commands:", health->host_write_commands, "");
+	print_bignum("Controller busy time (minutes):", health->controller_busy_time,
+	    "");
+	print_bignum("Power cycles:", health->power_cycles, "");
+	print_bignum("Power on hours:", health->power_on_hours, "");
+	print_bignum("Unsafe shutdowns:", health->unsafe_shutdowns, "");
+	print_bignum("Media errors:", health->media_errors, "");
 	print_bignum("No. error info log entries:",
 	    health->num_error_info_log_entries, "");
+
+	printf("Warning Temp Composite Time:    %d\n", health->warning_temp_time);
+	printf("Error Temp Composite Time:      %d\n", health->error_temp_time);
+	for (i = 0; i < 7; i++) {
+		if (health->temp_sensor[i] == 0)
+			continue;
+		printf("Temperature Sensor %d:           ", i + 1);
+		print_temp(health->temp_sensor[i]);
+	}
 }
 
 static void
@@ -265,14 +306,593 @@
 	}
 }
 
+/*
+ * Intel specific log pages from
+ * http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/ssd-dc-p3700-spec.pdf
+ *
+ * Though the version as of this date has a typo for the size of log page 0xca,
+ * offset 147: it is only 1 byte, not 6.
+ */
+static void
+print_intel_temp_stats(void *buf, uint32_t size __unused)
+{
+	struct intel_log_temp_stats	*temp = buf;
+
+	printf("Intel Temperature Log\n");
+	printf("=====================\n");
+
+	printf("Current:                        ");
+	print_temp(temp->current);
+	printf("Overtemp Last Flags             %#jx\n",
+	    (uintmax_t)temp->overtemp_flag_last);
+	printf("Overtemp Lifetime Flags         %#jx\n",
+	    (uintmax_t)temp->overtemp_flag_life);
+	printf("Max Temperature                 ");
+	print_temp(temp->max_temp);
+	printf("Min Temperature                 ");
+	print_temp(temp->min_temp);
+	printf("Max Operating Temperature       ");
+	print_temp(temp->max_oper_temp);
+	printf("Min Operating Temperature       ");
+	print_temp(temp->min_oper_temp);
+	printf("Estimated Temperature Offset:   %ju C/K\n",
+	    (uintmax_t)temp->est_offset);
+}
+
+/*
+ * Format from Table 22, section 5.7 IO Command Latency Statistics.
+ * Read and write stats pages have identical encoding.
+ */
+static void
+print_intel_read_write_lat_log(void *buf, uint32_t size __unused)
+{
+	const char *walker = buf;
+	int i;
+
+	printf("Major:                         %d\n", le16dec(walker + 0));
+	printf("Minor:                         %d\n", le16dec(walker + 2));
+	for (i = 0; i < 32; i++)
+		printf("%4dus-%4dus:                 %ju\n", i * 32, (i + 1) * 32,
+		    (uintmax_t)le32dec(walker + 4 + i * 4));
+	for (i = 1; i < 32; i++)
+		printf("%4dms-%4dms:                 %ju\n", i, i + 1,
+		    (uintmax_t)le32dec(walker + 132 + i * 4));
+	for (i = 1; i < 32; i++)
+		printf("%4dms-%4dms:                 %ju\n", i * 32, (i + 1) * 32,
+		    (uintmax_t)le32dec(walker + 256 + i * 4));
+}
+
+static void
+print_intel_read_lat_log(void *buf, uint32_t size)
+{
+
+	printf("Intel Read Latency Log\n");
+	printf("======================\n");
+	print_intel_read_write_lat_log(buf, size);
+}
+
+static void
+print_intel_write_lat_log(void *buf, uint32_t size)
+{
+
+	printf("Intel Write Latency Log\n");
+	printf("=======================\n");
+	print_intel_read_write_lat_log(buf, size);
+}
+
+/*
+ * Table 19. 5.4 SMART Attributes.
+ * Samsung also implements this and some extra data not documented.
+ */
+static void
+print_intel_add_smart(void *buf, uint32_t size __unused)
+{
+	uint8_t *walker = buf;
+	uint8_t *end = walker + 150;
+	const char *name;
+	uint64_t raw;
+	uint8_t normalized;
+
+	static struct kv_name kv[] = {
+		{ 0xab, "Program Fail Count" },
+		{ 0xac, "Erase Fail Count" },
+		{ 0xad, "Wear Leveling Count" },
+		{ 0xb8, "End to End Error Count" },
+		{ 0xc7, "CRC Error Count" },
+		{ 0xe2, "Timed: Media Wear" },
+		{ 0xe3, "Timed: Host Read %" },
+		{ 0xe4, "Timed: Elapsed Time" },
+		{ 0xea, "Thermal Throttle Status" },
+		{ 0xf0, "Retry Buffer Overflows" },
+		{ 0xf3, "PLL Lock Loss Count" },
+		{ 0xf4, "NAND Bytes Written" },
+		{ 0xf5, "Host Bytes Written" },
+	};
+
+	printf("Additional SMART Data Log\n");
+	printf("=========================\n");
+	/*
+	 * walker[0] = Key
+	 * walker[1,2] = reserved
+	 * walker[3] = Normalized Value
+	 * walker[4] = reserved
+	 * walker[5..10] = Little Endian Raw value
+	 *	(or other represenations)
+	 * walker[11] = reserved
+	 */
+	while (walker < end) {
+		name = kv_lookup(kv, __arraycount(kv), *walker);
+		normalized = walker[3];
+		raw = le48dec(walker + 5);
+		switch (*walker){
+		case 0:
+			break;
+		case 0xad:
+			printf("%-32s: %3d min: %u max: %u ave: %u\n", name,
+			    normalized, le16dec(walker + 5), le16dec(walker + 7),
+			    le16dec(walker + 9));
+			break;
+		case 0xe2:
+			printf("%-32s: %3d %.3f%%\n", name, normalized, raw / 1024.0);
+			break;
+		case 0xea:
+			printf("%-32s: %3d %d%% %d times\n", name, normalized,
+			    walker[5], le32dec(walker+6));
+			break;
+		default:
+			printf("%-32s: %3d %ju\n", name, normalized, (uintmax_t)raw);
+			break;
+		}
+		walker += 12;
+	}
+}
+
+/*
+ * HGST's 0xc1 page. This is a grab bag of additional data. Please see
+ * https://www.hgst.com/sites/default/files/resources/US_SN150_ProdManual.pdf
+ * https://www.hgst.com/sites/default/files/resources/US_SN100_ProdManual.pdf
+ * Appendix A for details
+ */
+
+typedef void (*subprint_fn_t)(void *buf, uint16_t subtype, uint8_t res, uint32_t size);
+
+struct subpage_print {
+	uint16_t key;
+	subprint_fn_t fn;
+};
+
+static void print_hgst_info_write_errors(void *, uint16_t, uint8_t, uint32_t);
+static void print_hgst_info_read_errors(void *, uint16_t, uint8_t, uint32_t);
+static void print_hgst_info_verify_errors(void *, uint16_t, uint8_t, uint32_t);
+static void print_hgst_info_self_test(void *, uint16_t, uint8_t, uint32_t);
+static void print_hgst_info_background_scan(void *, uint16_t, uint8_t, uint32_t);
+static void print_hgst_info_erase_errors(void *, uint16_t, uint8_t, uint32_t);
+static void print_hgst_info_erase_counts(void *, uint16_t, uint8_t, uint32_t);
+static void print_hgst_info_temp_history(void *, uint16_t, uint8_t, uint32_t);
+static void print_hgst_info_ssd_perf(void *, uint16_t, uint8_t, uint32_t);
+static void print_hgst_info_firmware_load(void *, uint16_t, uint8_t, uint32_t);
+
+static struct subpage_print hgst_subpage[] = {
+	{ 0x02, print_hgst_info_write_errors },
+	{ 0x03, print_hgst_info_read_errors },
+	{ 0x05, print_hgst_info_verify_errors },
+	{ 0x10, print_hgst_info_self_test },
+	{ 0x15, print_hgst_info_background_scan },
+	{ 0x30, print_hgst_info_erase_errors },
+	{ 0x31, print_hgst_info_erase_counts },
+	{ 0x32, print_hgst_info_temp_history },
+	{ 0x37, print_hgst_info_ssd_perf },
+	{ 0x38, print_hgst_info_firmware_load },
+};
+
+/* Print a subpage that is basically just key value pairs */
+static void
+print_hgst_info_subpage_gen(void *buf, uint16_t subtype __unused, uint32_t size,
+    const struct kv_name *kv, size_t kv_count)
+{
+	uint8_t *wsp, *esp;
+	uint16_t ptype;
+	uint8_t plen;
+	uint64_t param;
+	int i;
+
+	wsp = buf;
+	esp = wsp + size;
+	while (wsp < esp) {
+		ptype = le16dec(wsp);
+		wsp += 2;
+		wsp++;			/* Flags, just ignore */
+		plen = *wsp++;
+		param = 0;
+		for (i = 0; i < plen; i++)
+			param |= (uint64_t)*wsp++ << (i * 8);
+		printf("  %-30s: %jd\n", kv_lookup(kv, kv_count, ptype),
+		    (uintmax_t)param);
+	}
+}
+
+static void
+print_hgst_info_write_errors(void *buf, uint16_t subtype, uint8_t res __unused,
+    uint32_t size)
+{
+	static const struct kv_name kv[] = {
+		{ 0x0000, "Corrected Without Delay" },
+		{ 0x0001, "Corrected Maybe Delayed" },
+		{ 0x0002, "Re-Writes" },
+		{ 0x0003, "Errors Corrected" },
+		{ 0x0004, "Correct Algorithm Used" },
+		{ 0x0005, "Bytes Processed" },
+		{ 0x0006, "Uncorrected Errors" },
+		{ 0x8000, "Flash Write Commands" },
+		{ 0x8001, "HGST Special" },
+	};
+
+	printf("Write Errors Subpage:\n");
+	print_hgst_info_subpage_gen(buf, subtype, size, kv, __arraycount(kv));
+}
+
+static void
+print_hgst_info_read_errors(void *buf, uint16_t subtype, uint8_t res __unused,
+    uint32_t size)
+{
+	static const struct kv_name kv[] = {
+		{ 0x0000, "Corrected Without Delay" },
+		{ 0x0001, "Corrected Maybe Delayed" },
+		{ 0x0002, "Re-Reads" },
+		{ 0x0003, "Errors Corrected" },
+		{ 0x0004, "Correct Algorithm Used" },
+		{ 0x0005, "Bytes Processed" },
+		{ 0x0006, "Uncorrected Errors" },
+		{ 0x8000, "Flash Read Commands" },
+		{ 0x8001, "XOR Recovered" },
+		{ 0x8002, "Total Corrected Bits" },
+	};
+
+	printf("Read Errors Subpage:\n");
+	print_hgst_info_subpage_gen(buf, subtype, size, kv, __arraycount(kv));
+}
+
+static void
+print_hgst_info_verify_errors(void *buf, uint16_t subtype, uint8_t res __unused,
+    uint32_t size)
+{
+	static const struct kv_name kv[] = {
+		{ 0x0000, "Corrected Without Delay" },
+		{ 0x0001, "Corrected Maybe Delayed" },
+		{ 0x0002, "Re-Reads" },
+		{ 0x0003, "Errors Corrected" },
+		{ 0x0004, "Correct Algorithm Used" },
+		{ 0x0005, "Bytes Processed" },
+		{ 0x0006, "Uncorrected Errors" },
+		{ 0x8000, "Commands Processed" },
+	};
+
+	printf("Verify Errors Subpage:\n");
+	print_hgst_info_subpage_gen(buf, subtype, size, kv, __arraycount(kv));
+}
+
+static void
+print_hgst_info_self_test(void *buf, uint16_t subtype __unused, uint8_t res __unused,
+    uint32_t size)
+{
+	size_t i;
+	uint8_t *walker = buf;
+	uint16_t code, hrs;
+	uint32_t lba;
+
+	printf("Self Test Subpage:\n");
+	for (i = 0; i < size / 20; i++) {	/* Each entry is 20 bytes */
+		code = le16dec(walker);
+		walker += 2;
+		walker++;			/* Ignore fixed flags */
+		if (*walker == 0)		/* Last entry is zero length */
+			break;
+		if (*walker++ != 0x10) {
+			printf("Bad length for self test report\n");
+			return;
+		}
+		printf("  %-30s: %d\n", "Recent Test", code);
+		printf("    %-28s: %#x\n", "Self-Test Results", *walker & 0xf);
+		printf("    %-28s: %#x\n", "Self-Test Code", (*walker >> 5) & 0x7);
+		walker++;
+		printf("    %-28s: %#x\n", "Self-Test Number", *walker++);
+		hrs = le16dec(walker);
+		walker += 2;
+		lba = le32dec(walker);
+		walker += 4;
+		printf("    %-28s: %u\n", "Total Power On Hrs", hrs);
+		printf("    %-28s: %#jx (%jd)\n", "LBA", (uintmax_t)lba,
+		    (uintmax_t)lba);
+		printf("    %-28s: %#x\n", "Sense Key", *walker++ & 0xf);
+		printf("    %-28s: %#x\n", "Additional Sense Code", *walker++);
+		printf("    %-28s: %#x\n", "Additional Sense Qualifier", *walker++);
+		printf("    %-28s: %#x\n", "Vendor Specific Detail", *walker++);
+	}
+}
+
+static void
+print_hgst_info_background_scan(void *buf, uint16_t subtype __unused,
+    uint8_t res __unused, uint32_t size)
+{
+	uint8_t *walker = buf;
+	uint8_t status;
+	uint16_t code, nscan, progress;
+	uint32_t pom, nand;
+
+	printf("Background Media Scan Subpage:\n");
+	/* Decode the header */
+	code = le16dec(walker);
+	walker += 2;
+	walker++;			/* Ignore fixed flags */
+	if (*walker++ != 0x10) {
+		printf("Bad length for background scan header\n");
+		return;
+	}
+	if (code != 0) {
+		printf("Expceted code 0, found code %#x\n", code);
+		return;
+	}
+	pom = le32dec(walker);
+	walker += 4;
+	walker++;			/* Reserved */
+	status = *walker++;
+	nscan = le16dec(walker);
+	walker += 2;
+	progress = le16dec(walker);
+	walker += 2;
+	walker += 6;			/* Reserved */
+	printf("  %-30s: %d\n", "Power On Minutes", pom);
+	printf("  %-30s: %x (%s)\n", "BMS Status", status,
+	    status == 0 ? "idle" : (status == 1 ? "active" :
+	      (status == 8 ? "suspended" : "unknown")));
+	printf("  %-30s: %d\n", "Number of BMS", nscan);
+	printf("  %-30s: %d\n", "Progress Current BMS", progress);
+	/* Report retirements */
+	if (walker - (uint8_t *)buf != 20) {
+		printf("Coding error, offset not 20\n");
+		return;
+	}
+	size -= 20;
+	printf("  %-30s: %d\n", "BMS retirements", size / 0x18);
+	while (size > 0) {
+		code = le16dec(walker);
+		walker += 2;
+		walker++;
+		if (*walker++ != 0x14) {
+			printf("Bad length parameter\n");
+			return;
+		}
+		pom = le32dec(walker);
+		walker += 4;
+		/*
+		 * Spec sheet says the following are hard coded, if true, just
+		 * print the NAND retirement.
+		 */
+		if (walker[0] == 0x41 &&
+		    walker[1] == 0x0b &&
+		    walker[2] == 0x01 &&
+		    walker[3] == 0x00 &&
+		    walker[4] == 0x00 &&
+		    walker[5] == 0x00 &&
+		    walker[6] == 0x00 &&
+		    walker[7] == 0x00) {
+			walker += 8;
+			walker += 4;	/* Skip reserved */
+			nand = le32dec(walker);
+			walker += 4;
+			printf("  %-30s: %d\n", "Retirement number", code);
+			printf("    %-28s: %#x\n", "NAND (C/T)BBBPPP", nand);
+		} else {
+			printf("Parameter %#x entry corrupt\n", code);
+			walker += 16;
+		}
+	}
+}
+
+static void
+print_hgst_info_erase_errors(void *buf, uint16_t subtype __unused,
+    uint8_t res __unused, uint32_t size)
+{
+	static const struct kv_name kv[] = {
+		{ 0x0000, "Corrected Without Delay" },
+		{ 0x0001, "Corrected Maybe Delayed" },
+		{ 0x0002, "Re-Erase" },
+		{ 0x0003, "Errors Corrected" },
+		{ 0x0004, "Correct Algorithm Used" },
+		{ 0x0005, "Bytes Processed" },
+		{ 0x0006, "Uncorrected Errors" },
+		{ 0x8000, "Flash Erase Commands" },
+		{ 0x8001, "Mfg Defect Count" },
+		{ 0x8002, "Grown Defect Count" },
+		{ 0x8003, "Erase Count -- User" },
+		{ 0x8004, "Erase Count -- System" },
+	};
+
+	printf("Erase Errors Subpage:\n");
+	print_hgst_info_subpage_gen(buf, subtype, size, kv, __arraycount(kv));
+}
+
+static void
+print_hgst_info_erase_counts(void *buf, uint16_t subtype, uint8_t res __unused,
+    uint32_t size)
+{
+	/* My drive doesn't export this -- so not coding up */
+	printf("XXX: Erase counts subpage: %p, %#x %d\n", buf, subtype, size);
+}
+
+static void
+print_hgst_info_temp_history(void *buf, uint16_t subtype __unused,
+    uint8_t res __unused, uint32_t size __unused)
+{
+	uint8_t *walker = buf;
+	uint32_t min;
+
+	printf("Temperature History:\n");
+	printf("  %-30s: %d C\n", "Current Temperature", *walker++);
+	printf("  %-30s: %d C\n", "Reference Temperature", *walker++);
+	printf("  %-30s: %d C\n", "Maximum Temperature", *walker++);
+	printf("  %-30s: %d C\n", "Minimum Temperature", *walker++);
+	min = le32dec(walker);
+	walker += 4;
+	printf("  %-30s: %d:%02d:00\n", "Max Temperature Time", min / 60, min % 60);
+	min = le32dec(walker);
+	walker += 4;
+	printf("  %-30s: %d:%02d:00\n", "Over Temperature Duration", min / 60,
+	    min % 60);
+	min = le32dec(walker);
+	walker += 4;
+	printf("  %-30s: %d:%02d:00\n", "Min Temperature Time", min / 60, min % 60);
+}
+
+static void
+print_hgst_info_ssd_perf(void *buf, uint16_t subtype __unused, uint8_t res,
+    uint32_t size __unused)
+{
+	uint8_t *walker = buf;
+	uint64_t val;
+
+	printf("SSD Performance Subpage Type %d:\n", res);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "Host Read Commands", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "Host Read Blocks", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "Host Cache Read Hits Commands", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "Host Cache Read Hits Blocks", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "Host Read Commands Stalled", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "Host Write Commands", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "Host Write Blocks", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "Host Write Odd Start Commands", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "Host Write Odd End Commands", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "Host Write Commands Stalled", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "NAND Read Commands", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "NAND Read Blocks", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "NAND Write Commands", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "NAND Write Blocks", val);
+	val = le64dec(walker);
+	walker += 8;
+	printf("  %-30s: %ju\n", "NAND Read Before Writes", val);
+}
+
+static void
+print_hgst_info_firmware_load(void *buf, uint16_t subtype __unused,
+    uint8_t res __unused, uint32_t size __unused)
+{
+	uint8_t *walker = buf;
+
+	printf("Firmware Load Subpage:\n");
+	printf("  %-30s: %d\n", "Firmware Downloads", le32dec(walker));
+}
+
+static void
+kv_indirect(void *buf, uint32_t subtype, uint8_t res, uint32_t size,
+    struct subpage_print *sp, size_t nsp)
+{
+	size_t i;
+
+	for (i = 0; i < nsp; i++, sp++) {
+		if (sp->key == subtype) {
+			sp->fn(buf, subtype, res, size);
+			return;
+		}
+	}
+	printf("No handler for page type %x\n", subtype);
+}
+
+static void
+print_hgst_info_log(void *buf, uint32_t size __unused)
+{
+	uint8_t	*walker, *end, *subpage;
+	int pages __unused;
+	uint16_t len;
+	uint8_t subtype, res;
+
+	printf("HGST Extra Info Log\n");
+	printf("===================\n");
+
+	walker = buf;
+	pages = *walker++;
+	walker++;
+	len = le16dec(walker);
+	walker += 2;
+	end = walker + len;		/* Length is exclusive of this header */
+
+	while (walker < end) {
+		subpage = walker + 4;
+		subtype = *walker++ & 0x3f;	/* subtype */
+		res = *walker++;		/* Reserved */
+		len = le16dec(walker);
+		walker += len + 2;		/* Length, not incl header */
+		if (walker > end) {
+			printf("Ooops! Off the end of the list\n");
+			break;
+		}
+		kv_indirect(subpage, subtype, res, len, hgst_subpage,
+		    __arraycount(hgst_subpage));
+	}
+}
+
+/*
+ * Table of log page printer / sizing.
+ *
+ * This includes Intel specific pages that are widely implemented.
+ * Make sure you keep all the pages of one vendor together so -v help
+ * lists all the vendors pages.
+ */
 static struct logpage_function {
 	uint8_t		log_page;
-	print_fn_t	fn;
+	const char     *vendor;
+	const char     *name;
+	print_fn_t	print_fn;
+	size_t		size;
 } logfuncs[] = {
-	{NVME_LOG_ERROR,		print_log_error		},
-	{NVME_LOG_HEALTH_INFORMATION,	print_log_health	},
-	{NVME_LOG_FIRMWARE_SLOT,	print_log_firmware	},
-	{0,				NULL			},
+	{NVME_LOG_ERROR,		NULL,	"Drive Error Log",
+	 print_log_error,		0},
+	{NVME_LOG_HEALTH_INFORMATION,	NULL,	"Health/SMART Data",
+	 print_log_health,		sizeof(struct nvme_health_information_page)},
+	{NVME_LOG_FIRMWARE_SLOT,	NULL,	"Firmware Information",
+	 print_log_firmware,		sizeof(struct nvme_firmware_page)},
+	{HGST_INFO_LOG,			"hgst",	"Detailed Health/SMART",
+	 print_hgst_info_log,		DEFAULT_SIZE},
+	{HGST_INFO_LOG,			"wds",	"Detailed Health/SMART",
+	 print_hgst_info_log,		DEFAULT_SIZE},
+	{INTEL_LOG_TEMP_STATS,		"intel", "Temperature Stats",
+	 print_intel_temp_stats,	sizeof(struct intel_log_temp_stats)},
+	{INTEL_LOG_READ_LAT_LOG,	"intel", "Read Latencies",
+	 print_intel_read_lat_log,	DEFAULT_SIZE},
+	{INTEL_LOG_WRITE_LAT_LOG,	"intel", "Write Latencies",
+	 print_intel_write_lat_log,	DEFAULT_SIZE},
+	{INTEL_LOG_ADD_SMART,		"intel", "Extra Health/SMART Data",
+	 print_intel_add_smart,		DEFAULT_SIZE},
+	{INTEL_LOG_ADD_SMART,		"samsung", "Extra Health/SMART Data",
+	 print_intel_add_smart,		DEFAULT_SIZE},
+
+	{0, NULL, NULL, NULL, 0},
 };
 
 __dead static void
@@ -283,24 +903,48 @@
 	exit(1);
 }
 
+__dead static void
+logpage_help(void)
+{
+	struct logpage_function		*f;
+	const char 			*v;
+
+	fprintf(stderr, "\n");
+	fprintf(stderr, "%-8s %-10s %s\n", "Page", "Vendor","Page Name");
+	fprintf(stderr, "-------- ---------- ----------\n");
+	for (f = logfuncs; f->log_page > 0; f++) {
+		v = f->vendor == NULL ? "-" : f->vendor;
+		fprintf(stderr, "0x%02x     %-10s %s\n", f->log_page, v, f->name);
+	}
+
+	exit(1);
+}
+
 void
 logpage(int argc, char *argv[])
 {
 	int				fd, nsid;
 	int				log_page = 0, pageflag = false;
-	int				hexflag = false, ns_specified;
+	int				binflag = false, hexflag = false, ns_specified;
 	int				ch;
 	char				*p;
 	char				cname[64];
 	uint32_t			size;
 	void				*buf;
+	const char 			*vendor = NULL;
 	struct logpage_function		*f;
 	struct nvm_identify_controller	cdata;
 	print_fn_t			print_fn;
 
-	while ((ch = getopt(argc, argv, "p:x")) != -1) {
+	while ((ch = getopt(argc, argv, "bp:xv:")) != -1) {
 		switch (ch) {
+		case 'b':
+			binflag = true;
+			break;
 		case 'p':
+			if (strcmp(optarg, "help") == 0)
+				logpage_help();
+
 			/* TODO: Add human-readable ASCII page IDs */
 			log_page = strtol(optarg, &p, 0);
 			if (p != NULL && *p != '\0') {
@@ -308,20 +952,17 @@
 				    "\"%s\" not valid log page id.\n",
 				    optarg);
 				logpage_usage();
-			/* TODO: Define valid log page id ranges in nvme.h? */
-			} else if (log_page == 0 ||
-				   (log_page >= 0x04 && log_page <= 0x7F) ||
-				   (log_page >= 0x80 && log_page <= 0xBF)) {
-				fprintf(stderr,
-				    "\"%s\" not valid log page id.\n",
-				    optarg);
-				logpage_usage();
 			}
 			pageflag = true;
 			break;
 		case 'x':
 			hexflag = true;
 			break;
+		case 'v':
+			if (strcmp(optarg, "help") == 0)
+				logpage_help();
+			vendor = optarg;
+			break;
 		}
 	}
 
@@ -362,39 +1003,35 @@
 	}
 
 	print_fn = print_hex;
-	if (!hexflag) {
+	size = DEFAULT_SIZE;
+	if (binflag)
+		print_fn = print_bin;
+	if (!binflag && !hexflag) {
 		/*
-		 * See if there is a pretty print function for the
-		 *  specified log page.  If one isn't found, we
-		 *  just revert to the default (print_hex).
+		 * See if there is a pretty print function for the specified log
+		 * page.  If one isn't found, we just revert to the default
+		 * (print_hex). If there was a vendor specified bt the user, and
+		 * the page is vendor specific, don't match the print function
+		 * unless the vendors match.
 		 */
-		f = logfuncs;
-		while (f->log_page > 0) {
-			if (log_page == f->log_page) {
-				print_fn = f->fn;
-				break;
-			}
-			f++;
+		for (f = logfuncs; f->log_page > 0; f++) {
+			if (f->vendor != NULL && vendor != NULL &&
+			    strcmp(f->vendor, vendor) != 0)
+				continue;
+			if (log_page != f->log_page)
+				continue;
+			print_fn = f->print_fn;
+			size = f->size;
+			break;
 		}
 	}
 
+	if (log_page == NVME_LOG_ERROR) {
+		size = sizeof(struct nvme_error_information_entry);
+		size *= (cdata.elpe + 1);
+	}
+
 	/* Read the log page */
-	switch (log_page) {
-	case NVME_LOG_ERROR:
-		size = sizeof(struct nvme_error_information_entry);
-		size *= (cdata.elpe + 1);
-		break;
-	case NVME_LOG_HEALTH_INFORMATION:
-		size = sizeof(struct nvme_health_information_page);
-		break;
-	case NVME_LOG_FIRMWARE_SLOT:
-		size = sizeof(struct nvme_firmware_page);
-		break;
-	default:
-		size = DEFAULT_SIZE;
-		break;
-	}
-
 	buf = get_log_buffer(size);
 	read_logpage(fd, log_page, nsid, buf, size);
 	print_fn(buf, size);
--- a/sbin/nvmectl/nvme.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/sbin/nvmectl/nvme.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvme.h,v 1.1 2016/06/04 16:29:35 nonaka Exp $	*/
+/*	$NetBSD: nvme.h,v 1.1.6.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*-
  * Copyright (C) 2012-2013 Intel Corporation
@@ -25,13 +25,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/nvme/nvme.h 296617 2016-03-10 17:13:10Z mav $
+ * $FreeBSD: head/sys/dev/nvme/nvme.h 314888 2017-03-07 23:02:59Z imp $
  */
 
 #ifndef __NVME_H__
 #define __NVME_H__
 
-#define	NVME_MAX_XFER_SIZE	MAXPHYS
+/* Cap nvme to 1MB transfers driver explodes with larger sizes */
+#define NVME_MAX_XFER_SIZE		(MAXPHYS < (1<<20) ? MAXPHYS : (1<<20))
 
 /* Get/Set Features */
 #define	NVME_FEAT_ARBITRATION				0x01
@@ -60,6 +61,19 @@
 #define	NVME_LOG_CHANGED_NAMESPACE_LIST			0x04
 #define	NVME_LOG_COMMAND_EFFECTS_LOG			0x05
 #define	NVME_LOG_RESERVATION_NOTIFICATION		0x80
+/*
+ * The following are Intel Specific log pages, but they seem
+ * to be widely implemented.
+ */
+#define	INTEL_LOG_READ_LAT_LOG				0xc1
+#define	INTEL_LOG_WRITE_LAT_LOG				0xc2
+#define	INTEL_LOG_TEMP_STATS				0xc5
+#define	INTEL_LOG_ADD_SMART				0xca
+#define	INTEL_LOG_DRIVE_MKT_NAME			0xdd
+/*
+ * HGST log page, with lots ofs sub pages.
+ */
+#define	HGST_INFO_LOG					0xc1
 
 /* Error Information Log (Log Identifier 01h) */
 struct nvme_error_information_entry {
@@ -101,9 +115,9 @@
 	uint64_t		unsafe_shutdowns[2];
 	uint64_t		media_errors[2];
 	uint64_t		num_error_info_log_entries[2];
-	uint32_t		warning_composite_temperature_time;
-	uint32_t		critical_composite_temperature_time;
-	uint16_t		temperature_sensor[8];
+	uint32_t		warning_temp_time;
+	uint32_t		error_temp_time;
+	uint16_t		temp_sensor[8];
 
 	uint8_t			reserved[296];
 } __packed __aligned(4);
@@ -126,6 +140,18 @@
 	uint8_t			reserved[448];
 } __packed __aligned(4);
 
+struct intel_log_temp_stats {
+	uint64_t	current;
+	uint64_t	overtemp_flag_last;
+	uint64_t	overtemp_flag_life;
+	uint64_t	max_temp;
+	uint64_t	min_temp;
+	uint64_t	_rsvd[5];
+	uint64_t	max_oper_temp;
+	uint64_t	min_oper_temp;
+	uint64_t	est_offset;
+} __packed __aligned(4);
+
 /* Commands Supported and Effects (Log Identifier 05h) */
 struct nvme_command_effeects_page {
 	uint32_t		acs[256];
--- a/sbin/nvmectl/nvmectl.8	Sun Apr 30 10:27:16 2017 +0000
+++ b/sbin/nvmectl/nvmectl.8	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: nvmectl.8,v 1.2 2016/06/05 09:13:08 wiz Exp $
+.\" $NetBSD: nvmectl.8,v 1.2.6.1 2017/05/02 03:19:16 pgoyette Exp $
 .\"
 .\" Copyright (c) 2012 Intel Corporation
 .\" All rights reserved.
@@ -32,7 +32,7 @@
 .\"
 .\" Author: Jim Harris <jimharris@FreeBSD.org>
 .\"
-.\" $FreeBSD: head/sbin/nvmecontrol/nvmecontrol.8 299151 2016-05-06 03:11:34Z pfg $
+.\" $FreeBSD: head/sbin/nvmecontrol/nvmecontrol.8 314230 2017-02-25 00:09:16Z imp $
 .\"
 .Dd May 19, 2016
 .Dt NVMECTL 8
@@ -62,6 +62,8 @@
 .Ic logpage
 .Op Fl x
 .Op Fl p Ar page_id
+.Op Fl v Ar vendor-string
+.Op Fl b
 .Ar device_id Ns | Ns Ar namespace_id
 .\".Nm
 .\".Ic firmware
@@ -75,9 +77,56 @@
 .Op Fl p Ar power_state
 .Op Fl w Ar workload_hint
 .Ar device_id
+.Nm
+.Ic wdc cap-diag
+.Op Fl o path_template
+.Ar device id
+.Nm
+.Ic wdc drive-log
+.Op Fl o path_template
+.Ar device id
+.Nm
+.Ic wdc get-crash-dump
+.Op Fl o path_template
+.Ar device id
+.\" .Nm
+.\" .Ic wdc purge
+.\" .Aq device id
+.\" .Nm
+.\" .Ic wdc purge-monitor
+.\" .Aq device id
 .Sh DESCRIPTION
 NVM Express (NVMe) is a storage protocol standard, for SSDs and other
 high-speed storage devices over PCI Express.
+.Ss logpage
+The logpage command knows how to print log pages of various types.
+It also knows about vendor specific log pages from hgst/wdc and intel.
+Page 0xc1 for hgst/wdc contains the advanced smart information about
+the drive.
+Page 0xc1 is read latency stats for intel.
+Page 0xc2 is write latency stats for intel.
+Page 0xc5 is temperature stats for intel.
+Page 0xca is advanced smart information for intel.
+.Pp
+Specifying
+.Fl p
+.Ic help
+will list all valid vendors and pages.
+.Fl x
+will print the page as hex.
+.Fl b
+will print the binary data for the page.
+.Ss wdc
+The various wdc commands retrieve log data from the wdc/hgst drives.
+The
+.Fl o
+flag specifies a path template to use to output the files.
+Each file takes the path template (which defaults to nothing), appends
+the drive's serial number and the type of dump it is followed
+by
+.Pa .bin .
+These logs must be sent to the vendor for analysis.
+This tool only provides a way to extract them.
 .Sh EXAMPLES
 .Dl nvmectl devlist
 .Pp
@@ -95,9 +144,9 @@
 .\".Pp
 .\".Dl nvmectl perftest -n 32 -o read -s 512 -t 30 nvme0ns1
 .\".Pp
-.\"Run a performance test on nvme0ns1 using 32 kernel threads for 30 seconds.  Each
-.\"thread will issue a single 512 byte read command.  Results are printed to
-.\"stdout when 30 seconds expires.
+.\"Run a performance test on nvme0ns1 using 32 kernel threads for 30 seconds.
+.\"Each thread will issue a single 512 byte read command.
+.\"Results are printed to stdout when 30 seconds expires.
 .\".Pp
 .\".Dl nvmectl reset nvme0
 .\".Pp
@@ -109,9 +158,20 @@
 Log pages defined by the NVMe specification include Error Information Log (ID=1),
 SMART/Health Information Log (ID=2), and Firmware Slot Log (ID=3).
 .Pp
+.Dl nvmectl logpage -p 0xc1 -v wdc nvme0
+.Pp
+Display a human-readable summary of the nvme0's wdc-specific advanced
+SMART data.
+.Pp
 .Dl nvmectl logpage -p 1 -x nvme0
 .Pp
 Display a hexadecimal dump of the nvme0 controller's Error Information Log.
+.Pp
+.Dl nvmectl logpage -p 0xcb -b nvme0 > /tmp/page-cb.bin
+.Pp
+Print the contents of vendor specific page 0xcb as binary data on
+standard out.
+Redirect it to a temporary file.
 .\".Pp
 .\".Dl nvmectl firmware -s 2 -f /tmp/nvme_firmware nvme0
 .\".Pp
@@ -138,6 +198,9 @@
 .Dl nvmectl power nvme0
 .Pp
 Get the current power mode.
+.Sh HISTORY
+The nvmecontrol utility appeared in
+.Fx 9.2 .
 .Sh AUTHORS
 .An -nosplit
 nvmecontrol was developed by Intel and originally written by
--- a/sbin/nvmectl/nvmectl.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sbin/nvmectl/nvmectl.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmectl.c,v 1.2 2016/06/04 20:59:49 joerg Exp $	*/
+/*	$NetBSD: nvmectl.c,v 1.2.6.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*-
  * Copyright (C) 2012-2013 Intel Corporation
@@ -28,9 +28,9 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: nvmectl.c,v 1.2 2016/06/04 20:59:49 joerg Exp $");
+__RCSID("$NetBSD: nvmectl.c,v 1.2.6.1 2017/05/02 03:19:16 pgoyette Exp $");
 #if 0
-__FBSDID("$FreeBSD: head/sbin/nvmecontrol/nvmecontrol.c 295087 2016-01-30 22:48:06Z imp $");
+__FBSDID("$FreeBSD: head/sbin/nvmecontrol/nvmecontrol.c 314229 2017-02-25 00:09:12Z imp $");
 #endif
 #endif
 
@@ -52,13 +52,7 @@
 
 #include "nvmectl.h"
 
-typedef void (*nvme_fn_t)(int argc, char *argv[]);
-
-static struct nvme_function {
-	const char	*name;
-	nvme_fn_t	fn;
-	const char	*usage;
-} funcs[] = {
+static struct nvme_function funcs[] = {
 	{"devlist",	devlist,	DEVLIST_USAGE},
 	{"identify",	identify,	IDENTIFY_USAGE},
 #ifdef PERFTEST_USAGE
@@ -72,15 +66,14 @@
 	{"firmware",	firmware,	FIRMWARE_USAGE},
 #endif
 	{"power",	power,		POWER_USAGE},
+	{"wdc",		wdc,		WDC_USAGE},
 	{NULL,		NULL,		NULL},
 };
 
-__dead static void
-usage(void)
+void
+gen_usage(struct nvme_function *f)
 {
-	struct nvme_function *f;
 
-	f = funcs;
 	fprintf(stderr, "usage:\n");
 	while (f->name != NULL) {
 		fprintf(stderr, "%s", f->usage);
@@ -89,6 +82,26 @@
 	exit(1);
 }
 
+void
+dispatch(int argc, char *argv[], struct nvme_function *tbl)
+{
+	struct nvme_function *f = tbl;
+
+	if (argv[1] == NULL) {
+		gen_usage(tbl);
+		return;
+	}
+
+	while (f->name != NULL) {
+		if (strcmp(argv[1], f->name) == 0)
+			f->fn(argc-1, &argv[1]);
+		f++;
+	}
+
+	fprintf(stderr, "Unknown command: %s\n", argv[1]);
+	gen_usage(tbl);
+}
+
 static void
 print_bytes(void *data, uint32_t length)
 {
@@ -269,19 +282,11 @@
 int
 main(int argc, char *argv[])
 {
-	struct nvme_function *f;
 
 	if (argc < 2)
-		usage();
+		gen_usage(funcs);
 
-	f = funcs;
-	while (f->name != NULL) {
-		if (strcmp(argv[1], f->name) == 0)
-			f->fn(argc-1, &argv[1]);
-		f++;
-	}
-
-	usage();
+	dispatch(argc, argv, funcs);
 
 	return (0);
 }
--- a/sbin/nvmectl/nvmectl.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/sbin/nvmectl/nvmectl.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmectl.h,v 1.2 2016/06/04 20:59:49 joerg Exp $	*/
+/*	$NetBSD: nvmectl.h,v 1.2.6.1 2017/05/02 03:19:16 pgoyette Exp $	*/
 
 /*-
  * Copyright (C) 2012-2013 Intel Corporation
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sbin/nvmecontrol/nvmecontrol.h 295087 2016-01-30 22:48:06Z imp $
+ * $FreeBSD: head/sbin/nvmecontrol/nvmecontrol.h 314230 2017-02-25 00:09:16Z imp $
  */
 
 #ifndef __NVMECTL_H__
@@ -36,6 +36,14 @@
 #include <dev/ic/nvmeio.h>
 #include "nvme.h"
 
+typedef void (*nvme_fn_t)(int argc, char *argv[]);
+
+struct nvme_function {
+	const char	*name;
+	nvme_fn_t	fn;
+	const char	*usage;
+};
+
 #define NVME_CTRLR_PREFIX	"nvme"
 #define NVME_NS_PREFIX		"ns"
 
@@ -47,9 +55,9 @@
 
 #if 0
 #define PERFTEST_USAGE							       \
-"       nvmectl perftest <-n num_threads> <-o read|write>\n"	               \
+"       nvmectl perftest <-n num_threads> <-o read|write>\n"		       \
 "                        <-s size_in_bytes> <-t time_in_seconds>\n"	       \
-"                        <-i intr|wait> [-f refthread] [-p]\n"	               \
+"                        <-i intr|wait> [-f refthread] [-p]\n"		       \
 "                        <namespace id>\n"
 #endif
 
@@ -59,7 +67,8 @@
 #endif
 
 #define LOGPAGE_USAGE							       \
-"       nvmectl logpage <-p page_id> [-x] <controller id|namespace id>\n"  \
+"       nvmectl logpage <-p page_id> [-b] [-v vendor] [-x] "		       \
+    "<controller id|namespace id>\n"
 
 #if 0
 #define FIRMWARE_USAGE							       \
@@ -69,19 +78,23 @@
 #define POWER_USAGE							       \
 "       nvmectl power [-l] [-p new-state [-w workload-hint]] <controller id>\n"
 
+#define WDC_USAGE							       \
+"       nvmecontrol wdc (cap-diag|drive-log|get-crash-dump|purge|purge-montior)\n"
+
 void devlist(int, char *[]) __dead;
 void identify(int, char *[]) __dead;
 #ifdef PERFTEST_USAGE
-void perftest(int, char *[]);
+void perftest(int, char *[]) __dead;
 #endif
 #ifdef RESET_USAGE
-void reset(int, char *[]);
+void reset(int, char *[]) __dead;
 #endif
 void logpage(int, char *[]) __dead;
 #ifdef FIRMWARE_USAGE
-void firmware(int, char *[]);
+void firmware(int, char *[]) __dead;
 #endif
 void power(int, char *[]) __dead;
+void wdc(int, char *[]) __dead;
 
 int open_dev(const char *, int *, int, int);
 void parse_ns_str(const char *, char *, int *);
@@ -89,6 +102,8 @@
 void read_namespace_data(int, int, struct nvm_identify_namespace *);
 void print_hex(void *, uint32_t);
 void read_logpage(int, uint8_t, int, void *, uint32_t);
+void gen_usage(struct nvme_function *) __dead;
+void dispatch(int argc, char *argv[], struct nvme_function *f);
 void nvme_strvis(uint8_t *, int, const uint8_t *, int);
 
 #endif	/* __NVMECTL_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbin/nvmectl/wdc.c	Tue May 02 03:19:14 2017 +0000
@@ -0,0 +1,354 @@
+/*	$NetBSD: wdc.c,v 1.1.2.2 2017/05/02 03:19:16 pgoyette Exp $	*/
+
+/*-
+ * Copyright (c) 2017 Netflix, Inc
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: wdc.c,v 1.1.2.2 2017/05/02 03:19:16 pgoyette Exp $");
+#if 0
+__FBSDID("$FreeBSD: head/sbin/nvmecontrol/wdc.c 316105 2017-03-28 20:34:02Z ngie $");
+#endif
+#endif
+
+#include <sys/param.h>
+#include <sys/ioccom.h>
+#include <sys/endian.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "nvmectl.h"
+
+#define WDC_NVME_TOC_SIZE	8
+
+#define WDC_NVME_CAP_DIAG_OPCODE	0xe6
+#define WDC_NVME_CAP_DIAG_CMD		0x0000
+
+#define WDC_NVME_DIAG_OPCODE		0xc6
+#define WDC_NVME_DRIVE_LOG_SIZE_CMD	0x0120
+#define WDC_NVME_DRIVE_LOG_CMD		0x0020
+#define WDC_NVME_CRASH_DUMP_SIZE_CMD	0x0320
+#define WDC_NVME_CRASH_DUMP_CMD		0x0420
+#define WDC_NVME_PFAIL_DUMP_SIZE_CMD	0x0520
+#define WDC_NVME_PFAIL_DUMP_CMD		0x0620
+
+#define WDC_NVME_CLEAR_DUMP_OPCODE	0xff
+#define WDC_NVME_CLEAR_CRASH_DUMP_CMD	0x0503
+#define WDC_NVME_CLEAR_PFAIL_DUMP_CMD	0x0603
+
+static void wdc_cap_diag(int argc, char *argv[]);
+static void wdc_drive_log(int argc, char *argv[]);
+static void wdc_get_crash_dump(int argc, char *argv[]);
+static void wdc_purge(int argc, char *argv[]);
+static void wdc_purge_monitor(int argc, char *argv[]);
+
+#define WDC_CAP_DIAG_USAGE	"\tnvmecontrol wdc cap-diag [-o path-template]\n"
+#define WDC_DRIVE_LOG_USAGE	"\tnvmecontrol wdc drive-log [-o path-template]\n"
+#define WDC_GET_CRASH_DUMP_USAGE "\tnvmecontrol wdc get-crash-dump [-o path-template]\n"
+#define WDC_PURGE_USAGE		"\tnvmecontrol wdc purge [-o path-template]\n"
+#define WDC_PURGE_MONITOR_USAGE	"\tnvmecontrol wdc purge-monitor\n"
+
+static struct nvme_function wdc_funcs[] = {
+	{"cap-diag",		wdc_cap_diag,		WDC_CAP_DIAG_USAGE},
+	{"drive-log",		wdc_drive_log,		WDC_DRIVE_LOG_USAGE},
+	{"get-crash-dump",	wdc_get_crash_dump,	WDC_GET_CRASH_DUMP_USAGE},
+	{"purge",		wdc_purge,		WDC_PURGE_USAGE},
+	{"purge_monitor",	wdc_purge_monitor,	WDC_PURGE_MONITOR_USAGE},
+	{NULL,			NULL,			NULL},
+};
+
+static void
+wdc_append_serial_name(int fd, char *buf, size_t len, const char *suffix)
+{
+	struct nvm_identify_controller	cdata;
+	char sn[sizeof(cdata.sn) + 1];
+	char *walker;
+
+	len -= strlen(buf);
+	buf += strlen(buf);
+	read_controller_data(fd, &cdata);
+	memcpy(sn, cdata.sn, sizeof(cdata.sn));
+	walker = sn + sizeof(cdata.sn) - 1;
+	while (walker > sn && *walker == ' ')
+		walker--;
+	*++walker = '\0';
+	snprintf(buf, len, "%s%s.bin", sn, suffix);
+}
+
+static void
+wdc_get_data(int fd, uint32_t opcode, uint32_t len, uint32_t off, uint32_t cmd,
+    uint8_t *buffer, size_t buflen)
+{
+	struct nvme_pt_command	pt;
+
+	memset(&pt, 0, sizeof(pt));
+	pt.cmd.opcode = opcode;
+	pt.cmd.cdw10 = len / sizeof(uint32_t);	/* - 1 like all the others ??? */
+	pt.cmd.cdw11 = off / sizeof(uint32_t);
+	pt.cmd.cdw12 = cmd;
+	pt.buf = buffer;
+	pt.len = buflen;
+	pt.is_read = 1;
+//	printf("opcode %#x cdw10(len) %#x cdw11(offset?) %#x cdw12(cmd/sub) %#x buflen %zd\n",
+//	    (int)opcode, (int)cdw10, (int)cdw11, (int)cdw12, buflen);
+
+	if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
+		err(1, "wdc_get_data request failed");
+	if (nvme_completion_is_error(&pt.cpl))
+		errx(1, "wdc_get_data request returned error");
+}
+
+static void
+wdc_do_dump(int fd, char *tmpl, const char *suffix, uint32_t opcode,
+    uint32_t size_cmd, uint32_t cmd, int len_off)
+{
+	int fd2;
+	uint8_t *buf;
+	uint32_t len, offset;
+	ssize_t resid;
+	long page_size;
+
+	page_size = sysconf(_SC_PAGESIZE);
+	if (page_size <= 0)
+		page_size = 4096;
+
+	wdc_append_serial_name(fd, tmpl, MAXPATHLEN, suffix);
+
+	buf = aligned_alloc(page_size, WDC_NVME_TOC_SIZE);
+	if (buf == NULL)
+		errx(1, "Can't get buffer to get size");
+	wdc_get_data(fd, opcode, WDC_NVME_TOC_SIZE,
+	    0, size_cmd, buf, WDC_NVME_TOC_SIZE);
+	len = be32dec(buf + len_off);
+
+	if (len == 0)
+		errx(1, "No data for %s", suffix);
+
+	printf("Dumping %d bytes to %s\n", len, tmpl);
+	/* XXX overwrite protection? */
+	fd2 = open(tmpl, O_WRONLY | O_CREAT | O_TRUNC);
+	if (fd2 < 0)
+		err(1, "open %s", tmpl);
+	offset = 0;
+	buf = aligned_alloc(page_size, NVME_MAX_XFER_SIZE);
+	if (buf == NULL)
+		errx(1, "Can't get buffer to read dump");
+	while (len > 0) {
+		resid = len > NVME_MAX_XFER_SIZE ? NVME_MAX_XFER_SIZE : len;
+		wdc_get_data(fd, opcode, resid, offset, cmd, buf, resid);
+		if (write(fd2, buf, resid) != resid)
+			err(1, "write");
+		offset += resid;
+		len -= resid;
+	}
+	free(buf);
+	close(fd2);
+}
+
+static void
+wdc_do_clear_dump(int fd, uint32_t opcode, uint32_t cmd)
+{
+	struct nvme_pt_command	pt;
+
+	memset(&pt, 0, sizeof(pt));
+	pt.cmd.opcode = opcode;
+	pt.cmd.cdw12 = cmd;
+	if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
+		err(1, "wdc_do_clear_dump request failed");
+	if (nvme_completion_is_error(&pt.cpl))
+		errx(1, "wdc_do_clear_dump request returned error");
+}
+
+__dead static void
+wdc_cap_diag_usage(void)
+{
+	fprintf(stderr, "usage:\n");
+	fprintf(stderr, WDC_CAP_DIAG_USAGE);
+	exit(1);
+}
+
+__dead static void
+wdc_cap_diag(int argc, char *argv[])
+{
+	char path_tmpl[MAXPATHLEN];
+	int ch, fd;
+
+	path_tmpl[0] = '\0';
+	while ((ch = getopt(argc, argv, "o:")) != -1) {
+		switch ((char)ch) {
+		case 'o':
+			strlcpy(path_tmpl, optarg, MAXPATHLEN);
+			break;
+		default:
+			wdc_cap_diag_usage();
+		}
+	}
+	/* Check that a controller was specified. */
+	if (optind >= argc)
+		wdc_cap_diag_usage();
+	open_dev(argv[optind], &fd, 1, 1);
+
+	wdc_do_dump(fd, path_tmpl, "cap_diag", WDC_NVME_CAP_DIAG_OPCODE,
+	    WDC_NVME_CAP_DIAG_CMD, WDC_NVME_CAP_DIAG_CMD, 4);
+
+	close(fd);
+
+	exit(1);	
+}
+
+__dead static void
+wdc_drive_log_usage(void)
+{
+	fprintf(stderr, "usage:\n");
+	fprintf(stderr, WDC_DRIVE_LOG_USAGE);
+	exit(1);
+}
+
+__dead static void
+wdc_drive_log(int argc, char *argv[])
+{
+	char path_tmpl[MAXPATHLEN];
+	int ch, fd;
+
+	path_tmpl[0] = '\0';
+	while ((ch = getopt(argc, argv, "o:")) != -1) {
+		switch ((char)ch) {
+		case 'o':
+			strlcpy(path_tmpl, optarg, MAXPATHLEN);
+			break;
+		default:
+			wdc_drive_log_usage();
+		}
+	}
+	/* Check that a controller was specified. */
+	if (optind >= argc)
+		wdc_drive_log_usage();
+	open_dev(argv[optind], &fd, 1, 1);
+
+	wdc_do_dump(fd, path_tmpl, "drive_log", WDC_NVME_DIAG_OPCODE,
+	    WDC_NVME_DRIVE_LOG_SIZE_CMD, WDC_NVME_DRIVE_LOG_CMD, 0);
+
+	close(fd);
+
+	exit(1);
+}
+
+__dead static void
+wdc_get_crash_dump_usage(void)
+{
+	fprintf(stderr, "usage:\n");
+	fprintf(stderr, WDC_CAP_DIAG_USAGE);
+	exit(1);
+}
+
+__dead static void
+wdc_get_crash_dump(int argc, char *argv[])
+{
+	char path_tmpl[MAXPATHLEN];
+	int ch, fd;
+
+	while ((ch = getopt(argc, argv, "o:")) != -1) {
+		switch ((char)ch) {
+		case 'o':
+			strlcpy(path_tmpl, optarg, MAXPATHLEN);
+			break;
+		default:
+			wdc_get_crash_dump_usage();
+		}
+	}
+	/* Check that a controller was specified. */
+	if (optind >= argc)
+		wdc_get_crash_dump_usage();
+	open_dev(argv[optind], &fd, 1, 1);
+
+	wdc_do_dump(fd, path_tmpl, "crash_dump", WDC_NVME_DIAG_OPCODE,
+	    WDC_NVME_CRASH_DUMP_SIZE_CMD, WDC_NVME_CRASH_DUMP_CMD, 0);
+	wdc_do_clear_dump(fd, WDC_NVME_CLEAR_DUMP_OPCODE,
+	    WDC_NVME_CLEAR_CRASH_DUMP_CMD);
+//	wdc_led_beacon_disable(fd);
+	wdc_do_dump(fd, path_tmpl, "pfail_dump", WDC_NVME_DIAG_OPCODE,
+	    WDC_NVME_PFAIL_DUMP_SIZE_CMD, WDC_NVME_PFAIL_DUMP_CMD, 0);
+	wdc_do_clear_dump(fd, WDC_NVME_CLEAR_DUMP_OPCODE,
+		WDC_NVME_CLEAR_PFAIL_DUMP_CMD);
+
+	close(fd);
+
+	exit(1);
+}
+
+__dead static void
+wdc_purge(int argc, char *argv[])
+{
+	char path_tmpl[MAXPATHLEN];
+	int ch;
+
+	while ((ch = getopt(argc, argv, "o:")) != -1) {
+		switch ((char)ch) {
+		case 'o':
+			strlcpy(path_tmpl, optarg, MAXPATHLEN);
+			break;
+		default:
+			wdc_cap_diag_usage();
+		}
+	}
+
+	printf("purge has not been implemented.\n");
+	exit(1);
+}
+
+__dead static void
+wdc_purge_monitor(int argc, char *argv[])
+{
+	char path_tmpl[MAXPATHLEN];
+	int ch;
+
+	while ((ch = getopt(argc, argv, "o:")) != -1) {
+		switch ((char)ch) {
+		case 'o':
+			strlcpy(path_tmpl, optarg, MAXPATHLEN);
+			break;
+		default:
+			wdc_cap_diag_usage();
+		}
+	}
+
+	printf("purge has not been implemented.\n");
+	exit(1);
+}
+
+void
+wdc(int argc, char *argv[])
+{
+
+	dispatch(argc, argv, wdc_funcs);
+}
--- a/share/man/man4/midi.4	Sun Apr 30 10:27:16 2017 +0000
+++ b/share/man/man4/midi.4	Tue May 02 03:19:14 2017 +0000
@@ -1,6 +1,6 @@
-.\" $NetBSD: midi.4,v 1.30 2010/03/22 18:58:31 joerg Exp $
+.\" $NetBSD: midi.4,v 1.30.38.1 2017/05/02 03:19:16 pgoyette Exp $
 .\"
-.\" Copyright (c) 1999-2006 The NetBSD Foundation, Inc.
+.\" Copyright (c) 1999-2017 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This code is derived from software contributed to The NetBSD Foundation
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd May 6, 2006
+.Dd April 28, 2017
 .Dt MIDI 4
 .Os
 .Sh NAME
@@ -593,6 +593,7 @@
 protocol.
 .Sh SEE ALSO
 .Xr midiplay 1 ,
+.Xr midirecord 1 ,
 .Xr ioctl 2 ,
 .Xr ossaudio 3 ,
 .Xr audio 4 ,
--- a/share/man/man4/nvme.4	Sun Apr 30 10:27:16 2017 +0000
+++ b/share/man/man4/nvme.4	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-.\"	$NetBSD: nvme.4,v 1.9 2016/10/22 07:36:36 wiz Exp $
+.\"	$NetBSD: nvme.4,v 1.9.4.1 2017/05/02 03:19:16 pgoyette Exp $
 .\"	$OpenBSD: nvme.4,v 1.2 2016/04/14 11:53:37 jmc Exp $
 .\"
 .\" Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
@@ -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 October 21, 2016
+.Dd April 27, 2017
 .Dt NVME 4
 .Os
 .Sh NAME
@@ -133,17 +133,9 @@
 Such cards do not even probe when plugged
 into older generation slot.
 .Pp
-The driver also attaches and works fine for emulated
+The driver was also tested and confirmed working fine for emulated
 .Nm
-devices under QEMU and
+devices under QEMU 2.8.0 and
 .Tn Oracle
-.Tn VirtualBox .
-However, there seems to be some broken interaction between
 .Tn VirtualBox
-5.1.6
-and the driver, the emulated
-.Nm
-controller responds to commands only the first time it is attached,
-after reboot or module reload it stops responding.
-The virtual machine must be completely powered off
-(or even killed) to fix this.
+5.1.20.
--- a/share/man/man8/compat_freebsd.8	Sun Apr 30 10:27:16 2017 +0000
+++ b/share/man/man8/compat_freebsd.8	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-.\"	$NetBSD: compat_freebsd.8,v 1.15 2011/11/21 15:11:45 wiz Exp $
+.\"	$NetBSD: compat_freebsd.8,v 1.15.30.1 2017/05/02 03:19:16 pgoyette Exp $
 .\"	from: compat_linux.8,v 1.1 1995/03/05 23:30:36 fvdl Exp
 .\"
 .\" Copyright (c) 1995 Frank van der Linden
@@ -30,7 +30,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 4, 1995
+.Dd April 30, 2017
 .Dt COMPAT_FREEBSD 8
 .Os
 .Sh NAME
@@ -375,17 +375,8 @@
 Sometimes the files are unpacked, and you can get the individual
 files you need, but mostly they are stored in distribution sets,
 usually consisting of subdirectories with gzipped tar files in them.
-The primary ftp sites for the distributions are:
-.Bl -item -compact -offset indent
-.It
-.Pa ftp.freebsd.org:/pub/FreeBSD
-.El
-.Pp
-Mirror sites are described on:
-.Bl -item -compact -offset indent
-.It
-.Pa ftp.freebsd.org:/pub/FreeBSD/MIRROR.SITES
-.El
+The ftp site for the distributions is:
+.Lk ftp://ftp.FreeBSD.org/pub/FreeBSD
 .Pp
 This distribution consists of a number of tar-ed and gzipped files,
 Normally, they're controlled by an install program, but you can
--- a/share/man/man9/Makefile	Sun Apr 30 10:27:16 2017 +0000
+++ b/share/man/man9/Makefile	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-#       $NetBSD: Makefile,v 1.409.2.3 2017/04/30 04:56:55 pgoyette Exp $
+#       $NetBSD: Makefile,v 1.409.2.4 2017/05/02 03:19:16 pgoyette Exp $
 
 #	Makefile for section 9 (kernel function and variable) manual pages.
 
@@ -279,7 +279,8 @@
 	ctod.9 btodb.9
 MLINKS+=curproc.9 curcpu.9 curproc.9 curlwp.9
 MLINKS+=delay.9 DELAY.9
-MLINKS+=devsw_attach.9 devsw_detach.9 \
+MLINKS+=devsw_attach.9 devsw.9 \
+	devsw_attach.9 devsw_detach.9 \
 	devsw_attach.9 bdevsw_lookup.9 \
 	devsw_attach.9 cdevsw_lookup.9 \
 	devsw_attach.9 bdevsw_lookup_major.9 \
--- a/share/man/man9/devsw_attach.9	Sun Apr 30 10:27:16 2017 +0000
+++ b/share/man/man9/devsw_attach.9	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-.\"	$NetBSD: devsw_attach.9,v 1.2.6.1 2017/04/27 05:36:31 pgoyette Exp $
+.\"	$NetBSD: devsw_attach.9,v 1.2.6.2 2017/05/02 03:19:16 pgoyette Exp $
 .\"
 .\" Copyright (c) 2015 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,10 +27,11 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 17, 2016
-.Dt DEVSW_ATTACH 9
+.Dd April 30, 2017
+.Dt DEVSW 9
 .Os
 .Sh NAME
+.Nm devsw ,
 .Nm devsw_attach ,
 .Nm devsw_detach ,
 .Nm bdevsw_lookup ,
--- a/share/man/man9/driver.9	Sun Apr 30 10:27:16 2017 +0000
+++ b/share/man/man9/driver.9	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-.\"     $NetBSD: driver.9,v 1.28 2016/07/19 17:01:36 maya Exp $
+.\"     $NetBSD: driver.9,v 1.28.4.1 2017/05/02 03:19:16 pgoyette Exp $
 .\"
 .\" Copyright (c) 2001 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 19, 2016
+.Dd April 30, 2017
 .Dt DRIVER 9
 .Os
 .Sh NAME
@@ -370,4 +370,5 @@
 .Xr config 1 ,
 .Xr autoconf 9 ,
 .Xr config 9 ,
+.Xr devsw 9 ,
 .Xr pmf 9
--- a/share/man/man9/mutex.9	Sun Apr 30 10:27:16 2017 +0000
+++ b/share/man/man9/mutex.9	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-.\"	$NetBSD: mutex.9,v 1.26.16.1 2017/04/30 04:56:55 pgoyette Exp $
+.\"	$NetBSD: mutex.9,v 1.26.16.2 2017/05/02 03:19:16 pgoyette Exp $
 .\"
 .\" Copyright (c) 2007, 2009 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -187,6 +187,9 @@
 .Fn mutex_owned
 does not differentiate if a spin mutex is owned by the current process
 vs owned by another process.
+.Fn mutex_ownable
+is reasonably heavy-weight, and should only be used with
+.Xr KDASSERT 9 .
 .It Fn mutex_owned "mtx"
 .Pp
 For adaptive mutexes, return non-zero if the current LWP holds the mutex.
--- a/sys/arch/amd64/conf/ALL	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/amd64/conf/ALL	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: ALL,v 1.56 2017/04/18 19:09:12 riastradh Exp $
+# $NetBSD: ALL,v 1.56.2.1 2017/05/02 03:19:16 pgoyette Exp $
 # From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
 #
 # ALL machine description file
@@ -17,7 +17,7 @@
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident		"ALL-$Revision: 1.56 $"
+#ident		"ALL-$Revision: 1.56.2.1 $"
 
 maxusers	64		# estimated number of users
 
@@ -41,6 +41,13 @@
 
 options 	PMC	# performance-monitoring counters support
 
+# Beep when it is safe to power down the system (requires sysbeep)
+options 	BEEP_ONHALT
+# Some tunable details of the above feature (default values used below)
+options 	BEEP_ONHALT_COUNT=3	# Times to beep
+options 	BEEP_ONHALT_PITCH=1500	# Default frequency (in Hz)
+options 	BEEP_ONHALT_PERIOD=250	# Default duration (in msecs)
+
 options 	MULTIBOOT	# Multiboot support (see multiboot(8))
 
 # delay between "rebooting ..." message and hardware reset, in milliseconds
@@ -95,13 +102,6 @@
 options 	PIPE_SOCKETPAIR	# smaller, but slower pipe(2)
 options 	SYSCTL_INCLUDE_DESCR	# Include sysctl descriptions in kernel
 
-# Beep when it is safe to power down the system (requires sysbeep)
-options 	BEEP_ONHALT
-# Some tunable details of the above feature (default values used below)
-options 	BEEP_ONHALT_COUNT=3	# Times to beep
-options 	BEEP_ONHALT_PITCH=1500	# Default frequency (in Hz)
-options 	BEEP_ONHALT_PERIOD=250	# Default duration (in msecs)
-
 # Alternate buffer queue strategies for better responsiveness under high
 # disk I/O load.
 options 	BUFQ_READPRIO
@@ -109,9 +109,11 @@
 
 # Diagnostic/debugging support options
 options 	DIAGNOSTIC	# inexpensive kernel consistency checks
+				# XXX to be commented out on release branch
 options 	DEBUG		# expensive debugging checks/support
 options 	LOCKDEBUG	# expensive locking checks/support
 options 	DDB		# in-kernel debugger
+options 	DDB_COMMANDONENTER="bt"	# execute command when ddb is entered
 options 	DDB_ONPANIC=1	# see also sysctl(7): `ddb.onpanic'
 options 	DDB_HISTORY_SIZE=512	# enable history editing in DDB
 options 	DDB_VERBOSE_HELP
@@ -119,6 +121,7 @@
 options 	KGDB_DEVNAME="\"com\"",KGDB_DEVADDR=0x3f8,KGDB_DEVRATE=9600
 #options 	IPKDB		# IP Kernel Debugger
 #options 	IPKDBKEY="\"Pass_phrase_to_debug_over_network\""
+makeoptions	COPTS="-O2 -fno-omit-frame-pointer"
 makeoptions	DEBUG="-g"	# compile full symbol table
 options 	SYSCALL_STATS	# per syscall counts
 options 	SYSCALL_TIMES	# per syscall times
@@ -128,14 +131,15 @@
 options 	BIOHIST		# kernhist for buff I/O
 
 # Compatibility options
-#options 	COMPAT_NOMID	# NetBSD 0.8, 386BSD, and BSDI
-#options 	COMPAT_09	# NetBSD 0.9,
-#options 	COMPAT_10	# NetBSD 1.0,
-#options 	COMPAT_11	# NetBSD 1.1,
-#options 	COMPAT_12	# NetBSD 1.2 (and 386BSD and BSDI),
-#options 	COMPAT_13	# NetBSD 1.3 (and 386BSD and BSDI),
-#options 	COMPAT_14	# NetBSD 1.4,
-#options 	COMPAT_15	# NetBSD 1.5,
+options 	COMPAT_NOMID	# NetBSD 0.8, 386BSD, and BSDI
+options 	EXEC_AOUT	# required by binaries from before 1.5
+options 	COMPAT_09	# NetBSD 0.9,
+options 	COMPAT_10	# NetBSD 1.0,
+options 	COMPAT_11	# NetBSD 1.1,
+options 	COMPAT_12	# NetBSD 1.2 (and 386BSD and BSDI),
+options 	COMPAT_13	# NetBSD 1.3 (and 386BSD and BSDI),
+options 	COMPAT_14	# NetBSD 1.4,
+options 	COMPAT_15	# NetBSD 1.5,
 options 	COMPAT_16	# NetBSD 1.6,
 options 	COMPAT_20	# NetBSD 2.0,
 options 	COMPAT_30	# NetBSD 3.0,
@@ -148,11 +152,11 @@
 options 	COMPAT_386BSD_MBRPART # recognize old partition ID
 options 	TCP_COMPAT_42	# 4.2BSD TCP/IP bug compat. Not recommended.
 
+options 	COMPAT_OSSAUDIO	# OSS (Voxware) audio driver compatibility
 options 	COMPAT_NETBSD32 # NetBSD 32-bit
-options 	COMPAT_OSSAUDIO	# OSS (Voxware) audio driver compatibility
-options 	COMPAT_IBCS2	# binary compatibility with SCO and ISC
 options 	COMPAT_LINUX	# binary compatibility with Linux
 options 	COMPAT_LINUX32	# binary compatibility with Linux 32-bit
+options 	COMPAT_IBCS2	# binary compatibility with SCO and ISC
 options 	COMPAT_FREEBSD	# binary compatibility with FreeBSD
 options 	COMPAT_NDIS	# NDIS network driver
 options 	COMPAT_BSDPTY	# /dev/[pt]ty?? ptys.
@@ -160,8 +164,8 @@
 # Wedge support
 options 	DKWEDGE_AUTODISCOVER	# Automatically add dk(4) instances
 options 	DKWEDGE_METHOD_GPT	# Supports GPT partitions as wedges
-#options 	DKWEDGE_METHOD_BSDLABEL	# Support disklabel entries as wedges
-#options 	DKWEDGE_METHOD_MBR	# Support MBR partitions as wedges
+options 	DKWEDGE_METHOD_BSDLABEL	# Support disklabel entries as wedges
+options 	DKWEDGE_METHOD_MBR	# Support MBR partitions as wedges
 options 	DKWEDGE_METHOD_APPLE	# Support Apple partitions as wedges
 options 	DKWEDGE_METHOD_RDB	# Support RDB partitions as wedges
 
@@ -308,8 +312,6 @@
 options 	VGA_CONSOLE_SCREENTYPE="\"80x24\""
 # work around a hardware bug that loaded fonts don't work; found on ATI cards
 options 	VGA_CONSOLE_ATI_BROKEN_FONTSEL
-# issue VGA BIOS POST on resume
-options 	VGA_POST
 # console scrolling support.
 options 	WSDISPLAY_SCROLLSUPPORT
 # enable VGA raster mode capable of displaying multilingual text on console
@@ -348,13 +350,17 @@
 
 # This option can be used to retrieve CPU and APIC information.
 # that I/O APICs can be used if ACPI is enabled below.
-options 	MPBIOS_SCANPCI	# find PCI roots using MPBIOS
-options 	ACPI_SCANPCI	# find PCI roots using ACPI
+options 	ACPI_SCANPCI		# find PCI roots using ACPI
+options 	MPBIOS			# configure CPUs and APICs using MPBIOS
+options 	MPBIOS_SCANPCI		# MPBIOS configures PCI roots
+options 	PCI_INTR_FIXUP		# PCI interrupt routing via ACPI
+options 	PCI_BUS_FIXUP		# fixup PCI bus numbering
+options 	PCI_ADDR_FIXUP		# fixup PCI I/O addresses
+options 	ACPI_ACTIVATE_DEV	# If set, activate inactive devices
+options 	VGA_POST		# in-kernel support for VGA POST
 
 acpi0		at mainbus0
 
-options 	ACPI_ACTIVATE_DEV	# If set, activate inactive devices
-
 # ACPI devices
 apm*		at acpi?		# ACPI apm emulation
 acpiacad*	at acpi?		# ACPI AC Adapter
@@ -394,11 +400,18 @@
 mpu*		at acpi?		# Roland MPU-401 MIDI UART
 pckbc*		at acpi?		# PC keyboard controller
 pcppi*		at acpi?		# AT-style speaker sound
+sdhc*		at acpi?		# SD Host Controller
+sony*		at acpi?		# Sony Notebook Controller
+spic*		at acpi?		# Sony Programmable I/O Controller
+wsmouse*	at spic?		# mouse
 thinkpad*	at acpi?		# IBM/Lenovo Thinkpad hotkeys
-#tpm*		at acpi?		# ACPI TPM (Experimental)
+tpm*		at acpi?		# ACPI TPM (Experimental)
 ug*		at acpi?		# Abit uGuru Hardware monitor
+valz*		at acpi?		# Toshiba Dynabook hotkeys
 wb*		at acpi?		# Winbond W83L518D SD/MMC reader
 sdmmc*		at wb?			# SD/MMC bus
+sdhc*		at acpi?		# SD Host Controller
+sony*		at acpi?		# Sony Notebook Controller
 wmidell*	at acpiwmibus?		# Dell WMI mappings
 wmieeepc*	at acpiwmibus?		# Asus Eee PC WMI mappings
 wmihp*		at acpiwmibus?		# HP WMI mappings
@@ -406,16 +419,6 @@
 wss*		at acpi?		# NeoMagic 256AV in wss mode
 ym*		at acpi?		# Yamaha OPL3-SA[23] audio
 
-# Sony Vaio jog dial
-spic*		at acpi?		# Sony Programmable I/O Controller
-wsmouse*	at spic?
-
-# Sony LCD brightness etc.
-sony*		at acpi?		# Sony Miscellaneous Controller
-
-# Toshiba Libretto devices
-vald* at acpi?
-
 # Apple System Management Controller devices
 applesmcfan*	at applesmcbus?
 applesmctemp*	at applesmcbus?
@@ -438,23 +441,11 @@
 					# on anything else.
 #options 	PCIINTR_DEBUG		# super-verbose PCI interrupt fixup
 
-# PCI fixups, for both PCIBIOS and ACPI
-options 	PCI_ADDR_FIXUP		# fixup PCI I/O addresses
-options 	PCI_BUS_FIXUP		# fixup PCI bus numbering
-options 	PCI_INTR_FIXUP		# fixup PCI interrupt routing
-
 # Temperatures
 amdnb_misc* at pci?			# AMD NB Misc Configuration
 amdtemp* at amdnb_misc? 		# AMD CPU Temperature sensors
 
 # PCI bridges
-amdpcib* at pci? dev ? function ?	# AMD 8111 PCI-ISA w/ HPET
-hpet*	at amdpcib?
-ichlpcib* at pci? dev ? function ?	# Intel ICH PCI-ISA w/ timecounter,
-					# watchdog, gpio, SpeedStep and HPET
-hpet0	at ichlpcib?			# High Precision Event Timer
-fwhrng* at ichlpcib?			# Intel 82802 FWH Random Number Generator
-tco*	at ichlpcib?			# TCO watchdog timer
 rdcpcib* at pci? dev ? function ?	# RDC Vortex86/PMX-1000 PCI-ISA w/
 pchb*	at pci? dev ? function ?	# PCI-Host bridges
 options 	AGP_X86
@@ -463,17 +454,28 @@
 # XXX 'puc's aren't really bridges, but there's no better place for them here
 puc*	at pci? dev ? function ?	# PCI "universal" comm. cards
 
+amdpcib* at pci? dev ? function ?	# AMD 8111 PCI-ISA w/ HPET
+hpet*	at amdpcib?
+
 pwdog*	at pci? dev ? function ?	# QUANCOM PWDOG1
 
+ichlpcib* at pci? dev ? function ?	# Intel ICH PCI-LPC w/ timecounter,
+					# watchdog, gpio, Speedstep and HPET
+fwhrng* at ichlpcib?		# Intel 82802 FWH Random Number Generator
+hpet*	at ichlpcib?
+tco*	at ichlpcib?		# TCO watch dog timer
+
+aapic*	at pci? dev ? function ?	# AMD 8131 IO apic
+
 agp*	at pchb?
 
-
 # ISA bus support
+isa0	at mainbus?
+isa0	at pcib?
 isa0	at amdpcib?
 isa0	at ichlpcib?
 isa0	at rdcpcib?
-isa0	at mainbus?
-isa0	at pcib?
+isa0	at rdcpcib?
 
 # IBM 4810 BSP cash drawer port
 ibmcd*	at pci? dev ? function ?
@@ -499,6 +501,10 @@
 options 	PMS_ELANTECH_TOUCHPAD	# Enable support for Elantech Touchpads
 vga0		at isa?
 vga*		at pci? dev ? function ?
+genfb*		at pci? dev ? function ?
+options 	VCONS_DRAW_INTR
+wsdisplay*	at vga? console ?
+wsdisplay*	at wsemuldisplaydev?
 pcdisplay0	at isa?			# CGA, MDA, EGA, HGA
 wskbd*		at pckbd? console ?
 wsmouse*	at pms? mux 0
@@ -515,7 +521,6 @@
 unichromefb*	at pci? dev ? function ?	# VIA Unichrome framebuffer console
 voodoofb*	at pci? dev ? function ?
 wcfb*	at pci? dev ? function ?
-wsdisplay*	at wsemuldisplaydev?
 
 # DRI legacy drivers
 #i915drm*	at drm?		# Intel i915, i945 DRM driver
@@ -598,6 +603,28 @@
 
 # Hardware monitors
 
+amdnb_misc* at pci?			# AMD NB Misc Configuration
+amdtemp* at amdnb_misc?  		# AMD CPU Temperature sensors
+
+# Winbond LPC Super I/O
+wbsio*	at isa? port 0x2e
+wbsio*	at isa? port 0x4e
+
+# IBM Hawk Integrated Systems Management Processor
+ibmhawk0	at iic? addr 0x37
+
+# LM7[89] and compatible hardware monitors
+# Use flags to select temp sensor type (see lm(4) man page for details)
+lm0	at isa?	port 0x290 flags 0x0	# other common ports: 0x280, 0x310
+lm*	at wbsio?
+
+# SMSC LPC47B397 hardware monitor functions
+smsc0	at isa? port 0x02e
+
+# SMSC LPC47M192 hardware monitor
+smscmon*	at iic? addr 0x2c
+smscmon*	at iic? addr 0x2d	# (alternate address)
+
 # AMD 768 and 8111 power/ACPI controllers
 amdpm*	at pci? dev ? function ?	# RNG and SMBus 1.0 interface
 iic*	at amdpm?			# sensors below are on this bus
@@ -707,6 +734,9 @@
 # Keylock support
 gpiolock*	at gpio?
 
+# Pulsing GPIO pins in software
+gpiopwm*	at gpio?
+
 # Soekris 6501 GPIO/LED driver (provides gpiobus, needs gpio)
 soekrisgpio0	at isa? port 0x680
 
@@ -907,9 +937,9 @@
 
 # PCI network interfaces
 age*	at pci? dev ? function ?	# Attansic/Atheros L1 Gigabit Ethernet
-an*	at pci? dev ? function ?	# Aironet PC4500/PC4800 (802.11)
 alc*	at pci? dev ? function ?	# Attansic/Atheros L1C/L2C Ethernet
 ale*	at pci? dev ? function ?	# Attansic/Atheros L1E Ethernet
+an*	at pci? dev ? function ?	# Aironet PC4500/PC4800 (802.11)
 ath*	at pci? dev ? function ?	# Atheros 5210/5211/5212 802.11
 athn*	at pci? dev ? function ?	# Atheros AR9k (802.11a/g/n)
 atw*	at pci? dev ? function ?	# ADMtek ADM8211 (802.11)
@@ -935,7 +965,9 @@
 iwm*	at pci? dev ? function ?	# Intel Wireless WiFi Link 7xxx
 iwn*	at pci? dev ? function ?	# Intel PRO/Wireless 4965AGN
 ixg*	at pci? dev ? function ?	# Intel 8259x 10 gigabit
-jme*	at pci? dev ? function ?	# JMicron JMC2[56]0 Ethernet
+ixv*	at pci? dev ? function ?	# Intel 8259x 10G virtual function
+jme*	at pci? dev ? function ?	# JMicron JMC2[56]0 ethernet
+hme*	at pci? dev ? function ?	# Sun Microelectronics STP2002-STQ
 le*	at pci? dev ? function ?	# PCnet-PCI Ethernet
 lii*	at pci? dev ? function ?	# Atheros L2 Fast-Ethernet
 lmc*	at pci? dev ? function ?	# Lan Media Corp SSI/HSSI/DS3
@@ -952,6 +984,7 @@
 re*	at pci? dev ? function ?	# Realtek 8139C+/8169/8169S/8110S
 rtk*	at pci? dev ? function ?	# Realtek 8129/8139
 rtw*	at pci? dev ? function ?	# Realtek 8180L (802.11)
+rtwn*	at pci? dev ? function ?	# Realtek 8188CE/8192CE 802.11b/g/n
 sf*	at pci? dev ? function ?	# Adaptec AIC-6915 Ethernet
 sip*	at pci? dev ? function ?	# SiS 900/DP83815 Ethernet
 skc*	at pci? dev ? function ?	# SysKonnect SK9821 Gigabit Ethernet
@@ -1071,6 +1104,8 @@
 # USB Controller and Devices
 
 # PCI USB controllers
+xhci*	at pci?	dev ? function ?	# eXtensible Host Controller
+					# xhci is at best experimental
 ehci*	at pci?	dev ? function ?	# Enhanced Host Controller
 ohci*	at pci?	dev ? function ?	# Open Host Controller
 uhci*	at pci?	dev ? function ?	# Universal Host Controller (Intel)
@@ -1088,6 +1123,7 @@
 slhci*	at pcmcia? function ?		# ScanLogic SL811HS
 
 # USB bus support
+usb*	at xhci?
 usb*	at ehci?
 usb*	at ohci?
 usb*	at slhci?
@@ -1179,9 +1215,11 @@
 # USB Ethernet adapters
 aue*	at uhub? port ?		# ADMtek AN986 Pegasus based adapters
 axe*	at uhub? port ?		# ASIX AX88172 based adapters
+axen*	at uhub? port ?		# ASIX AX88178a/AX88179 based adapters
 cdce*	at uhub? port ?		# CDC, Ethernet Networking Control Model
 cue*	at uhub? port ?		# CATC USB-EL1201A based adapters
 kue*	at uhub? port ?		# Kawasaki LSI KL5KUSB101B based adapters
+#mos*	at uhub? port ?		# Moschip MCS7730/MCS7830/MCS7832 based adapters
 udav*	at uhub? port ?		# Davicom DM9601 based adapters
 url*	at uhub? port ?		# Realtek RTL8150L based adapters
 urndis* at uhub? port ? 	# Microsoft RNDIS specification
@@ -1411,10 +1449,14 @@
 
 # Video capture devices
 
-pseye*	at uhub?		# Sony PLAYSTATION(R) Eye webcam
-uvideo* at uhub?		# USB Video Class capture devices
-auvitek* at uhub?		# Auvitek AU0828 video capture devices
-emdtv*	at uhub?		# Empia EM28xx video capture devices
+auvitek* at uhub?			# Auvitek AU0828 USB TV
+coram*	at pci? dev ? function ?	# Conexant CX23885 PCI-E TV
+cxdtv*	at pci? dev ? function ?	# Conexant CX2388[0-3] PCI TV
+emdtv*	at uhub?			# Empia EM28xx USB TV
+cir*	at emdtv?
+pseye*	at uhub?			# Sony PLAYSTATION(R) Eye webcam
+uvideo* at uhub?			# USB Video Class capture devices
+
 video*	at videobus?
 dtv*	at dtvbus?
 
@@ -1514,6 +1556,8 @@
 viomb*	at virtio?			# Virtio memory balloon device
 ld*	at virtio?			# Virtio disk device
 vioif*	at virtio?			# Virtio network device
+viornd* at virtio?			# Virtio entropy device
+vioscsi* at virtio?			# Virtio SCSI device
 
 # Flash subsystem
 flash* at flashbus?
@@ -1659,9 +1703,11 @@
 options 	VERIFIED_EXEC_FP_SHA1
 options 	VERIFIED_EXEC_FP_MD5
 
-options 	PAX_MPROTECT=0		# PaX mprotect(2) restrictions
-options 	PAX_ASLR=0		# PaX Address Space Layout Randomization
-#options 	PAX_SEGVGUARD=0		# PaX Segmentation fault guard
+options 	PAX_SEGVGUARD=0		# PaX Segmentation fault guard
+options 	PAX_MPROTECT=1		# PaX mprotect(2) restrictions
+options 	PAX_MPROTECT_DEBUG=1	# PaX mprotect debug
+options 	PAX_ASLR=1		# PaX Address Space Layout Randomization
+options 	PAX_ASLR_DEBUG=1	# PaX ASLR debug
 
 #
 # NetBSD: GENERIC_ISDN,v 1.16 2010/01/03 03:53:34 dholland Exp
--- a/sys/arch/arm/nvidia/files.tegra	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/arm/nvidia/files.tegra	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-#	$NetBSD: files.tegra,v 1.33 2017/04/23 12:31:38 jmcneill Exp $
+#	$NetBSD: files.tegra,v 1.33.2.1 2017/05/02 03:19:16 pgoyette Exp $
 #
 # Configuration info for NVIDIA Tegra ARM Peripherals
 #
@@ -67,6 +67,11 @@
 attach	tegrampio at fdt with tegra_mpio
 file	arch/arm/nvidia/tegra_mpio.c		tegra_mpio
 
+# APB DMA
+device	tegraapbdma
+attach	tegraapbdma at fdt with tegra_apbdma
+file	arch/arm/nvidia/tegra_apbdma.c		tegra_apbdma
+
 # XUSB PADCTL
 device	tegraxusbpad
 attach	tegraxusbpad at fdt with tegra_xusbpad
@@ -99,6 +104,7 @@
 # XUSB (USB 3.0)
 attach	xhci at fdt with tegra_xusb
 file	arch/arm/nvidia/tegra_xusb.c		tegra_xusb
+defflag	opt_tegra.h				TEGRA_XUSB_DEBUG
 
 # SDMMC
 attach	sdhc at fdt with tegra_sdhc
--- a/sys/arch/arm/nvidia/tegra124_car.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/arm/nvidia/tegra124_car.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra124_car.c,v 1.12 2017/04/26 01:43:00 jmcneill Exp $ */
+/* $NetBSD: tegra124_car.c,v 1.12.2.1 2017/05/02 03:19:16 pgoyette Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.12 2017/04/26 01:43:00 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.12.2.1 2017/05/02 03:19:16 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -635,6 +635,7 @@
 	CLK_GATE_U("xusb_host", "xusb_host_src", CAR_DEV_U_XUSB_HOST),
 	CLK_GATE_W("xusb_ss", "xusb_ss_src", CAR_DEV_W_XUSB_SS),
 	CLK_GATE_X("gpu", "pll_ref", CAR_DEV_X_GPU),
+	CLK_GATE_H("apbdma", "clk_m", CAR_DEV_H_APBDMA),
 };
 
 struct tegra124_init_parent {
--- a/sys/arch/arm/nvidia/tegra124_cpu.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/arm/nvidia/tegra124_cpu.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra124_cpu.c,v 1.1 2017/04/23 12:31:38 jmcneill Exp $ */
+/* $NetBSD: tegra124_cpu.c,v 1.1.4.1 2017/05/02 03:19:16 pgoyette Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -30,7 +30,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra124_cpu.c,v 1.1 2017/04/23 12:31:38 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra124_cpu.c,v 1.1.4.1 2017/05/02 03:19:16 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -88,15 +88,15 @@
 	u_int divp;
 	u_int uvol;
 } tegra124_cpufreq_rates[] = {
-	{ 2316, 1, 193, 0, 1400000 },
-	{ 2100, 1, 175, 0, 1400000 },
-	{ 1896, 1, 158, 0, 1400000 },
-	{ 1692, 1, 141, 0, 1400000 },
-	{ 1500, 1, 125, 0, 1400000 },
-	{ 1296, 1, 108, 0, 1400000 },
-	{ 1092, 1, 91,  0, 1400000 },
-	{ 900,  1, 75,  0, 1400000 },
-	{ 696,  1, 58,  0, 1400000 }
+	{ 2316, 1, 193, 0, 1360000 },
+	{ 2100, 1, 175, 0, 1260000 },
+	{ 1896, 1, 158, 0, 1180000 },
+	{ 1692, 1, 141, 0, 1100000 },
+	{ 1500, 1, 125, 0, 1020000 },
+	{ 1296, 1, 108, 0, 960000 },
+	{ 1092, 1, 91,  0, 900000 },
+	{ 900,  1, 75,  0, 840000 },
+	{ 696,  1, 58,  0, 800000 }
 };
 
 static const u_int tegra124_cpufreq_max[] = {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/nvidia/tegra_apbdma.c	Tue May 02 03:19:14 2017 +0000
@@ -0,0 +1,487 @@
+/* $NetBSD: tegra_apbdma.c,v 1.1.2.2 2017/05/02 03:19:16 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2017 Jared D. McNeill <jmcneill@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: tegra_apbdma.c,v 1.1.2.2 2017/05/02 03:19:16 pgoyette Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <arm/nvidia/tegra_reg.h>
+#include <arm/nvidia/tegra_apbdmareg.h>
+#include <arm/nvidia/tegra_var.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#define	TEGRA_APBDMA_NCHAN	32
+
+static void *	tegra_apbdma_acquire(device_t, const void *, size_t,
+				     void (*)(void *), void *);
+static void	tegra_apbdma_release(device_t, void *);
+static int	tegra_apbdma_transfer(device_t, void *,
+				      struct fdtbus_dma_req *);
+static void	tegra_apbdma_halt(device_t, void *);
+
+static const struct fdtbus_dma_controller_func tegra_apbdma_funcs = {
+	.acquire = tegra_apbdma_acquire,
+	.release = tegra_apbdma_release,
+	.transfer = tegra_apbdma_transfer,
+	.halt = tegra_apbdma_halt
+};
+
+static int	tegra_apbdma_match(device_t, cfdata_t, void *);
+static void	tegra_apbdma_attach(device_t, device_t, void *);
+
+static int	tegra_apbdma_intr(void *);
+
+struct tegra_apbdma_softc;
+
+struct tegra_apbdma_chan {
+	struct tegra_apbdma_softc *ch_sc;
+	u_int			ch_n;
+	void			*ch_ih;
+	void			(*ch_cb)(void *);
+	void			*ch_cbarg;
+};
+
+struct tegra_apbdma_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	int			sc_phandle;
+
+	struct tegra_apbdma_chan sc_chan[TEGRA_APBDMA_NCHAN];
+};
+
+CFATTACH_DECL_NEW(tegra_apbdma, sizeof(struct tegra_apbdma_softc),
+	tegra_apbdma_match, tegra_apbdma_attach, NULL, NULL);
+
+#define	APBDMA_READ(sc, reg)						\
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define	APBDMA_WRITE(sc, reg, val)					\
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+
+static int
+tegra_apbdma_match(device_t parent, cfdata_t cf, void *aux)
+{
+	const char * const compatible[] = { "nvidia,tegra124-apbdma", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+tegra_apbdma_attach(device_t parent, device_t self, void *aux)
+{
+	struct tegra_apbdma_softc *sc = device_private(self);
+	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
+	struct fdtbus_reset *rst;
+	struct clk *clk;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+	u_int n;
+
+	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	clk = fdtbus_clock_get_index(phandle, 0);
+	if (clk == NULL) {
+		aprint_error(": couldn't get clock\n");
+		return;
+	}
+	rst = fdtbus_reset_get(phandle, "dma");
+	if (rst == NULL) {
+		aprint_error(": couldn't get reset dma\n");
+		return;
+	}
+
+	fdtbus_reset_assert(rst);
+	error = clk_enable(clk);
+	if (error) {
+		aprint_error(": couldn't enable clock dma: %d\n", error);
+		return;
+	}
+	fdtbus_reset_deassert(rst);
+
+	sc->sc_dev = self;
+	sc->sc_bst = faa->faa_bst;
+	sc->sc_phandle = phandle;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
+	for (n = 0; n < TEGRA_APBDMA_NCHAN; n++) {
+		sc->sc_chan[n].ch_sc = sc;
+		sc->sc_chan[n].ch_n = n;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": APBDMA\n");
+
+	/* Stop all channels */
+	for (n = 0; n < TEGRA_APBDMA_NCHAN; n++)
+		APBDMA_WRITE(sc, APBDMACHAN_CSR_REG(n), 0);
+
+	/* Mask interrupts */
+	APBDMA_WRITE(sc, APBDMA_IRQ_MASK_REG, 0);
+
+	/* Global enable */
+	APBDMA_WRITE(sc, APBDMA_COMMAND_REG, APBDMA_COMMAND_GEN);
+
+	fdtbus_register_dma_controller(self, phandle, &tegra_apbdma_funcs);
+}
+
+static int
+tegra_apbdma_intr(void *priv)
+{
+	struct tegra_apbdma_chan *ch = priv;
+	struct tegra_apbdma_softc *sc = ch->ch_sc;
+	const u_int n = ch->ch_n;
+	uint32_t sta;
+
+	sta = APBDMA_READ(sc, APBDMACHAN_STA_REG(n));
+	APBDMA_WRITE(sc, APBDMACHAN_STA_REG(n), sta);	/* clear EOC */
+
+	ch->ch_cb(ch->ch_cbarg);
+
+	return 1;
+}
+
+static void *
+tegra_apbdma_acquire(device_t dev, const void *data, size_t len,
+    void (*cb)(void *), void *cbarg)
+{
+	struct tegra_apbdma_softc *sc = device_private(dev);
+	struct tegra_apbdma_chan *ch;
+	char intrstr[128];
+
+	if (len != 1)
+		return NULL;
+
+	const u_int n = be32dec(data);
+	if (n >= TEGRA_APBDMA_NCHAN)
+		return NULL;
+
+	ch = &sc->sc_chan[n];
+	if (ch->ch_ih != NULL) {
+		aprint_error_dev(dev, "dma channel %u is in use\n", n);
+		return NULL;
+	}
+
+	if (!fdtbus_intr_str(sc->sc_phandle, n, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(dev, "failed to decode interrupt %u\n", n);
+		return NULL;
+	}
+
+	ch->ch_ih = fdtbus_intr_establish(sc->sc_phandle, n, IPL_VM,
+	    FDT_INTR_MPSAFE, tegra_apbdma_intr, ch);
+	if (ch->ch_ih == NULL) {
+		aprint_error_dev(dev, "failed to establish interrupt on %s\n",
+		    intrstr);
+		return NULL;
+	}
+	aprint_normal_dev(dev, "interrupting on %s (channel %u)\n", intrstr, n);
+
+	ch->ch_cb = cb;
+	ch->ch_cbarg = cbarg;
+
+	/* Unmask interrupts for this channel */
+	APBDMA_WRITE(sc, APBDMA_IRQ_MASK_SET_REG, __BIT(n));
+
+	return ch;
+}
+static void
+tegra_apbdma_release(device_t dev, void *priv)
+{
+	struct tegra_apbdma_softc *sc = device_private(dev);
+	struct tegra_apbdma_chan *ch = priv;
+	const u_int n = ch->ch_n;
+
+	KASSERT(ch->ch_ih != NULL);
+
+	/* Halt the channel */
+	APBDMA_WRITE(sc, APBDMACHAN_CSR_REG(n), 0);
+
+	/* Mask interrupts for this channel */
+	APBDMA_WRITE(sc, APBDMA_IRQ_MASK_CLR_REG, __BIT(n));
+
+	fdtbus_intr_disestablish(sc->sc_phandle, ch->ch_ih);
+
+	ch->ch_cb = NULL;
+	ch->ch_cbarg = NULL;
+}
+
+static int
+tegra_apbdma_transfer(device_t dev, void *priv, struct fdtbus_dma_req *req)
+    
+{
+	struct tegra_apbdma_softc *sc = device_private(dev);
+	struct tegra_apbdma_chan *ch = priv;
+	const u_int n = ch->ch_n;
+	uint32_t csr = 0;
+	uint32_t csre = 0;
+	uint32_t ahb_seq = 0;
+	uint32_t apb_seq = 0;
+
+	/* Scatter-gather not supported */
+	if (req->dreq_nsegs != 1)
+		return EINVAL;
+
+	/* Addresses must be aligned to 32-bits */
+	if ((req->dreq_segs[0].ds_addr & 3) != 0 ||
+	    (req->dreq_dev_phys & 3) != 0)
+		return EINVAL;
+
+	/* Length must be a multiple of 32-bits */
+	if ((req->dreq_segs[0].ds_len & 3) != 0)
+		return EINVAL;
+
+	/* REQ_SEL is between 0 and 31 */
+	if (req->dreq_sel < 0 || req->dreq_sel > 31)
+		return EINVAL;
+
+	csr |= __SHIFTIN(req->dreq_sel, APBDMACHAN_CSR_REQ_SEL);
+
+	/*
+	 * Set DMA transfer direction.
+	 * APBDMACHAN_CSR_DIR=0 means "APB read to AHB write", and
+	 * APBDMACHAN_CSR_DIR=1 means "AHB read to APB write".
+	 */
+	if (req->dreq_dir == FDT_DMA_WRITE)
+		csr |= APBDMACHAN_CSR_DIR; 
+
+	/*
+	 * Generate interrupt when DMA block transfer completes.
+	 */
+	if (req->dreq_block_irq)
+		csr |= APBDMACHAN_CSR_IE_EOC;
+
+	/*
+	 * Single or multiple block transfer
+	 */
+	if (!req->dreq_block_multi)
+		csr |= APBDMACHAN_CSR_ONCE;
+
+	/*
+	 * Flow control enable
+	 */
+	if (req->dreq_flow)
+		csr |= APBDMACHAN_CSR_FLOW;
+
+	/*
+	 * Route interrupt to CPU. 1 = CPU, 0 = COP
+	 */
+	ahb_seq |= APBDMACHAN_AHB_SEQ_INTR_ENB;
+
+	/*
+	 * AHB is a 32-bit bus.
+	 */
+	if (req->dreq_mem_opt.opt_bus_width != 32)
+		return EINVAL;
+	ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_BUS_WIDTH_32,
+			     APBDMACHAN_AHB_SEQ_BUS_WIDTH);
+
+	/*
+	 * AHB data swap.
+	 */
+	if (req->dreq_mem_opt.opt_swap)
+		ahb_seq |= APBDMACHAN_AHB_SEQ_DATA_SWAP;
+
+	/*
+	 * AHB burst size.
+	 */
+	switch (req->dreq_mem_opt.opt_burst_len) {
+	case 32:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_BURST_1,
+				     APBDMACHAN_AHB_SEQ_BURST);
+		break;
+	case 128:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_BURST_4,
+				     APBDMACHAN_AHB_SEQ_BURST);
+		break;
+	case 256:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_BURST_8,
+				     APBDMACHAN_AHB_SEQ_BURST);
+		break;
+	default:
+		return EINVAL;
+	}
+
+	/*
+	 * 2X double buffering mode. Only supported in run-multiple mode
+	 * with no-wrap operations.
+	 */
+	if (req->dreq_mem_opt.opt_dblbuf) {
+		if (req->dreq_mem_opt.opt_wrap_len != 0)
+			return EINVAL;
+		if (!req->dreq_block_multi)
+			return EINVAL;
+		ahb_seq |= APBDMACHAN_AHB_SEQ_DBL_BUF;
+	}
+
+	/*
+	 * AHB address wrap.
+	 */
+	switch (req->dreq_mem_opt.opt_wrap_len) {
+	case 0:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_WRAP_NO_WRAP,
+				     APBDMACHAN_AHB_SEQ_WRAP);
+		break;
+	case 128:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_WRAP_32,
+				     APBDMACHAN_AHB_SEQ_WRAP);
+		break;
+	case 256:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_WRAP_64,
+				     APBDMACHAN_AHB_SEQ_WRAP);
+		break;
+	case 512:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_WRAP_128,
+				     APBDMACHAN_AHB_SEQ_WRAP);
+		break;
+	case 1024:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_WRAP_256,
+				     APBDMACHAN_AHB_SEQ_WRAP);
+		break;
+	case 2048:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_WRAP_512,
+				     APBDMACHAN_AHB_SEQ_WRAP);
+		break;
+	case 4096:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_WRAP_1024,
+				     APBDMACHAN_AHB_SEQ_WRAP);
+		break;
+	case 8192:
+		ahb_seq |= __SHIFTIN(APBDMACHAN_AHB_SEQ_WRAP_2048,
+				     APBDMACHAN_AHB_SEQ_WRAP);
+		break;
+	default:
+		return EINVAL;
+	}
+
+	/*
+	 * APB bus width.
+	 */
+	switch (req->dreq_dev_opt.opt_bus_width) {
+	case 8:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_BUS_WIDTH_8,
+				     APBDMACHAN_APB_SEQ_BUS_WIDTH);
+		break;
+	case 16:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_BUS_WIDTH_16,
+				     APBDMACHAN_APB_SEQ_BUS_WIDTH);
+		break;
+	case 32:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_BUS_WIDTH_32,
+				     APBDMACHAN_APB_SEQ_BUS_WIDTH);
+		break;
+	default:
+		return EINVAL;
+	}
+
+	/*
+	 * APB data swap.
+	 */
+	if (req->dreq_dev_opt.opt_swap)
+		apb_seq |= APBDMACHAN_APB_SEQ_DATA_SWAP;
+
+	/*
+	 * APB address wrap-around window.
+	 */
+	switch (req->dreq_dev_opt.opt_wrap_len) {
+	case 0:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_WRAP_NO_WRAP,
+				     APBDMACHAN_APB_SEQ_WRAP);
+		break;
+	case 4:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_WRAP_1,
+				     APBDMACHAN_APB_SEQ_WRAP);
+		break;
+	case 8:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_WRAP_2,
+				     APBDMACHAN_APB_SEQ_WRAP);
+		break;
+	case 16:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_WRAP_4,
+				     APBDMACHAN_APB_SEQ_WRAP);
+		break;
+	case 32:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_WRAP_8,
+				     APBDMACHAN_APB_SEQ_WRAP);
+		break;
+	case 64:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_WRAP_16,
+				     APBDMACHAN_APB_SEQ_WRAP);
+		break;
+	case 128:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_WRAP_32,
+				     APBDMACHAN_APB_SEQ_WRAP);
+		break;
+	case 256:
+		apb_seq |= __SHIFTIN(APBDMACHAN_APB_SEQ_WRAP_64,
+				     APBDMACHAN_APB_SEQ_WRAP);
+		break;
+	default:
+		return EINVAL;
+	}
+
+	/*
+	 * Program all channel registers before setting the channel enable bit.
+	 */
+	APBDMA_WRITE(sc, APBDMACHAN_AHB_PTR_REG(n), req->dreq_segs[0].ds_addr);
+	APBDMA_WRITE(sc, APBDMACHAN_APB_PTR_REG(n), req->dreq_dev_phys);
+	APBDMA_WRITE(sc, APBDMACHAN_AHB_SEQ_REG(n), ahb_seq);
+	APBDMA_WRITE(sc, APBDMACHAN_APB_SEQ_REG(n), apb_seq);
+	APBDMA_WRITE(sc, APBDMACHAN_WCOUNT_REG(n), req->dreq_segs[0].ds_len);
+	APBDMA_WRITE(sc, APBDMACHAN_CSRE_REG(n), csre);
+	APBDMA_WRITE(sc, APBDMACHAN_CSR_REG(n), csr | APBDMACHAN_CSR_ENB);
+
+	return 0;
+}
+
+static void
+tegra_apbdma_halt(device_t dev, void *priv)
+{
+	struct tegra_apbdma_softc *sc = device_private(dev);
+	struct tegra_apbdma_chan *ch = priv;
+	const u_int n = ch->ch_n;
+	uint32_t v;
+
+	v = APBDMA_READ(sc, APBDMACHAN_CSR_REG(n));
+	v &= ~APBDMACHAN_CSR_ENB;
+	APBDMA_WRITE(sc, APBDMACHAN_CSR_REG(n), v);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/nvidia/tegra_apbdmareg.h	Tue May 02 03:19:14 2017 +0000
@@ -0,0 +1,111 @@
+/* $NetBSD: tegra_apbdmareg.h,v 1.2.2.2 2017/05/02 03:19:16 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2017 Jared D. McNeill <jmcneill@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ARM_TEGRA_APBDMAREG_H
+#define _ARM_TEGRA_APBDMAREG_H
+
+/*
+ * APB DMA registers
+ */
+#define	APBDMA_COMMAND_REG		0x00
+#define	 APBDMA_COMMAND_GEN		__BIT(31)
+#define	APBDMA_STATUS_REG		0x04
+#define	APBDMA_CNTRL_REG		0x10
+#define	APBDMA_IRQ_STA_CPU_REG		0x14
+#define	APBDMA_IRQ_STA_COP_REG		0x18
+#define	APBDMA_IRQ_MASK_REG		0x1c
+#define	APBDMA_IRQ_MASK_SET_REG		0x20
+#define	APBDMA_IRQ_MASK_CLR_REG		0x24
+#define	APBDMA_TRIG_REG			0x28
+#define	APBDMA_CHANNEL_TRIG_REG		0x2c
+#define	APBDMA_DMA_STATUS_REG		0x30
+#define	APBDMA_CHANNEL_EN_REG		0x34
+#define	APBDMA_SECURITY_REG		0x38
+#define	APBDMA_CHANNEL_SWID_REG		0x3c
+#define	APBDMA_CHAN_WT_0_REG		0x44
+#define	APBDMA_CHAN_WT_1_REG		0x48
+#define	APBDMA_CHAN_WT_2_REG		0x4c
+#define	APBDMA_CHAN_WT_3_REG		0x50
+#define	APBDMA_CHANNEL_SWID1_REG	0x54
+
+/*
+ * APB DMA channel registers
+ */
+#define	APBDMACHAN_CSR_REG(n)		(0x1000 + ((n) * 0x40))
+#define	 APBDMACHAN_CSR_ENB		__BIT(31)
+#define	 APBDMACHAN_CSR_IE_EOC		__BIT(30)
+#define	 APBDMACHAN_CSR_HOLD		__BIT(29)
+#define	 APBDMACHAN_CSR_DIR		__BIT(28)
+#define	 APBDMACHAN_CSR_ONCE		__BIT(27)
+#define	 APBDMACHAN_CSR_FLOW		__BIT(21)
+#define	 APBDMACHAN_CSR_REQ_SEL		__BITS(20,16)
+#define	APBDMACHAN_STA_REG(n)		(0x1004 + ((n) * 0x40))
+#define	APBDMACHAN_DMA_BYTE_STA_REG(n)	(0x1008 + ((n) * 0x40))
+#define	APBDMACHAN_CSRE_REG(n)		(0x100c + ((n) * 0x40))
+#define	APBDMACHAN_AHB_PTR_REG(n)	(0x1010 + ((n) * 0x40))
+#define	 APBDMACHAN_AHB_PTR_MASK	__BITS(31,2)
+#define	APBDMACHAN_AHB_SEQ_REG(n)	(0x1014 + ((n) * 0x40))
+#define	 APBDMACHAN_AHB_SEQ_INTR_ENB	__BIT(31)
+#define	 APBDMACHAN_AHB_SEQ_BUS_WIDTH	__BITS(30,28)
+#define	  APBDMACHAN_AHB_SEQ_BUS_WIDTH_32	2
+#define	 APBDMACHAN_AHB_SEQ_DATA_SWAP	__BIT(27)
+#define	 APBDMACHAN_AHB_SEQ_BURST	__BITS(26,24)
+#define	  APBDMACHAN_AHB_SEQ_BURST_1		4
+#define	  APBDMACHAN_AHB_SEQ_BURST_4		5
+#define	  APBDMACHAN_AHB_SEQ_BURST_8		6
+#define	 APBDMACHAN_AHB_SEQ_DBL_BUF	__BIT(19)
+#define	 APBDMACHAN_AHB_SEQ_WRAP	__BITS(18,16)
+#define	  APBDMACHAN_AHB_SEQ_WRAP_NO_WRAP	0
+#define	  APBDMACHAN_AHB_SEQ_WRAP_32		1
+#define	  APBDMACHAN_AHB_SEQ_WRAP_64		2
+#define	  APBDMACHAN_AHB_SEQ_WRAP_128		3
+#define	  APBDMACHAN_AHB_SEQ_WRAP_256		4
+#define	  APBDMACHAN_AHB_SEQ_WRAP_512		5
+#define	  APBDMACHAN_AHB_SEQ_WRAP_1024		6
+#define	  APBDMACHAN_AHB_SEQ_WRAP_2048		7
+#define	APBDMACHAN_APB_PTR_REG(n)	(0x1018 + ((n) * 0x40))
+#define	 APBDMACHAN_APB_PTR_MASK	__BITS(31,2)
+#define	APBDMACHAN_APB_SEQ_REG(n)	(0x101c + ((n) * 0x40))
+#define	 APBDMACHAN_APB_SEQ_BUS_WIDTH	__BITS(30,28)
+#define	  APBDMACHAN_APB_SEQ_BUS_WIDTH_8	0
+#define	  APBDMACHAN_APB_SEQ_BUS_WIDTH_16	1
+#define	  APBDMACHAN_APB_SEQ_BUS_WIDTH_32	2
+#define	 APBDMACHAN_APB_SEQ_DATA_SWAP	__BIT(27)
+#define	 APBDMACHAN_APB_SEQ_WRAP	__BITS(18,16)
+#define	  APBDMACHAN_APB_SEQ_WRAP_NO_WRAP	0
+#define	  APBDMACHAN_APB_SEQ_WRAP_1		1
+#define	  APBDMACHAN_APB_SEQ_WRAP_2		2
+#define	  APBDMACHAN_APB_SEQ_WRAP_4		3
+#define	  APBDMACHAN_APB_SEQ_WRAP_8		4
+#define	  APBDMACHAN_APB_SEQ_WRAP_16		5
+#define	  APBDMACHAN_APB_SEQ_WRAP_32		6
+#define	  APBDMACHAN_APB_SEQ_WRAP_64		7
+#define	APBDMACHAN_WCOUNT_REG(n)	(0x1020 + ((n) * 0x40))
+#define	APBDMACHAN_WORD_REG(n)		(0x1024 + ((n) * 0x40))
+
+#endif /* _ARM_TEGRA_APBDMAREG_H */
--- a/sys/arch/arm/nvidia/tegra_xusb.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/arm/nvidia/tegra_xusb.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_xusb.c,v 1.5 2017/04/16 12:28:21 jmcneill Exp $ */
+/* $NetBSD: tegra_xusb.c,v 1.5.2.1 2017/05/02 03:19:16 pgoyette Exp $ */
 
 /*
  * Copyright (c) 2016 Jonathan A. Kollasch
@@ -30,7 +30,7 @@
 #include "opt_tegra.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_xusb.c,v 1.5 2017/04/16 12:28:21 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_xusb.c,v 1.5.2.1 2017/05/02 03:19:16 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -57,6 +57,14 @@
 #include <dev/usb/xhcireg.h>
 #include <dev/usb/xhcivar.h>
 
+#ifdef TEGRA_XUSB_DEBUG
+int tegra_xusb_debug = 1;
+#else
+int tegra_xusb_debug = 0;
+#endif
+
+#define DPRINTF(...)	if (tegra_xusb_debug) device_printf(__VA_ARGS__)
+
 static int	tegra_xusb_match(device_t, cfdata_t, void *);
 static void	tegra_xusb_attach(device_t, device_t, void *);
 static void	tegra_xusb_mountroot(device_t);
@@ -126,10 +134,10 @@
 	char intrstr[128];
 	bus_addr_t addr;
 	bus_size_t size;
-	int error;
+	struct fdtbus_reset *rst;
 	struct clk *clk;
 	uint32_t rate;
-	struct fdtbus_reset *rst;
+	int error;
 
 	aprint_naive("\n");
 	aprint_normal(": XUSB\n");
@@ -149,7 +157,7 @@
 		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
 		return;
 	}
-	printf("mapped %#llx\n", (uint64_t)addr);
+	DPRINTF(sc->sc_dev, "mapped %#llx\n", (uint64_t)addr);
 
 	if (fdtbus_get_reg(faa->faa_phandle, 1, &addr, &size) != 0) {
 		aprint_error(": couldn't get registers\n");
@@ -160,7 +168,7 @@
 		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
 		return;
 	}
-	printf("mapped %#llx\n", (uint64_t)addr);
+	DPRINTF(sc->sc_dev, "mapped %#llx\n", (uint64_t)addr);
 
 	if (fdtbus_get_reg(faa->faa_phandle, 2, &addr, &size) != 0) {
 		aprint_error(": couldn't get registers\n");
@@ -171,7 +179,7 @@
 		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
 		return;
 	}
-	printf("mapped %#llx\n", (uint64_t)addr);
+	DPRINTF(sc->sc_dev, "mapped %#llx\n", (uint64_t)addr);
 
 	if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
 		aprint_error_dev(self, "failed to decode interrupt\n");
@@ -204,40 +212,40 @@
 	clk = fdtbus_clock_get(faa->faa_phandle, "pll_e");
 	rate = clk_get_rate(clk);
 	error = clk_enable(clk); /* XXX set frequency */
-	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "rate %u error %d\n", rate, error);
 	tegra_xusb_attach_check(sc, error, "failed to enable pll_e clock");
 
 	clk = fdtbus_clock_get(faa->faa_phandle, "xusb_host_src");
 	rate = clk_get_rate(clk);
-	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "rate %u error %d\n", rate, error);
 	error = clk_set_rate(clk, 102000000);
 	tegra_xusb_attach_check(sc, error, "failed to set xusb_host_src clock rate");
 
 	rate = clk_get_rate(clk);
 	error = clk_enable(clk); /* XXX set frequency */
-	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "rate %u error %d\n", rate, error);
 	tegra_xusb_attach_check(sc, error, "failed to enable xusb_host_src clock");
 
 	clk = fdtbus_clock_get(faa->faa_phandle, "xusb_falcon_src");
 	rate = clk_get_rate(clk);
-	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "rate %u error %d\n", rate, error);
 	error = clk_set_rate(clk, 204000000);
 	tegra_xusb_attach_check(sc, error, "failed to set xusb_falcon_src clock rate");
 
 	rate = clk_get_rate(clk);
 	error = clk_enable(clk);
-	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "rate %u error %d\n", rate, error);
 	tegra_xusb_attach_check(sc, error, "failed to enable xusb_falcon_src clock");
 
 	clk = fdtbus_clock_get(faa->faa_phandle, "xusb_host");
 	rate = clk_get_rate(clk);
 	error = clk_enable(clk); /* XXX set frequency */
-	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "rate %u error %d\n", rate, error);
 
 	clk = fdtbus_clock_get(faa->faa_phandle, "xusb_ss");
 	rate = clk_get_rate(clk);
 	error = clk_enable(clk); /* XXX set frequency */
-	device_printf(sc->sc_dev, "xusb_ss rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "xusb_ss rate %u error %d\n", rate, error);
 	tegra_xusb_attach_check(sc, error, "failed to enable xusb_ss clock");
 
 	psc->sc_clk_ss_src = fdtbus_clock_get(faa->faa_phandle, "xusb_ss_src");
@@ -245,37 +253,36 @@
 		"failed to get xusb_ss_src clock");
 
 	rate = clk_get_rate(psc->sc_clk_ss_src);
-	device_printf(sc->sc_dev, "xusb_ss_src rate %u\n", rate);
+	DPRINTF(sc->sc_dev, "xusb_ss_src rate %u\n", rate);
 	error = clk_set_rate(psc->sc_clk_ss_src, 2000000);
 	rate = clk_get_rate(psc->sc_clk_ss_src);
-	device_printf(sc->sc_dev, "xusb_ss_src rate %u error %d\n", rate,
-	    error);
+	DPRINTF(sc->sc_dev, "xusb_ss_src rate %u error %d\n", rate, error);
 	tegra_xusb_attach_check(sc, error, "failed to get xusb_ss_src clock rate");
 
 	rate = clk_get_rate(psc->sc_clk_ss_src);
-	device_printf(sc->sc_dev, "ss_src rate %u\n", rate);
+	DPRINTF(sc->sc_dev, "ss_src rate %u\n", rate);
 	tegra_xusb_attach_check(sc, error, "failed to set xusb_ss_src clock rate");
 
 	error = clk_set_rate(psc->sc_clk_ss_src, 120000000);
 	rate = clk_get_rate(psc->sc_clk_ss_src);
-	device_printf(sc->sc_dev, "ss_src rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "ss_src rate %u error %d\n", rate, error);
 	tegra_xusb_attach_check(sc, error, "failed to get xusb_ss_src clock rate");
 
 	error = clk_enable(psc->sc_clk_ss_src);
-	device_printf(sc->sc_dev, "ss_src rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "ss_src rate %u error %d\n", rate, error);
 	tegra_xusb_attach_check(sc, error, "failed to enable xusb_ss_src clock");
 
 #if 0
 	clk = fdtbus_clock_get(faa->faa_phandle, "xusb_hs_src");
 	error = 0;
 	rate = clk_get_rate(clk);
-	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "rate %u error %d\n", rate, error);
 #endif
 
 	clk = fdtbus_clock_get(faa->faa_phandle, "xusb_fs_src");
 	rate = clk_get_rate(clk);
 	error = clk_enable(clk); /* XXX set frequency */
-	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "rate %u error %d\n", rate, error);
 	tegra_xusb_attach_check(sc, error, "failed to enable xusb_fs_src clock");
 
 	rst = fdtbus_reset_get(faa->faa_phandle, "xusb_host");
@@ -311,29 +318,29 @@
 	uint32_t val;
 	int error;
 
-	device_printf(sc->sc_dev, "%s()\n", __func__);
+	DPRINTF(sc->sc_dev, "%s()\n", __func__);
 
 	val = bus_space_read_4(bst, ipfsh, 0x0);
-	device_printf(sc->sc_dev, "%s ipfs 0x0 = 0x%x\n", __func__, val);
+	DPRINTF(sc->sc_dev, "%s ipfs 0x0 = 0x%x\n", __func__, val);
 
 	if (tegra_xusb_load_fw(psc) != 0)
 		return;
-	device_printf(sc->sc_dev, "post fw\n");
+	DPRINTF(sc->sc_dev, "post fw\n");
 
 	tegra_xusbpad_xhci_enable();
 
 	clk = fdtbus_clock_get(psc->sc_phandle, "xusb_falcon_src");
 	rate = clk_get_rate(clk);
 	error = clk_enable(clk);
-	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "rate %u error %d\n", rate, error);
 
 	clk = fdtbus_clock_get(psc->sc_phandle, "xusb_host_src");
 	rate = clk_get_rate(clk);
 	error = clk_enable(clk);
-	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
+	DPRINTF(sc->sc_dev, "rate %u error %d\n", rate, error);
 
 	val = bus_space_read_4(bst, ipfsh, 0x0);
-	device_printf(sc->sc_dev, "%s ipfs 0x0 = 0x%x\n", __func__, val);
+	DPRINTF(sc->sc_dev, "%s ipfs 0x0 = 0x%x\n", __func__, val);
 
 	rst = fdtbus_reset_get(psc->sc_phandle, "xusb_host");
 	fdtbus_reset_deassert(rst);
@@ -345,7 +352,7 @@
 	fdtbus_reset_deassert(rst);
 
 	val = csb_read_4(psc, XUSB_CSB_FALCON_CPUCTL_REG);
-	device_printf(sc->sc_dev, "XUSB_FALC_CPUCTL 0x%x\n", val);
+	DPRINTF(sc->sc_dev, "XUSB_FALC_CPUCTL 0x%x\n", val);
 
 
 	error = xhci_init(sc);
@@ -376,20 +383,20 @@
 	uint32_t msg;
 	int error;
 
-	device_printf(sc->sc_dev, "%s()\n", __func__);
+	DPRINTF(sc->sc_dev, "%s()\n", __func__);
 
 	irv = bus_space_read_4(bst, fpcih, T_XUSB_CFG_ARU_SMI_INTR_REG);
-	device_printf(sc->sc_dev, "XUSB_CFG_ARU_SMI_INTR 0x%x\n", irv);
+	DPRINTF(sc->sc_dev, "XUSB_CFG_ARU_SMI_INTR 0x%x\n", irv);
 	bus_space_write_4(bst, fpcih, T_XUSB_CFG_ARU_SMI_INTR_REG, irv);
 
 	if (irv & T_XUSB_CFG_ARU_SMI_INTR_FW_HANG)
-		device_printf(sc->sc_dev, "firmware hang\n");
+		aprint_error_dev(sc->sc_dev, "firmware hang\n");
 
 	msg = bus_space_read_4(bst, fpcih, T_XUSB_CFG_ARU_MAILBOX_DATA_OUT_REG);
-	device_printf(sc->sc_dev, "XUSB_CFG_ARU_MBOX_DATA_OUT 0x%x\n", msg);
+	DPRINTF(sc->sc_dev, "XUSB_CFG_ARU_MBOX_DATA_OUT 0x%x\n", msg);
 
 	val = bus_space_read_4(bst, fpcih, T_XUSB_CFG_ARU_MAILBOX_CMD_REG);
-	device_printf(sc->sc_dev, "XUSB_CFG_ARU_MBOX_CMD 0x%x\n", val);
+	DPRINTF(sc->sc_dev, "XUSB_CFG_ARU_MBOX_CMD 0x%x\n", val);
 	val &= ~T_XUSB_CFG_ARU_MAILBOX_CMD_DEST_SMI;
 	bus_space_write_4(bst, fpcih, T_XUSB_CFG_ARU_MAILBOX_CMD_REG, val);
 
@@ -402,19 +409,19 @@
 	switch (type) {
 	case 2:
 	case 3:
-		device_printf(sc->sc_dev, "FALC_CLOCK %u\n", data * 1000);
+		DPRINTF(sc->sc_dev, "FALC_CLOCK %u\n", data * 1000);
 		break;
 	case 4:
 	case 5:
-		device_printf(sc->sc_dev, "SSPI_CLOCK %u\n", data * 1000);
+		DPRINTF(sc->sc_dev, "SSPI_CLOCK %u\n", data * 1000);
 		rate = clk_get_rate(psc->sc_clk_ss_src);
-		device_printf(sc->sc_dev, "rate of psc->sc_clk_ss_src %u\n",
+		DPRINTF(sc->sc_dev, "rate of psc->sc_clk_ss_src %u\n",
 		    rate);
 		error = clk_set_rate(psc->sc_clk_ss_src, data * 1000);
 		if (error != 0)
 			goto clk_fail;
 		rate = clk_get_rate(psc->sc_clk_ss_src);
-		device_printf(sc->sc_dev,
+		DPRINTF(sc->sc_dev,
 		    "rate of psc->sc_clk_ss_src %u after\n", rate);
 		if (data == (rate / 1000)) {
 			msg = __SHIFTIN(128, MAILBOX_DATA_TYPE) |
@@ -455,52 +462,52 @@
 	const bus_space_handle_t ipfsh = psc->sc_bsh_ipfs;
 	const bus_space_handle_t fpcih = psc->sc_bsh_fpci;
 
-	device_printf(sc->sc_dev, "%s()\n", __func__);
+	DPRINTF(sc->sc_dev, "%s()\n", __func__);
 
-	device_printf(sc->sc_dev, "%s ipfs 0x0 = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s ipfs 0x0 = 0x%x\n", __func__,
 	    bus_space_read_4(bst, ipfsh, 0x0));
 
-	device_printf(sc->sc_dev, "%s ipfs 0x40 = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s ipfs 0x40 = 0x%x\n", __func__,
 	    bus_space_read_4(bst, ipfsh, 0x40));
 
-	device_printf(sc->sc_dev, "%s ipfs 0x80 = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s ipfs 0x80 = 0x%x\n", __func__,
 	    bus_space_read_4(bst, ipfsh, 0x80));
 	/* FPCI_BAR0_START and FPCI_BAR0_ACCESS_TYPE */
 	bus_space_write_4(bst, ipfsh, 0x80, 0x00100000);
-	device_printf(sc->sc_dev, "%s ipfs 0x80 = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s ipfs 0x80 = 0x%x\n", __func__,
 	    bus_space_read_4(bst, ipfsh, 0x80));
 
-	device_printf(sc->sc_dev, "%s ipfs 0x180 = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s ipfs 0x180 = 0x%x\n", __func__,
 	    bus_space_read_4(bst, ipfsh, 0x180));
 	/* EN_FPCI */
 	tegra_reg_set_clear(bst, ipfsh, 0x180, 1, 0);
-	device_printf(sc->sc_dev, "%s ipfs 0x180 = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s ipfs 0x180 = 0x%x\n", __func__,
 	    bus_space_read_4(bst, ipfsh, 0x180));
 
-	device_printf(sc->sc_dev, "%s fpci PCI_COMMAND_STATUS_REG = 0x%x\n",
+	DPRINTF(sc->sc_dev, "%s fpci PCI_COMMAND_STATUS_REG = 0x%x\n",
 	    __func__, bus_space_read_4(bst, fpcih, PCI_COMMAND_STATUS_REG));
 	tegra_reg_set_clear(bst, fpcih, PCI_COMMAND_STATUS_REG,
 	    PCI_COMMAND_MASTER_ENABLE|PCI_COMMAND_MEM_ENABLE, 0x0);
-	device_printf(sc->sc_dev, "%s fpci PCI_COMMAND_STATUS_REG = 0x%x\n",
+	DPRINTF(sc->sc_dev, "%s fpci PCI_COMMAND_STATUS_REG = 0x%x\n",
 	    __func__, bus_space_read_4(bst, fpcih, PCI_COMMAND_STATUS_REG));
 
-	device_printf(sc->sc_dev, "%s fpci PCI_BAR0 = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s fpci PCI_BAR0 = 0x%x\n", __func__,
 	    bus_space_read_4(bst, fpcih, PCI_BAR0));
 	/* match FPCI BAR0 to above */
 	bus_space_write_4(bst, fpcih, PCI_BAR0, 0x10000000);
-	device_printf(sc->sc_dev, "%s fpci PCI_BAR0 = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s fpci PCI_BAR0 = 0x%x\n", __func__,
 	    bus_space_read_4(bst, fpcih, PCI_BAR0));
 	
-	device_printf(sc->sc_dev, "%s ipfs 0x188 = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s ipfs 0x188 = 0x%x\n", __func__,
 	    bus_space_read_4(bst, ipfsh, 0x188));
 	tegra_reg_set_clear(bst, ipfsh, 0x188, __BIT(16), 0);
-	device_printf(sc->sc_dev, "%s ipfs 0x188 = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s ipfs 0x188 = 0x%x\n", __func__,
 	    bus_space_read_4(bst, ipfsh, 0x188));
 
-	device_printf(sc->sc_dev, "%s fpci 0x1bc = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s fpci 0x1bc = 0x%x\n", __func__,
 	    bus_space_read_4(bst, fpcih, 0x1bc));
 	bus_space_write_4(bst, fpcih, 0x1bc, 0x80);
-	device_printf(sc->sc_dev, "%s fpci 0x1bc = 0x%x\n", __func__,
+	DPRINTF(sc->sc_dev, "%s fpci 0x1bc = 0x%x\n", __func__,
 	    bus_space_read_4(bst, fpcih, 0x1bc));
 }
 
@@ -593,7 +600,7 @@
 	}
 
 	firmware_image = psc->sc_fw_dma.addr;
-	device_printf(sc->sc_dev, "blob %p len %zu\n", firmware_image,
+	DPRINTF(sc->sc_dev, "blob %p len %zu\n", firmware_image,
 	    firmware_size);
 
 #if defined(TEGRA124_XUSB_BIN_STATIC)
@@ -615,22 +622,22 @@
 	const uint32_t boot_codesize = le32dec(&header[FWHEADER_BOOT_CODESIZE]);
 
 	if (fwimg_len != firmware_size)
-		device_printf(sc->sc_dev, "fwimg_len mismatch %u != %zu\n",
+		aprint_error_dev(sc->sc_dev, "fwimg_len mismatch %u != %zu\n",
 		    fwimg_len, firmware_size);
 
 	bus_dmamap_sync(sc->sc_bus.ub_dmatag, psc->sc_fw_dma.map, 0,
 	    firmware_size, BUS_DMASYNC_PREWRITE);
 
-	device_printf(sc->sc_dev, "XUSB_FALC_CPUCTL 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_CPUCTL 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_CPUCTL_REG));
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_ILOAD_BASE_LO 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_ILOAD_BASE_LO 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_ILOAD_BASE_LO_REG));
 
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_ILOAD_ATTR 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_ILOAD_ATTR 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_ILOAD_ATTR_REG));
 	csb_write_4(psc, XUSB_CSB_MEMPOOL_ILOAD_ATTR_REG,
 	    fwimg_len);
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_ILOAD_ATTR 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_ILOAD_ATTR 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_ILOAD_ATTR_REG));
 
 	const uint64_t fwbase = psc->sc_fw_dma.map->dm_segs[0].ds_addr +
@@ -638,24 +645,24 @@
 
 	csb_write_4(psc, XUSB_CSB_MEMPOOL_ILOAD_BASE_HI_REG, fwbase >> 32);
 	csb_write_4(psc, XUSB_CSB_MEMPOOL_ILOAD_BASE_LO_REG, fwbase);
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_ILOAD_BASE_LO 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_ILOAD_BASE_LO 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_ILOAD_BASE_LO_REG));
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_ILOAD_BASE_HI 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_ILOAD_BASE_HI 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_ILOAD_BASE_HI_REG));
 
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_APMAP 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_APMAP 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_APMAP_REG));
 	csb_write_4(psc, XUSB_CSB_MEMPOOL_APMAP_REG,
 	    XUSB_CSB_MEMPOOL_APMAP_BOOTPATH);
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_APMAP 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_APMAP 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_APMAP_REG));
 
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_TRIG 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_TRIG 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG_REG));
 	csb_write_4(psc, XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG_REG,
 	    __SHIFTIN(ACTION_L2IMEM_INVALIDATE_ALL,
 		XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG_ACTION));
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_TRIG 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_TRIG 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG_REG));
 
 	const u_int code_tag_blocks =
@@ -664,56 +671,56 @@
 	    howmany(boot_codesize, IMEM_BLOCK_SIZE);
 	const u_int code_blocks = code_tag_blocks + code_size_blocks;
 
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_SIZE 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_SIZE 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_L2IMEMOP_SIZE_REG));
 	csb_write_4(psc, XUSB_CSB_MEMPOOL_L2IMEMOP_SIZE_REG,
 	    __SHIFTIN(code_tag_blocks,
 		XUSB_CSB_MEMPOOL_L2IMEMOP_SIZE_SRC_OFFSET) |
 	    __SHIFTIN(code_size_blocks,
 		XUSB_CSB_MEMPOOL_L2IMEMOP_SIZE_SRC_COUNT));
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_SIZE 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_SIZE 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_L2IMEMOP_SIZE_REG));
 
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_TRIG 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_TRIG 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG_REG));
 	csb_write_4(psc, XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG_REG,
 	    __SHIFTIN(ACTION_L2IMEM_LOAD_LOCKED_RESULT,
 		XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG_ACTION));
-	device_printf(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_TRIG 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_CSB_MP_L2IMEMOP_TRIG 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG_REG));
 
-	device_printf(sc->sc_dev, "XUSB_FALC_IMFILLCTL 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_IMFILLCTL 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_IMFILLCTL_REG));
 	csb_write_4(psc, XUSB_CSB_FALCON_IMFILLCTL_REG, code_size_blocks);
-	device_printf(sc->sc_dev, "XUSB_FALC_IMFILLCTL 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_IMFILLCTL 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_IMFILLCTL_REG));
 
-	device_printf(sc->sc_dev, "XUSB_FALC_IMFILLRNG1 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_IMFILLRNG1 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_IMFILLRNG1_REG));
 	csb_write_4(psc, XUSB_CSB_FALCON_IMFILLRNG1_REG,
 	    __SHIFTIN(code_tag_blocks, XUSB_CSB_FALCON_IMFILLRNG1_TAG_LO) |
 	    __SHIFTIN(code_blocks, XUSB_CSB_FALCON_IMFILLRNG1_TAG_HI));
-	device_printf(sc->sc_dev, "XUSB_FALC_IMFILLRNG1 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_IMFILLRNG1 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_IMFILLRNG1_REG));
 
-	device_printf(sc->sc_dev, "XUSB_FALC_DMACTL 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_DMACTL 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_DMACTL_REG));
 	csb_write_4(psc, XUSB_CSB_FALCON_DMACTL_REG, 0);
-	device_printf(sc->sc_dev, "XUSB_FALC_DMACTL 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_DMACTL 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_DMACTL_REG));
 
-	device_printf(sc->sc_dev, "XUSB_FALC_BOOTVEC 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_BOOTVEC 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_BOOTVEC_REG));
 	csb_write_4(psc, XUSB_CSB_FALCON_BOOTVEC_REG,
 	    boot_codetag);
-	device_printf(sc->sc_dev, "XUSB_FALC_BOOTVEC 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_BOOTVEC 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_BOOTVEC_REG));
 
-	device_printf(sc->sc_dev, "XUSB_FALC_CPUCTL 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_CPUCTL 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_CPUCTL_REG));
 	csb_write_4(psc, XUSB_CSB_FALCON_CPUCTL_REG,
 	    XUSB_CSB_FALCON_CPUCTL_STARTCPU);
-	device_printf(sc->sc_dev, "XUSB_FALC_CPUCTL 0x%x\n",
+	DPRINTF(sc->sc_dev, "XUSB_FALC_CPUCTL 0x%x\n",
 	    csb_read_4(psc, XUSB_CSB_FALCON_CPUCTL_REG));
 
 	return 0;
@@ -758,7 +765,7 @@
 	if (!(type == 128 || type == 129)) {
 		val = bus_space_read_4(bst, fpcih,
 		    T_XUSB_CFG_ARU_MAILBOX_OWNER_REG);
-		device_printf(sc->sc_dev, "XUSB_CFG_ARU_MBOX_OWNER 0x%x\n",
+		DPRINTF(sc->sc_dev, "XUSB_CFG_ARU_MBOX_OWNER 0x%x\n",
 		    val);
 		if (val != MAILBOX_OWNER_NONE) {
 			return EBUSY;
@@ -769,7 +776,7 @@
 
 		val = bus_space_read_4(bst, fpcih,
 		    T_XUSB_CFG_ARU_MAILBOX_OWNER_REG);
-		device_printf(sc->sc_dev, "XUSB_CFG_ARU_MBOX_OWNER 0x%x\n",
+		DPRINTF(sc->sc_dev, "XUSB_CFG_ARU_MBOX_OWNER 0x%x\n",
 		    val);
 		if (val != MAILBOX_OWNER_SW) {
 			return EBUSY;
@@ -789,7 +796,7 @@
 		for (u_int i = 0; i < 2500; i++) {
 			val = bus_space_read_4(bst, fpcih,
 			    T_XUSB_CFG_ARU_MAILBOX_OWNER_REG);
-			device_printf(sc->sc_dev,
+			DPRINTF(sc->sc_dev,
 			    "XUSB_CFG_ARU_MBOX_OWNER 0x%x\n", val);
 			if (val == MAILBOX_OWNER_NONE) {
 				break;
@@ -799,10 +806,10 @@
 
 		val = bus_space_read_4(bst, fpcih,
 		    T_XUSB_CFG_ARU_MAILBOX_OWNER_REG);
-		device_printf(sc->sc_dev,
+		DPRINTF(sc->sc_dev,
 		    "XUSB_CFG_ARU_MBOX_OWNER 0x%x\n", val);
 		if (val != MAILBOX_OWNER_NONE) {
-			device_printf(sc->sc_dev,
+			aprint_error_dev(sc->sc_dev,
 			    "timeout, XUSB_CFG_ARU_MBOX_OWNER 0x%x\n", val);
 		}
 	}
--- a/sys/arch/evbarm/conf/TEGRA	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/evbarm/conf/TEGRA	Tue May 02 03:19:14 2017 +0000
@@ -1,5 +1,5 @@
 #
-#	$NetBSD: TEGRA,v 1.18 2017/04/26 01:51:52 jmcneill Exp $
+#	$NetBSD: TEGRA,v 1.18.2.1 2017/05/02 03:19:17 pgoyette Exp $
 #
 #	NVIDIA Tegra K1 (T124)
 #
@@ -53,6 +53,9 @@
 # Memory controller
 tegramc*	at fdt?	pass 4		# MC
 
+# DMA controller
+tegraapbdma*	at fdt? pass 4		# APB DMA
+
 # FUSE controller
 tegrafuse*	at fdt? pass 4		# FUSE
 
--- a/sys/arch/i386/stand/efiboot/Makefile.efiboot	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/i386/stand/efiboot/Makefile.efiboot	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.efiboot,v 1.8 2017/04/08 19:53:21 christos Exp $
+# $NetBSD: Makefile.efiboot,v 1.8.6.1 2017/05/02 03:19:17 pgoyette Exp $
 
 S=		${.CURDIR}/../../../../..
 
@@ -10,7 +10,7 @@
 
 SOURCES?= start.S conf.c devopen.c efiboot.c self_reloc.c
 LIBI386SRCS= boot.c biosdisk.c bootinfo.c bootinfo_biosgeom.c
-LIBI386SRCS+= bootmenu.c boot_params.S diskbuf.c exec.c menuutils.c
+LIBI386SRCS+= bootmenu.c diskbuf.c exec.c menuutils.c
 LIBI386SRCS+= panic.c parseutils.c pread.c
 LIBI386SRCS+= eficons.c efidelay.c efidisk.c efidisk_ll.c efigetsecs.c
 LIBI386SRCS+= efimemory.c
--- a/sys/arch/i386/stand/efiboot/boot.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/i386/stand/efiboot/boot.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: boot.c,v 1.4 2017/03/12 05:33:48 nonaka Exp $	*/
+/*	$NetBSD: boot.c,v 1.4.8.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@@ -30,6 +30,7 @@
 
 #include <sys/bootblock.h>
 #include <sys/boot_flag.h>
+#include <machine/limits.h>
 
 #include "bootcfg.h"
 #include "bootmod.h"
@@ -340,7 +341,7 @@
 	       "boot [xdNx:][filename] [-12acdqsvxz]\n"
 	       "     (ex. \"hd0a:netbsd.old -s\"\n"
 	       "dev [xd[N[x]]:]\n"
-	       "consdev {pc|com[0123]|com[0123]kbd|auto}\n"
+	       "consdev {pc|com[0123][,{speed}]|com,{ioport}[,{speed}]}\n"
 	       "devpath\n"
 	       "efivar\n"
 	       "gop [{modenum|list}]\n"
@@ -436,12 +437,77 @@
 	default_devname = savedevname;
 }
 
-/* ARGSUSED */
+static const struct cons_devs {
+	const char	*name;
+	u_int		tag;
+	int		ioport;
+} cons_devs[] = {
+	{ "pc",		CONSDEV_PC,   0 },
+	{ "com0",	CONSDEV_COM0, 0 },
+	{ "com1",	CONSDEV_COM1, 0 },
+	{ "com2",	CONSDEV_COM2, 0 },
+	{ "com3",	CONSDEV_COM3, 0 },
+	{ "com0kbd",	CONSDEV_COM0KBD, 0 },
+	{ "com1kbd",	CONSDEV_COM1KBD, 0 },
+	{ "com2kbd",	CONSDEV_COM2KBD, 0 },
+	{ "com3kbd",	CONSDEV_COM3KBD, 0 },
+	{ "com",	CONSDEV_COM0, -1 },
+	{ "auto",	CONSDEV_AUTO, 0 },
+	{ NULL,		0 }
+};
+
 void
 command_consdev(char *arg)
 {
+	const struct cons_devs *cdp;
+	char *sep, *sep2 = NULL;
+	int ioport, speed = 0;
 
-	/* XXX not implemented yet */
+	sep = strchr(arg, ',');
+	if (sep != NULL) {
+		*sep++ = '\0';
+		sep2 = strchr(sep, ',');
+		if (sep != NULL)
+			*sep2++ = '\0';
+	}
+
+	for (cdp = cons_devs; cdp->name; cdp++) {
+		if (strcmp(arg, cdp->name) == 0) {
+			ioport = cdp->ioport;
+			if (cdp->tag == CONSDEV_PC || cdp->tag == CONSDEV_AUTO) {
+				if (sep != NULL || sep2 != NULL)
+					goto error;
+			} else {
+				/* com? */
+				if (ioport == -1) {
+					if (sep != NULL) {
+						u_long t = strtoul(sep, NULL, 0);
+						if (t > INT_MAX)
+							goto error;
+						ioport = (int)t;
+					}
+					if (sep2 != NULL) {
+						speed = atoi(sep2);
+						if (speed < 0)
+							goto error;
+					}
+				} else {
+					if (sep != NULL) {
+						speed = atoi(sep);
+						if (speed < 0)
+							goto error;
+					}
+					if (sep2 != NULL)
+						goto error;
+				}
+			}
+			consinit(cdp->tag, ioport, speed);
+			print_banner();
+			return;
+		}
+	}
+error:
+	printf("invalid console device.\n");
 }
 
 #ifndef SMALL
--- a/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: efibootia32.c,v 1.2 2017/02/21 10:53:37 nonaka Exp $	*/
+/*	$NetBSD: efibootia32.c,v 1.2.8.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@@ -30,8 +30,6 @@
 
 #include <sys/bootblock.h>
 
-struct x86_boot_params boot_params;
-
 void startprog32_start(physaddr_t, uint32_t, uint32_t *, physaddr_t,
     physaddr_t, physaddr_t, u_long, void *);
 extern void (*startprog32)(physaddr_t, uint32_t, uint32_t *, physaddr_t,
--- a/sys/arch/i386/stand/efiboot/bootia32/start.S	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/i386/stand/efiboot/bootia32/start.S	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: start.S,v 1.1 2017/01/24 11:09:14 nonaka Exp $	*/
+/*	$NetBSD: start.S,v 1.1.10.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2008-2010 Rui Paulo <rpaulo@FreeBSD.org>
@@ -29,6 +29,7 @@
  */
 
 #include <machine/asm.h>
+#include <sys/bootblock.h>
 
 	.text
 	.align	16
@@ -72,3 +73,18 @@
 	.long   0
 	.long   10
 	.word   0
+
+	/* boot parameters */
+	.text
+	.code16
+	.align 512
+.Lfake_bootxx:
+	jmp	1f
+	.balign 4
+	.long	X86_BOOT_MAGIC_EFI	/* checked by installboot */
+	.globl _C_LABEL(boot_params)
+_C_LABEL(boot_params):			/* space for patchable variables */
+	.long	1f - boot_params	/* length of this data area */
+#include <boot_params.S>
+	. = .Lfake_bootxx + 0x80	/* Space for patching unknown params */
+1:
--- a/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: efibootx64.c,v 1.2 2017/02/11 10:23:39 nonaka Exp $	*/
+/*	$NetBSD: efibootx64.c,v 1.2.8.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@@ -30,8 +30,6 @@
 
 #include <sys/bootblock.h>
 
-struct x86_boot_params boot_params;
-
 void startprog64_start(physaddr_t, physaddr_t, physaddr_t, u_long,
     void *, physaddr_t);
 extern void (*startprog64)(physaddr_t, physaddr_t, physaddr_t, u_long,
--- a/sys/arch/i386/stand/efiboot/bootx64/start.S	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/i386/stand/efiboot/bootx64/start.S	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: start.S,v 1.1 2017/01/24 11:09:14 nonaka Exp $	*/
+/*	$NetBSD: start.S,v 1.1.10.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*-
  * Copyright (C) 1999 Hewlett-Packard Co.
@@ -39,6 +39,7 @@
  */
 
 #include <machine/asm.h>
+#include <sys/bootblock.h>
 
 	.text
 	.align 16
@@ -77,3 +78,18 @@
 	.long   0
 	.long   10
 	.word   0
+
+	/* boot parameters */
+	.text
+	.code16
+	.align 512
+.Lfake_bootxx:
+	jmp	1f
+	.balign 4
+	.long	X86_BOOT_MAGIC_EFI	/* checked by installboot */
+	.globl _C_LABEL(boot_params)
+_C_LABEL(boot_params):			/* space for patchable variables */
+	.long	1f - boot_params	/* length of this data area */
+#include <boot_params.S>
+	. = .Lfake_bootxx + 0x80	/* Space for patching unknown params */
+1:
--- a/sys/arch/i386/stand/efiboot/efiboot.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/i386/stand/efiboot/efiboot.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: efiboot.h,v 1.4 2017/02/11 10:23:39 nonaka Exp $	*/
+/*	$NetBSD: efiboot.h,v 1.4.8.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@@ -55,6 +55,7 @@
 
 /* eficons.c */
 int cninit(void);
+void consinit(int, int, int);
 void command_text(char *);
 void command_gop(char *);
 
--- a/sys/arch/i386/stand/efiboot/eficons.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/i386/stand/efiboot/eficons.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: eficons.c,v 1.3 2017/03/24 01:25:36 nonaka Exp $	*/
+/*	$NetBSD: eficons.c,v 1.3.6.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@@ -34,6 +34,8 @@
 #include "bootinfo.h"
 #include "vbe.h"
 
+extern struct x86_boot_params boot_params;
+
 struct btinfo_console btinfo_console;
 
 static EFI_GRAPHICS_OUTPUT_PROTOCOL *efi_gop;
@@ -46,6 +48,68 @@
 static void eficons_init_video(void);
 static void efi_switch_video_to_text_mode(void);
 
+static int
+getcomaddr(int idx)
+{
+	static const short comioport[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+
+	if (idx < __arraycount(comioport))
+		return comioport[idx];
+	return 0;
+}
+
+/*
+ * XXX only pass console parameters to kernel.
+ */
+void
+consinit(int dev, int ioport, int speed)
+{
+	int iodev;
+
+#if defined(CONSPEED)
+	btinfo_console.speed = CONSPEED;
+#else
+	btinfo_console.speed = 9600;
+#endif
+
+	switch (dev) {
+	case CONSDEV_AUTO:
+		/* XXX comport */
+		goto nocom;
+
+	case CONSDEV_COM0:
+	case CONSDEV_COM1:
+	case CONSDEV_COM2:
+	case CONSDEV_COM3:
+		iodev = dev;
+comport:
+		btinfo_console.addr = ioport;
+		if (btinfo_console.addr == 0) {
+			btinfo_console.addr = getcomaddr(iodev - CONSDEV_COM0);
+			if (btinfo_console.addr == 0)
+				goto nocom;
+		}
+		if (speed != 0)
+			btinfo_console.speed = speed;
+		break;
+
+	case CONSDEV_COM0KBD:
+	case CONSDEV_COM1KBD:
+	case CONSDEV_COM2KBD:
+	case CONSDEV_COM3KBD:
+		iodev = dev - CONSDEV_COM0KBD + CONSDEV_COM0;
+		goto comport;	/* XXX kbd */
+
+	case CONSDEV_PC:
+	default:
+nocom:
+		iodev = CONSDEV_PC;
+		break;
+	}
+
+	strlcpy(btinfo_console.devname, iodev == CONSDEV_PC ? "pc" : "com", 16);
+}
+
 int
 cninit(void)
 {
@@ -53,10 +117,8 @@
 	efi_switch_video_to_text_mode();
 	eficons_init_video();
 
-	/* XXX serial console */
-	btinfo_console.devname[0] = 'p';
-	btinfo_console.devname[1] = 'c';
-	btinfo_console.devname[2] = 0;
+	consinit(boot_params.bp_consdev, boot_params.bp_consaddr,
+	    boot_params.bp_conspeed);
 
 	return 0;
 }
--- a/sys/arch/mips/mips/cache_r4k_subr.S	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/mips/mips/cache_r4k_subr.S	Tue May 02 03:19:14 2017 +0000
@@ -37,7 +37,7 @@
 
 #include <mips/asm.h>
 
-RCSID("$NetBSD: cache_r4k_subr.S,v 1.2 2016/07/11 16:15:36 matt Exp $")
+RCSID("$NetBSD: cache_r4k_subr.S,v 1.2.10.1 2017/05/02 03:19:17 pgoyette Exp $")
 
 #include <mips/cache_r4k.h>
 
@@ -83,7 +83,7 @@
 	and	v1, a0, LINE_SIZE - 1		# get offset in cache line
 	xor	a0, v1				# align start to cache line
 	PTR_ADDU a1, v1				# add offset to size
-	PTR_ADDU a1, LINE_SIZE - 1		# size is now rouned
+	PTR_ADDU a1, LINE_SIZE - 1		# size is now rounded
 	PTR_SRL	t0, a1, LINE_SHIFT		# get # of cache lines
 
 	beqz	t0, 3f				# bail if t0 is 0 (no lines)
--- a/sys/arch/mips/mips/cache_r5k.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/mips/mips/cache_r5k.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: cache_r5k.c,v 1.19 2016/10/10 07:37:56 skrll Exp $	*/
+/*	$NetBSD: cache_r5k.c,v 1.19.6.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cache_r5k.c,v 1.19 2016/10/10 07:37:56 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cache_r5k.c,v 1.19.6.1 2017/05/02 03:19:17 pgoyette Exp $");
 
 #include <sys/param.h>
 
@@ -134,7 +134,7 @@
 
 	/*
 	 * If we are going to flush more than is in a way (or the stride
-	 * need for that way), we are flushing everything.
+	 * needed for that way), we are flushing everything.
 	 */
 	if (size >= way_size) {
 		r5k_picache_sync_all();
--- a/sys/arch/next68k/dev/zs.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/next68k/dev/zs.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: zs.c,v 1.33 2008/06/13 12:26:55 cegger Exp $	*/
+/*	$NetBSD: zs.c,v 1.33.74.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.33 2008/06/13 12:26:55 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.33.74.1 2017/05/02 03:19:17 pgoyette Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -183,7 +183,7 @@
 	if (zs_attached)
 		return 0;
 
-	ia->ia_addr = (void *)IIOV(NEXT_P_SCC);
+	ia->ia_addr = (void *)NEXT_P_SCC;
 
 	return 1;
 }
--- a/sys/arch/sparc/stand/boot/Makefile	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/sparc/stand/boot/Makefile	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.41 2017/04/09 20:51:55 christos Exp $
+#	$NetBSD: Makefile,v 1.41.4.1 2017/05/02 03:19:17 pgoyette Exp $
 
 STRIPFLAG=
 PROGSOURCE=	boot.c net.c netif_sun.c conf.c openfirm.c bootinfo.c \
@@ -40,16 +40,17 @@
 boot.net: boot.${RELOC_DEFAULT}
 	(printf ${SUN_MAGIC_HEADER}; cat ${.ALLSRC} ) > ${.TARGET}
 
+
+.include "${S}/conf/newvers_stand.mk"
+
+.include <bsd.prog.mk>
+
 bootjs.net: ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN}
 	${LD} -S -o ${.TARGET} ${LINKFLAGS} -Ttext 300000 ${OBJS} \
 	    ${LIBSA} ${LIBZ} ${LIBKERN}
 	${SIZE} ${.TARGET}
 CLEANFILES+=	bootjs.net.map
 
-.include "${S}/conf/newvers_stand.mk"
-
-.include <bsd.prog.mk>
-
 .for RELOC in ${RELOCS}
 boot.${RELOC}: ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN}
 	${LD} -S -o ${.TARGET}.tmp ${LINKFLAGS} -Ttext ${RELOC} ${OBJS} \
--- a/sys/arch/sparc64/dev/ffb.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/sparc64/dev/ffb.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffb.c,v 1.59 2017/04/22 15:07:49 macallan Exp $	*/
+/*	$NetBSD: ffb.c,v 1.59.2.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 /*	$OpenBSD: creator.c,v 1.20 2002/07/30 19:48:15 jason Exp $	*/
 
 /*
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffb.c,v 1.59 2017/04/22 15:07:49 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffb.c,v 1.59.2.1 2017/05/02 03:19:17 pgoyette Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -125,7 +125,6 @@
 void	ffb_ras_copyrows(void *, int, int, int);
 void	ffb_ras_erasecols(void *, int, int, int, long int);
 void	ffb_ras_eraserows(void *, int, int, long int);
-void	ffb_ras_do_cursor(struct rasops_info *);
 void	ffb_ras_fill(struct ffb_softc *);
 void	ffb_ras_invert(struct ffb_softc *);
 static void	ffb_ras_setfg(struct ffb_softc *, int32_t);
@@ -1087,20 +1086,44 @@
 		case 1: {
 			uint8_t *data8 = data;
 			uint32_t reg;
-			for (i = 0; i < he; i++) {
+			if (attr & WSATTR_UNDERLINE) {				
+				for (i = 0; i < he - 2; i++) {
+					reg = *data8;
+					FBC_WRITE(sc, FFB_FBC_FONT, reg << 24);
+					data8++;
+				}
+				FBC_WRITE(sc, FFB_FBC_FONT, 0xff000000);
+				data8++;
 				reg = *data8;
 				FBC_WRITE(sc, FFB_FBC_FONT, reg << 24);
-				data8++;
+			} else {
+				for (i = 0; i < he; i++) {
+					reg = *data8;
+					FBC_WRITE(sc, FFB_FBC_FONT, reg << 24);
+					data8++;
+				}
 			}
 			break;
 		}
 		case 2: {
 			uint16_t *data16 = data;
 			uint32_t reg;
-			for (i = 0; i < he; i++) {
+			if (attr & WSATTR_UNDERLINE) {				
+				for (i = 0; i < he - 2; i++) {
+					reg = *data16;
+					FBC_WRITE(sc, FFB_FBC_FONT, reg << 16);
+					data16++;
+				}
+				FBC_WRITE(sc, FFB_FBC_FONT, 0xffff0000);
+				data16++;
 				reg = *data16;
 				FBC_WRITE(sc, FFB_FBC_FONT, reg << 16);
-				data16++;
+			} else {
+				for (i = 0; i < he; i++) {
+					reg = *data16;
+					FBC_WRITE(sc, FFB_FBC_FONT, reg << 16);
+					data16++;
+				}
 			}
 			break;
 		}
@@ -1149,7 +1172,7 @@
 	FBC_WRITE(sc, FFB_FBC_BW, wi);
 
 	/* if we draw a space we're done */
-	if (c == ' ') return;
+	if (c == ' ') goto out;
 
 	/* now enable alpha blending */
 	ffb_ras_setfg(sc, fg);
@@ -1186,7 +1209,16 @@
 			ddest++;
 		}
 		dest += 2048;
-	} 
+	}
+out:
+	/* check if we need to draw an underline */
+	if (attr & WSATTR_UNDERLINE) {
+		dest =  sc->sc_sfb32 + ((y + he - 2) << 11) + x;
+		for (i = 0; i < wi; i++) {
+			*dest = 0xa0000000;
+			dest++;
+		}
+	}
 }
 
 int
@@ -1198,11 +1230,11 @@
 		bg = WS_DEFAULT_BG;
 	}
 	if (flags & WSATTR_REVERSE) {
-		*attrp = (bg & 0xff) << 24 | (fg & 0xff) << 16 | 
-		    (flags & 0xff);
+		*attrp = (bg & 0xff) << 24 | (fg & 0xff) << 16;
 	} else
-		*attrp = (fg & 0xff) << 24 | (bg & 0xff) << 16 | 
-		    (flags & 0xff);
+		*attrp = (fg & 0xff) << 24 | (bg & 0xff) << 16;
+	if (flags & WSATTR_UNDERLINE)
+		*attrp |= WSATTR_UNDERLINE;
 	return 0;
 }
 
@@ -1217,8 +1249,7 @@
 	ri->ri_width = sc->sc_width;
 	ri->ri_height = sc->sc_height;
 	ri->ri_stride = sc->sc_linebytes;
-	ri->ri_flg = RI_CENTER | RI_ENABLE_ALPHA | RI_PREFER_ALPHA |
-		     RI_FULLCLEAR;
+	ri->ri_flg = RI_CENTER | RI_ENABLE_ALPHA | RI_PREFER_ALPHA;
 
 	/*
 	 * we can't accelerate copycols() so instead of falling back to
@@ -1239,7 +1270,7 @@
 	ri->ri_bpos = 16;
 
 	rasops_init(ri, 0, 0);
-	ri->ri_caps = WSSCREEN_WSCOLORS;
+	ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_UNDERLINE | WSSCREEN_REVERSE;
 	rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
 		    sc->sc_width / ri->ri_font->fontwidth);
 
--- a/sys/arch/x86/include/i82489reg.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/arch/x86/include/i82489reg.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: i82489reg.h,v 1.15 2017/04/22 04:24:25 nonaka Exp $	*/
+/*	$NetBSD: i82489reg.h,v 1.15.2.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -44,6 +44,7 @@
 #	define LAPIC_VERSION_LVT_MASK	0x00ff0000
 #	define LAPIC_VERSION_LVT_SHIFT	16
 #	define LAPIC_VERSION_DIRECTED_EOI 0x01000000
+#	define LAPIC_VERSION_EXTAPIC_SPACE 0x80000000
 
 #define LAPIC_TPRI		0x080	/* Task Prio. RW */
 #	define LAPIC_TPRI_MASK		0x000000ff
--- a/sys/compat/common/vm_43.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/compat/common/vm_43.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_43.c,v 1.18 2011/02/08 20:20:26 rmind Exp $	*/
+/*	$NetBSD: vm_43.c,v 1.18.46.1 2017/05/02 03:19:17 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_43.c,v 1.18 2011/02/08 20:20:26 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_43.c,v 1.18.46.1 2017/05/02 03:19:17 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -110,12 +110,21 @@
 	SCARG(&nargs, flags) = 0;
 	if (SCARG(uap, flags) & OMAP_ANON)
 		SCARG(&nargs, flags) |= MAP_ANON;
-	if (SCARG(uap, flags) & OMAP_COPY)
-		SCARG(&nargs, flags) |= MAP_COPY;
 	if (SCARG(uap, flags) & OMAP_SHARED)
 		SCARG(&nargs, flags) |= MAP_SHARED;
 	else
 		SCARG(&nargs, flags) |= MAP_PRIVATE;
+	if (SCARG(uap, flags) & OMAP_COPY) {
+		SCARG(&nargs, flags) |= MAP_PRIVATE;
+#if defined(COMPAT_10) && defined(__i386__)
+		/*
+		 * Ancient kernel on x86 did not obey PROT_EXEC on i386 at least
+		 * and ld.so did not turn it on. We take care of this on amd64
+		 * in compat32.
+		 */
+		SCARG(&nargs, prot) |= PROT_EXEC;
+#endif
+	}
 	if (SCARG(uap, flags) & OMAP_FIXED)
 		SCARG(&nargs, flags) |= MAP_FIXED;
 	if (SCARG(uap, flags) & OMAP_INHERIT)
--- a/sys/compat/linux32/arch/amd64/linux32_exec.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/compat/linux32/arch/amd64/linux32_exec.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_exec.h,v 1.6 2014/02/21 07:53:53 maxv Exp $ */
+/*	$NetBSD: linux32_exec.h,v 1.6.20.1 2017/05/02 03:19:17 pgoyette Exp $ */
 
 /*-
  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
@@ -75,10 +75,12 @@
 };      
 #define LINUX32_ELF_AUX_ARGSIZ sizeof(struct linux32_extra_stack_data)
 
-#endif
+#else
 
 #define LINUX32_ELF_AUX_ARGSIZ \
-	(howmany(LINUX32_ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr)) + LINUX32_RANDOM_BYTES)
+    (LINUX32_ELF_AUX_ENTRIES * sizeof(Aux32Info) + LINUX32_RANDOM_BYTES)
+
+#endif
 
 #ifdef _KERNEL
 int linux32_exec_setup_stack(struct lwp *, struct exec_package *);
--- a/sys/compat/netbsd32/netbsd32_netbsd.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/compat/netbsd32/netbsd32_netbsd.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_netbsd.c,v 1.205 2016/10/19 09:44:01 skrll Exp $	*/
+/*	$NetBSD: netbsd32_netbsd.c,v 1.205.6.1 2017/05/02 03:19:18 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001, 2008 Matthew R. Green
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.205 2016/10/19 09:44:01 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.205.6.1 2017/05/02 03:19:18 pgoyette Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ddb.h"
@@ -90,6 +90,8 @@
 #include <compat/netbsd32/netbsd32_syscallargs.h>
 #include <compat/netbsd32/netbsd32_conv.h>
 
+#include <compat/sys/mman.h>
+
 #if defined(DDB)
 #include <ddb/ddbvar.h>
 #endif
@@ -1521,8 +1523,11 @@
 	 * Ancient kernel on x86 did not obey PROT_EXEC on i386 at least
 	 * and ld.so did not turn it on!
 	 */
-	if (SCARG(&ua, flags) & MAP_COPY)
+	if (SCARG(&ua, flags) & COMPAT_MAP_COPY) {
+		SCARG(&ua, flags) = MAP_PRIVATE
+		    | (SCARG(&ua, flags) & ~COMPAT_MAP_COPY);
 		SCARG(&ua, prot) |= PROT_EXEC;
+	}
 #endif
 	NETBSD32TO64_UAP(fd);
 	NETBSD32TOX_UAP(PAD, long);
--- a/sys/compat/sys/mman.h	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/compat/sys/mman.h	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: mman.h,v 1.2 2005/12/11 12:20:29 christos Exp $	*/
+/*	$NetBSD: mman.h,v 1.2.156.1 2017/05/02 03:19:18 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1993
@@ -34,6 +34,12 @@
 #ifndef _COMPAT_SYS_MMAN_H_
 #define _COMPAT_SYS_MMAN_H_
 
+/*
+ * Deprecated flag; these are treated as MAP_PRIVATE internally by
+ * the kernel. 
+ */
+#define	COMPAT_MAP_COPY	0x0004	/* "copy" region at mmap time */
+
 __BEGIN_DECLS
 int	msync(void *, size_t);
 int	__msync13(void *, size_t, int);
--- a/sys/dev/audio.c	Sun Apr 30 10:27:16 2017 +0000
+++ b/sys/dev/audio.c	Tue May 02 03:19:14 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.327.2.2 2017/04/29 11:12:14 pgoyette Exp $	*/
+/*	$NetBSD: audio.c,v 1.327.2.3 2017/05/02 03:19:18 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au>
@@ -148,7 +148,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.327.2.2 2017/04/29 11:12:14 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.327.2.3 2017/05/02 03:19:18 pgoyette Exp $");
 
 #include "audio.h"
 #if NAUDIO > 0
@@ -650,8 +650,6 @@
 		    "failed\n", __func__);
 	}
 
-	sc->sc_pr.blksize = vc->sc_mpr.blksize;
-	sc->sc_rr.blksize = vc->sc_mrr.blksize;
 	sc->sc_sih_rd = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE,
 	    audio_softintr_rd, sc);
 	sc->sc_sih_wr = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE,
@@ -1287,14 +1285,16 @@
 	}
 
 #ifdef AUDIO_DEBUG
-	printf("%s: HW-buffer=%p pustream=%p\n",
-	       __func__, &vc->sc_mpr.s, vc->sc_pustream);
-	for (i = 0; i < pfilters->req_size; i++) {
-		char num[100];
-		snprintf(num, 100, "[%d]", i);
-		audio_print_params(num, &vc->sc_pstreams[i].param);
-	}
-	audio_print_params("[HW]", &vc->sc_mpr.s.param);
+	if (audiodebug) {
+		printf("%s: HW-buffer=%p pustream=%p\n",
+		       __func__, &vc->sc_mpr.s, vc->sc_pustream);
+		for (i = 0; i < pfilters->req_size; i++) {
+			char num[100];
+			snprintf(num, 100, "[%d]", i);
+			audio_print_params(num, &vc->sc_pstreams[i].param);
+		}
+		audio_print_params("[HW]", &vc->sc_mpr.s.param);
+	}
 #endif /* AUDIO_DEBUG */
 
 	return 0;
@@ -1366,13 +1366,15 @@
 	HW_UNLOCK(vc);
 
 #ifdef AUDIO_DEBUG
-	printf("%s: HW-buffer=%p pustream=%p\n",
-	       __func__, &vc->sc_mrr.s, vc->sc_rustream);
-	audio_print_params("[HW]", &vc->sc_mrr.s.param);
-	for (i = 0; i < rfilters->req_size; i++) {
-		char num[100];
-		snprintf(num, 100, "[%d]", i);
-		audio_print_params(num, &vc->sc_rstreams[i].param);
+	if (audiodebug) {
+		printf("%s: HW-buffer=%p pustream=%p\n",
+		       __func__, &vc->sc_mrr.s, vc->sc_rustream);
+		audio_print_params("[HW]", &vc->sc_mrr.s.param);
+		for (i = 0; i < rfilters->req_size; i++) {
+			char num[100];
+			snprintf(num, 100, "[%d]", i);
+			audio_print_params(num, &vc->sc_rstreams[i].param);
+		}
 	}
 #endif /* AUDIO_DEBUG */
 
@@ -1986,6 +1988,8 @@
 	if (vc == NULL) {
 		chan = SIMPLEQ_FIRST(&sc->sc_audiochan);
 		vc = chan->vc;
+		sc->sc_pr.blksize = vc->sc_mrr.blksize;
+		sc->sc_rr.blksize = vc->sc_mrr.blksize;
 	}
 
 	DPRINTF(("audio_initbufs: mode=0x%x\n", vc->sc_mode));
@@ -2001,6 +2005,8 @@
 				return error;
 		}
 	}
+	if (vc == SIMPLEQ_FIRST(&sc->sc_audiochan)->vc)
+		sc->sc_rr.blksize = vc->sc_mrr.blksize;
 
 	if (audio_can_playback(sc) || (vc->sc_open & AUOPEN_WRITE)) {
 		audio_init_ringbuffer(sc, &vc->sc_mpr,
@@ -2014,6 +2020,8 @@
 				return error;
 		}
 	}
+	if (vc == SIMPLEQ_FIRST(&sc->sc_audiochan)->vc)
+		sc->sc_pr.blksize = vc->sc_mpr.blksize;
 
 #ifdef AUDIO_INTR_TIME
 #define double u_long
@@ -2156,9 +2164,9 @@
 				return error;
 			}
 		}
+		audio_initbufs(sc, NULL);
 		audio_init_ringbuffer(sc, &sc->sc_pr, AUMODE_PLAY);
 		audio_init_ringbuffer(sc, &sc->sc_rr, AUMODE_RECORD);
-		audio_initbufs(sc, NULL);
 		sc->schedule_wih = false;
 		sc->schedule_rih = false;
 		sc->sc_eof = 0;
@@ -2191,8 +2199,8 @@
 		mode |= AUMODE_PLAY | AUMODE_PLAY_ALL;
 	}
 
+	vc->sc_mpr.blksize = sc->sc_pr.blksize;
 	vc->sc_mrr.blksize = sc->sc_rr.blksize;
-	vc->sc_mpr.blksize = sc->sc_pr.blksize;
 
 	/*
 	 * Multiplex device: /dev/audio (MU-Law) and /dev/sound (linear)
@@ -3597,7 +3605,7 @@
 	struct audio_softc *sc;
 	struct audio_chan *chan;
 	struct virtual_channel *vc;
-	int blksize;
+	int blksize, cc, used;
 
 	sc = v;
 	chan = SIMPLEQ_FIRST(&sc->sc_audiochan);
@@ -3616,10 +3624,16 @@
 	    vc->sc_mpr.s.outp, blksize);
 
 	if (audio_stream_get_used(&sc->sc_pr.s) < blksize) {
-		audio_fill_silence(&vc->sc_pparams, vc->sc_mpr.s.inp,
-		    vc->sc_mpr.blksize);
-		vc->sc_mpr.s.inp = audio_stream_add_inp(&vc->sc_mpr.s,
-		    vc->sc_mpr.s.inp, blksize);
+		used = blksize;
+		while (used > 0) {
+			cc = sc->sc_pr.s.end - sc->sc_pr.s.inp;
+			if (cc > used)
+				cc = used;
+			audio_fill_silence(&vc->sc_pparams, vc->sc_mpr.s.inp, cc);
+			vc->sc_mpr.s.inp = audio_stream_add_inp(&vc->sc_mpr.s,
+			    vc->sc_mpr.s.inp, cc);
+			used -= cc;
+		}
 		goto wake_mix;
 	}
 
@@ -3800,8 +3814,10 @@
 	inp = cb->s.inp;
 	cc = blksize - (inp - cb->s.start) % blksize;
 	if (sc->sc_writeme == false)
-		audio_pint_silence(sc, cb, inp, cc, vc);
-	cb->s.inp = audio_stream_add_inp(&cb->s, cb->s.inp, blksize);
+		audio_fill_silence(&vc->sc_mpr.s.param, inp, cc);
+	else
+		cc = blksize;
+	cb->s.inp = audio_stream_add_inp(&cb->s, cb->s.inp, cc);
 	mutex_exit(sc->sc_intr_lock);
 
 	kpreempt_disable();
@@ -4104,9 +4120,6 @@
 	if (error == 0)
 		error = audiosetinfo(sc, &ai, true, vc);
 
-	sc->sc_pr.blksize = vc->sc_mpr.blksize;
-	sc->sc_rr.blksize = vc->sc_mrr.blksize;
-
 	return error;
 }
 
@@ -4446,7 +4459,6 @@
 	int error;
 	int np, nr;
 	unsigned int blks;
-	int oldpblksize, oldrblksize;
 	u_int gain;
 	bool rbus, pbus;
 	bool cleared, modechange, pausechange;
@@ -4525,9 +4537,6 @@
 	if (np > 0 && (error = audio_check_params(&pp)))
 		return error;
 
-	oldpblksize = vc->sc_mpr.blksize;
-	oldrblksize = vc->sc_mrr.blksize;
-
 	setmode = 0;
 	if (nr > 0) {
 		if (!cleared) {
@@ -4712,50 +4721,6 @@
 		pausechange = true;
 	}
 
-	if (SPECIFIED(ai->blocksize)) {
-		int pblksize, rblksize;
-
-		/* Block size specified explicitly. */
-		if (ai->blocksize == 0) {
-			if (!cleared) {
-				audio_clear_intr_unlocked(sc, vc);
-				cleared = true;
-			}
-			vc->sc_blkset = false;
-			audio_calc_blksize(sc, AUMODE_RECORD, vc);
-			audio_calc_blksize(sc, AUMODE_PLAY, vc);
-		} else {
-			vc->sc_blkset = true;
-			/* check whether new blocksize changes actually */
-			if (hw->round_blocksize == NULL) {
-				if (!cleared) {
-					audio_clear_intr_unlocked(sc, vc);
-					cleared = true;
-				}
-				vc->sc_mpr.blksize = ai->blocksize;
-				vc->sc_mrr.blksize = ai->blocksize;
-			} else {
-				pblksize = hw->round_blocksize(sc->hw_hdl,
-				    ai->blocksize, AUMODE_PLAY,
-				    &vc->sc_mpr.s.param);
-				rblksize = hw->round_blocksize(sc->hw_hdl,
-				    ai->blocksize, AUMODE_RECORD,
-				    &vc->sc_mrr.s.param);
-				if ((pblksize != vc->sc_mpr.blksize &&
-				    pblksize > sc->sc_pr.blksize)
-				    || (rblksize != vc->sc_mrr.blksize &&
-				    rblksize > sc->sc_rr.blksize)) {
-					if (!cleared) {
-					    audio_clear_intr_unlocked(sc, vc);
-					    cleared = true;
-					}
-					vc->sc_mpr.blksize = pblksize;
-					vc->sc_mrr.blksize = rblksize;
-				}
-			}
-		}
-	}
-
 	if (SPECIFIED(ai->mode)) {
 		if (vc->sc_mode & AUMODE_PLAY)
 			audio_init_play(sc, vc);
@@ -4763,6 +4728,22 @@
 			audio_init_record(sc, vc);
 	}
 
+	if (vc == SIMPLEQ_FIRST(&sc->sc_audiochan)->vc) {
+		if (!cleared) {
+			audio_clear_intr_unlocked(sc, vc);
+			cleared = true;
+		}
+		vc->sc_blkset = false;
+		audio_calc_blksize(sc, AUMODE_RECORD, vc);
+		audio_calc_blksize(sc, AUMODE_PLAY, vc);
+		sc->sc_pr.blksize = vc->sc_mpr.blksize;
+		sc->sc_rr.blksize = vc->sc_mrr.blksize;
+	} else {
+		vc->sc_blkset = true;
+		vc->sc_mpr.blksize = sc->sc_pr.blksize;
+		vc->sc_mrr.blksize = sc->sc_rr.blksize;
+	}
+
 	if (hw->commit_settings && sc->sc_open