[rtems-libbsd commit] Update to FreeBSD stable/12 2019-08-26

Sebastian Huber sebh at rtems.org
Mon Aug 26 07:49:49 UTC 2019


Module:    rtems-libbsd
Branch:    5-freebsd-12
Commit:    3411e3d738723cfb777f01c99bb9243843b3c9f8
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=3411e3d738723cfb777f01c99bb9243843b3c9f8

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Aug 26 09:07:22 2019 +0200

Update to FreeBSD stable/12 2019-08-26

Git mirror commit 621e7bafbf6857451f23ba11b0495c7ac69aff89.

---

 freebsd-org                                        |   2 +-
 freebsd/sys/arm/ti/cpsw/if_cpsw.c                  |   4 +-
 freebsd/sys/arm/ti/ti_hwmods.c                     |  16 +-
 freebsd/sys/cam/ata/ata_all.h                      |   1 +
 freebsd/sys/cam/cam.c                              |  10 +-
 freebsd/sys/cam/nvme/nvme_all.h                    |   4 +-
 freebsd/sys/cam/scsi/scsi_all.c                    |  45 +-
 freebsd/sys/cam/scsi/scsi_all.h                    |  57 ++-
 freebsd/sys/dev/bge/if_bge.c                       |   4 +-
 freebsd/sys/dev/fdt/simplebus.c                    |   9 +-
 freebsd/sys/dev/fdt/simplebus.h                    |   2 +
 freebsd/sys/dev/gpio/gpiobus.c                     | 185 +++++++-
 freebsd/sys/dev/gpio/gpiobusvar.h                  |  14 +-
 freebsd/sys/dev/gpio/ofw_gpiobus.c                 |   4 +-
 freebsd/sys/dev/mmc/mmcsd.c                        |   6 +-
 freebsd/sys/dev/nvme/nvme.h                        | 510 +++++++++++++++++++--
 freebsd/sys/dev/ofw/ofw_subr.c                     |   3 +-
 freebsd/sys/fs/devfs/devfs_vnops.c                 |   1 +
 freebsd/sys/kern/init_main.c                       |   8 +-
 freebsd/sys/kern/kern_event.c                      |   1 +
 freebsd/sys/kern/kern_sysctl.c                     |  24 +
 freebsd/sys/kern/subr_bus.c                        |   5 +-
 freebsd/sys/kern/sys_pipe.c                        |   2 +-
 freebsd/sys/kern/uipc_mbuf2.c                      |   2 +-
 freebsd/sys/kern/uipc_usrreq.c                     |  41 +-
 freebsd/sys/net/ieee_oui.h                         |   7 +-
 freebsd/sys/net/if_spppsubr.c                      |   2 +-
 freebsd/sys/net/if_tun.c                           |   6 +-
 freebsd/sys/net/if_tun.h                           |   1 +
 freebsd/sys/net/iflib.h                            |   7 +
 freebsd/sys/net/route.c                            |   2 +
 freebsd/sys/netinet/tcp_input.c                    |   3 +
 freebsd/sys/netinet/tcp_usrreq.c                   |   4 +-
 freebsd/sys/netinet6/ip6_output.c                  |  17 +-
 freebsd/sys/netinet6/mld6.c                        |  48 +-
 freebsd/sys/netipsec/ipsec.c                       |   5 +
 freebsd/sys/netipsec/ipsec.h                       |   2 +
 freebsd/sys/netipsec/key.c                         |  12 +-
 freebsd/sys/netipsec/xform_ah.c                    |   9 +-
 freebsd/sys/netipsec/xform_esp.c                   |   9 +-
 freebsd/sys/netpfil/ipfw/ip_fw_private.h           |   1 +
 freebsd/sys/opencrypto/cryptodev.c                 |  23 +
 freebsd/sys/sys/ata.h                              |  32 +-
 freebsd/sys/sys/bus.h                              |  13 +-
 freebsd/sys/sys/file.h                             |   5 +-
 freebsd/sys/sys/mount.h                            |   7 +-
 freebsd/sys/sys/proc.h                             |   7 +
 freebsd/sys/sys/sysctl.h                           |  20 +
 freebsd/sys/sys/vnode.h                            |  12 +-
 freebsd/usr.bin/netstat/ipsec.c                    |  29 +-
 .../include/machine/rtems-bsd-kernel-namespace.h   |   6 +-
 51 files changed, 1040 insertions(+), 209 deletions(-)

diff --git a/freebsd-org b/freebsd-org
index 3427c34..621e7ba 160000
--- a/freebsd-org
+++ b/freebsd-org
@@ -1 +1 @@
-Subproject commit 3427c3416aa3c0f25124070959cca78024b94d85
+Subproject commit 621e7bafbf6857451f23ba11b0495c7ac69aff89
diff --git a/freebsd/sys/arm/ti/cpsw/if_cpsw.c b/freebsd/sys/arm/ti/cpsw/if_cpsw.c
index fb61aeb..be9ad62 100644
--- a/freebsd/sys/arm/ti/cpsw/if_cpsw.c
+++ b/freebsd/sys/arm/ti/cpsw/if_cpsw.c
@@ -762,7 +762,9 @@ cpsw_get_fdt_data(struct cpsw_softc *sc, int port)
 			continue;
 		}
 		OF_prop_free(name);
-		if (mdio_child_addr != slave_mdio_addr[port])
+
+		if (mdio_child_addr != slave_mdio_addr[port] &&
+		    mdio_child_addr != (slave_mdio_addr[port] & 0xFFF))
 			continue;
 
 		if (fdt_get_phyaddr(child, NULL, &phy, NULL) != 0){
diff --git a/freebsd/sys/arm/ti/ti_hwmods.c b/freebsd/sys/arm/ti/ti_hwmods.c
index 450679a..a546d76 100644
--- a/freebsd/sys/arm/ti/ti_hwmods.c
+++ b/freebsd/sys/arm/ti/ti_hwmods.c
@@ -99,6 +99,16 @@ struct hwmod ti_hwmods[] = {
 	{NULL,		0}
 };
 
+static inline int
+ti_get_hwmods_prop(phandle_t node, void **name)
+{
+	int len;
+
+	if ((len = OF_getprop_alloc(node, "ti,hwmods", name)) > 0)
+		return (len);
+	return (OF_getprop_alloc(OF_parent(node), "ti,hwmods", name));
+}
+
 clk_ident_t
 ti_hwmods_get_clock(device_t dev)
 {
@@ -112,7 +122,7 @@ ti_hwmods_get_clock(device_t dev)
 	if ((node = ofw_bus_get_node(dev)) == 0)
 		return (INVALID_CLK_IDENT);
 
-	if ((len = OF_getprop_alloc(node, "ti,hwmods", (void**)&name)) <= 0)
+	if ((len = ti_get_hwmods_prop(node, (void **)&name)) <= 0)
 		return (INVALID_CLK_IDENT);
 
 	buf = name;
@@ -150,7 +160,7 @@ int ti_hwmods_contains(device_t dev, const char *hwmod)
 	if ((node = ofw_bus_get_node(dev)) == 0)
 		return (0);
 
-	if ((len = OF_getprop_alloc(node, "ti,hwmods", (void**)&name)) <= 0)
+	if ((len = ti_get_hwmods_prop(node, (void **)&name)) <= 0)
 		return (0);
 
 	buf = name;
@@ -184,7 +194,7 @@ ti_hwmods_get_unit(device_t dev, const char *hwmod)
 	if ((node = ofw_bus_get_node(dev)) == 0)
 		return (0);
 
-	if ((len = OF_getprop_alloc(node, "ti,hwmods", (void**)&name)) <= 0)
+	if ((len = ti_get_hwmods_prop(node, (void **)&name)) <= 0)
 		return (0);
 
 	buf = name;
diff --git a/freebsd/sys/cam/ata/ata_all.h b/freebsd/sys/cam/ata/ata_all.h
index 087d682..ca63525 100644
--- a/freebsd/sys/cam/ata/ata_all.h
+++ b/freebsd/sys/cam/ata/ata_all.h
@@ -135,6 +135,7 @@ void	ata_read_log(struct ccb_ataio *ataio, uint32_t retries,
 		     uint16_t block_count, uint32_t protocol,
 		     uint8_t *data_ptr, uint32_t dxfer_len, uint32_t timeout);
 
+void	ata_param_fixup(struct ata_params *ident_buf);
 void	ata_bswap(int8_t *buf, int len);
 void	ata_btrim(int8_t *buf, int len);
 void	ata_bpack(int8_t *src, int8_t *dst, int len);
diff --git a/freebsd/sys/cam/cam.c b/freebsd/sys/cam/cam.c
index 5d07beb..25f99ae 100644
--- a/freebsd/sys/cam/cam.c
+++ b/freebsd/sys/cam/cam.c
@@ -418,7 +418,6 @@ cam_error_string(struct cam_device *device, union ccb *ccb, char *str,
 		switch (ccb->ccb_h.func_code) {
 		case XPT_ATA_IO:
 			ata_command_sbuf(&ccb->ataio, &sb);
-			sbuf_printf(&sb, "\n");
 			break;
 		case XPT_SCSI_IO:
 #ifdef _KERNEL
@@ -426,17 +425,22 @@ cam_error_string(struct cam_device *device, union ccb *ccb, char *str,
 #else /* !_KERNEL */
 			scsi_command_string(device, &ccb->csio, &sb);
 #endif /* _KERNEL/!_KERNEL */
-			sbuf_printf(&sb, "\n");
 			break;
 		case XPT_SMP_IO:
 			smp_command_sbuf(&ccb->smpio, &sb, path_str, 79 -
 					 strlen(path_str), (proto_flags &
 					 CAM_ESMF_PRINT_FULL_CMD) ? 79 : 0);
-			sbuf_printf(&sb, "\n");
+			break;
+		case XPT_NVME_IO:
+		case XPT_NVME_ADMIN:
+			nvme_command_sbuf(&ccb->nvmeio, &sb);
 			break;
 		default:
+			sbuf_printf(&sb, "CAM func %#x",
+			    ccb->ccb_h.func_code);
 			break;
 		}
+		sbuf_printf(&sb, "\n");
 	}
 
 	if (flags & CAM_ESF_CAM_STATUS) {
diff --git a/freebsd/sys/cam/nvme/nvme_all.h b/freebsd/sys/cam/nvme/nvme_all.h
index e31c1e5..8ebbfff 100644
--- a/freebsd/sys/cam/nvme/nvme_all.h
+++ b/freebsd/sys/cam/nvme/nvme_all.h
@@ -42,8 +42,10 @@ int	nvme_identify_match(caddr_t identbuffer, caddr_t table_entry);
 
 struct sbuf;
 void	nvme_print_ident(const struct nvme_controller_data *, const struct nvme_namespace_data *, struct sbuf *);
-const char *nvme_op_string(const struct nvme_command *);
+const char *nvme_op_string(const struct nvme_command *, int admin);
 const char *nvme_cmd_string(const struct nvme_command *, char *, size_t);
+void nvme_cmd_sbuf(const struct nvme_command *, struct sbuf *sb);
+int nvme_command_sbuf(struct ccb_nvmeio *nvmeio, struct sbuf *sb);
 const void *nvme_get_identify_cntrl(struct cam_periph *);
 const void *nvme_get_identify_ns(struct cam_periph *);
 
diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c
index 3675723..3aab5aab 100644
--- a/freebsd/sys/cam/scsi/scsi_all.c
+++ b/freebsd/sys/cam/scsi/scsi_all.c
@@ -382,7 +382,7 @@ static struct op_table_entry scsi_op_codes[] = {
 	{ 0x40,	D | T | L | P | W | R | O | M | S | C, "CHANGE DEFINITION" },
 	/* 41  O               WRITE SAME(10) */
 	{ 0x41,	D, "WRITE SAME(10)" },
-	/* 42       O          UNMAP */
+	/* 42  O               UNMAP */
 	{ 0x42,	D, "UNMAP" },
 	/* 42       O          READ SUB-CHANNEL */
 	{ 0x42,	R, "READ SUB-CHANNEL" },
@@ -397,7 +397,8 @@ static struct op_table_entry scsi_op_codes[] = {
 	{ 0x46,	R, "GET CONFIGURATION" },
 	/* 47       O          PLAY AUDIO MSF */
 	{ 0x47,	R, "PLAY AUDIO MSF" },
-	/* 48 */
+	/* 48  O               SANITIZE */
+	{ 0x48,	D, "SANITIZE" },
 	/* 49 */
 	/* 4A       M          GET EVENT STATUS NOTIFICATION */
 	{ 0x4A,	R, "GET EVENT STATUS NOTIFICATION" },
@@ -1165,10 +1166,10 @@ static struct asc_table_entry asc_table[] = {
 	{ SST(0x04, 0x1A, SS_RDEF,	/* XXX TBD */
 	    "Logical unit not ready, START/STOP UNIT command in progress") },
 	/* D         B    */
-	{ SST(0x04, 0x1B, SS_RDEF,	/* XXX TBD */
+	{ SST(0x04, 0x1B, SS_WAIT | EBUSY,
 	    "Logical unit not ready, sanitize in progress") },
 	/* DT     MAEB    */
-	{ SST(0x04, 0x1C, SS_RDEF,	/* XXX TBD */
+	{ SST(0x04, 0x1C, SS_START | SSQ_DECREMENT_COUNT | ENXIO,
 	    "Logical unit not ready, additional power use not yet granted") },
 	/* D              */
 	{ SST(0x04, 0x1D, SS_RDEF,	/* XXX TBD */
@@ -1456,7 +1457,7 @@ static struct asc_table_entry asc_table[] = {
 	{ SST(0x11, 0x14, SS_RDEF,	/* XXX TBD */
 	    "Read error - LBA marked bad by application client") },
 	/* D              */
-	{ SST(0x11, 0x15, SS_RDEF,	/* XXX TBD */
+	{ SST(0x11, 0x15, SS_FATAL | EIO,
 	    "Write after sanitize required") },
 	/* D   W O   BK   */
 	{ SST(0x12, 0x00, SS_RDEF,
@@ -2067,7 +2068,7 @@ static struct asc_table_entry asc_table[] = {
 	{ SST(0x31, 0x02, SS_RDEF,	/* XXX TBD */
 	    "Zoned formatting failed due to spare linking") },
 	/* D         B    */
-	{ SST(0x31, 0x03, SS_RDEF,	/* XXX TBD */
+	{ SST(0x31, 0x03, SS_FATAL | EIO,
 	    "SANITIZE command failed") },
 	/* D   W O   BK   */
 	{ SST(0x32, 0x00, SS_RDEF,
@@ -8400,6 +8401,38 @@ scsi_ata_read_log(struct ccb_scsiio *csio, uint32_t retries,
 	return (retval);
 }
 
+int scsi_ata_setfeatures(struct ccb_scsiio *csio, uint32_t retries,
+			 void (*cbfcnp)(struct cam_periph *, union ccb *),
+			 uint8_t tag_action, uint8_t feature,
+			 uint64_t lba, uint32_t count,
+			 uint8_t sense_len, uint32_t timeout)
+{
+	return (scsi_ata_pass(csio,
+		retries,
+		cbfcnp,
+		/*flags*/CAM_DIR_NONE,
+		tag_action,
+		/*protocol*/AP_PROTO_PIO_IN,
+		/*ata_flags*/AP_FLAG_TDIR_FROM_DEV |
+			     AP_FLAG_BYT_BLOK_BYTES |
+			     AP_FLAG_TLEN_SECT_CNT,
+		/*features*/feature,
+		/*sector_count*/count,
+		/*lba*/lba,
+		/*command*/ATA_SETFEATURES,
+		/*device*/ 0,
+		/*icc*/ 0,
+		/*auxiliary*/0,
+		/*control*/0,
+		/*data_ptr*/NULL,
+		/*dxfer_len*/0,
+		/*cdb_storage*/NULL,
+		/*cdb_storage_len*/0,
+		/*minimum_cmd_size*/0,
+		sense_len,
+		timeout));
+}
+
 /*
  * Note! This is an unusual CDB building function because it can return
  * an error in the event that the command in question requires a variable
diff --git a/freebsd/sys/cam/scsi/scsi_all.h b/freebsd/sys/cam/scsi/scsi_all.h
index 735d068..467b955 100644
--- a/freebsd/sys/cam/scsi/scsi_all.h
+++ b/freebsd/sys/cam/scsi/scsi_all.h
@@ -264,7 +264,9 @@ struct scsi_mode_hdr_10
 	u_int8_t datalen[2];
 	u_int8_t medium_type;
 	u_int8_t dev_specific;
-	u_int8_t reserved[2];
+	u_int8_t flags;
+#define	SMH_LONGLBA	0x01
+	u_int8_t reserved;
 	u_int8_t block_descr_len[2];
 };
 
@@ -276,6 +278,20 @@ struct scsi_mode_block_descr
 	u_int8_t block_len[3];
 };
 
+struct scsi_mode_block_descr_dshort
+{
+	u_int8_t num_blocks[4];
+	u_int8_t reserved;
+	u_int8_t block_len[3];
+};
+
+struct scsi_mode_block_descr_dlong
+{
+	u_int8_t num_blocks[8];
+	u_int8_t reserved[4];
+	u_int8_t block_len[4];
+};
+
 struct scsi_per_res_in
 {
 	u_int8_t opcode;
@@ -568,6 +584,7 @@ struct scsi_log_sense
 #define	SLS_ERROR_NONMEDIUM_PAGE	0x06
 #define	SLS_ERROR_LASTN_PAGE		0x07
 #define	SLS_LOGICAL_BLOCK_PROVISIONING	0x0c
+#define	SLS_TEMPERATURE			0x0d
 #define	SLS_SELF_TEST_PAGE		0x10
 #define	SLS_SOLID_STATE_MEDIA		0x11
 #define	SLS_STAT_AND_PERF		0x19
@@ -683,6 +700,14 @@ struct scsi_log_informational_exceptions {
 	uint8_t	temperature;
 };
 
+struct scsi_log_temperature {
+	struct scsi_log_param_header hdr;
+#define	SLP_TEMPERATURE			0x0000
+#define	SLP_REFTEMPERATURE		0x0001
+	uint8_t	reserved;
+	uint8_t	temperature;
+};
+
 struct scsi_control_page {
 	u_int8_t page_code;
 	u_int8_t page_length;
@@ -2763,6 +2788,19 @@ struct scsi_vpd_tpc
 };
 
 /*
+ * SCSI Feature Sets VPD Page
+ */
+struct scsi_vpd_sfs
+{
+	uint8_t device;
+	uint8_t page_code;
+#define	SVPD_SCSI_SFS			0x92
+	uint8_t page_length[2];
+	uint8_t reserved[4];
+	uint8_t codes[];
+};
+
+/*
  * Block Device Characteristics VPD Page based on
  * T10/1799-D Revision 31
  */
@@ -2803,11 +2841,15 @@ struct scsi_vpd_block_device_characteristics
 	uint8_t flags;
 #define	SVPD_VBULS		0x01
 #define	SVPD_FUAB		0x02
+#define	SVPD_BOCS		0x04
+#define	SVPD_RBWZ		0x08
 #define	SVPD_ZBC_NR		0x00	/* Not Reported */
 #define	SVPD_HAW_ZBC		0x10	/* Host Aware */
 #define	SVPD_DM_ZBC		0x20	/* Drive Managed */
 #define	SVPD_ZBC_MASK		0x30	/* Zoned mask */
-	uint8_t reserved[55];
+	uint8_t reserved[3];
+	uint8_t depopulation_time[4];
+	uint8_t reserved2[48];
 };
 
 #define SBDC_IS_PRESENT(bdc, length, field)				   \
@@ -2844,7 +2886,7 @@ struct scsi_vpd_logical_block_prov
 };
 
 /*
- * Block Limits VDP Page based on SBC-4 Revision 2
+ * Block Limits VDP Page based on SBC-4 Revision 17
  */
 struct scsi_vpd_block_limits
 {
@@ -2854,7 +2896,8 @@ struct scsi_vpd_block_limits
 	u_int8_t page_length[2];
 #define SVPD_BL_PL_BASIC	0x10
 #define SVPD_BL_PL_TP		0x3C
-	u_int8_t reserved1;
+	u_int8_t flags;
+#define	SVPD_BL_WSNZ		0x01
 	u_int8_t max_cmp_write_len;
 	u_int8_t opt_txfer_len_grain[2];
 	u_int8_t max_txfer_len[4];
@@ -4177,6 +4220,12 @@ int scsi_ata_read_log(struct ccb_scsiio *csio, uint32_t retries,
 		      uint8_t protocol, uint8_t *data_ptr, uint32_t dxfer_len,
 		      uint8_t sense_len, uint32_t timeout);
 
+int scsi_ata_setfeatures(struct ccb_scsiio *csio, uint32_t retries,
+			 void (*cbfcnp)(struct cam_periph *, union ccb *),
+			 uint8_t tag_action, uint8_t feature,
+			 uint64_t lba, uint32_t count,
+			 uint8_t sense_len, uint32_t timeout);
+
 int scsi_ata_pass(struct ccb_scsiio *csio, uint32_t retries,
 		  void (*cbfcnp)(struct cam_periph *, union ccb *),
 		  uint32_t flags, uint8_t tag_action,
diff --git a/freebsd/sys/dev/bge/if_bge.c b/freebsd/sys/dev/bge/if_bge.c
index a4a937b..b8c73e0 100644
--- a/freebsd/sys/dev/bge/if_bge.c
+++ b/freebsd/sys/dev/bge/if_bge.c
@@ -3253,6 +3253,8 @@ bge_mbox_reorder(struct bge_softc *sc)
 		bus = device_get_parent(dev);
 		if (device_get_devclass(dev) != pcib)
 			break;
+		if (device_get_devclass(bus) != pci)
+			break;
 		for (i = 0; i < nitems(mbox_reorder_lists); i++) {
 			if (pci_get_vendor(dev) ==
 			    mbox_reorder_lists[i].vendor &&
@@ -3264,8 +3266,6 @@ bge_mbox_reorder(struct bge_softc *sc)
 				return (1);
 			}
 		}
-		if (device_get_devclass(bus) != pci)
-			break;
 	}
 	return (0);
 }
diff --git a/freebsd/sys/dev/fdt/simplebus.c b/freebsd/sys/dev/fdt/simplebus.c
index 54b1707..583590d 100644
--- a/freebsd/sys/dev/fdt/simplebus.c
+++ b/freebsd/sys/dev/fdt/simplebus.c
@@ -64,13 +64,6 @@ static const struct ofw_bus_devinfo *simplebus_get_devinfo(device_t bus,
     device_t child);
 
 /*
- * local methods
- */
-
-static int simplebus_fill_ranges(phandle_t node,
-    struct simplebus_softc *sc);
-
-/*
  * Driver methods.
  */
 static device_method_t	simplebus_methods[] = {
@@ -186,7 +179,7 @@ simplebus_init(device_t dev, phandle_t node)
 	OF_getencprop(node, "#size-cells", &sc->scells, sizeof(sc->scells));
 }
 
-static int
+int
 simplebus_fill_ranges(phandle_t node, struct simplebus_softc *sc)
 {
 	int host_address_cells;
diff --git a/freebsd/sys/dev/fdt/simplebus.h b/freebsd/sys/dev/fdt/simplebus.h
index caccf16..bc69557 100644
--- a/freebsd/sys/dev/fdt/simplebus.h
+++ b/freebsd/sys/dev/fdt/simplebus.h
@@ -61,4 +61,6 @@ device_t simplebus_add_device(device_t dev, phandle_t node, u_int order,
     const char *name, int unit, struct simplebus_devinfo *di);
 struct simplebus_devinfo *simplebus_setup_dinfo(device_t dev, phandle_t node,
     struct simplebus_devinfo *di);
+int simplebus_fill_ranges(phandle_t node,
+    struct simplebus_softc *sc);
 #endif	/* _FDT_SIMPLEBUS_H */
diff --git a/freebsd/sys/dev/gpio/gpiobus.c b/freebsd/sys/dev/gpio/gpiobus.c
index 2b1899e..d256ee4 100644
--- a/freebsd/sys/dev/gpio/gpiobus.c
+++ b/freebsd/sys/dev/gpio/gpiobus.c
@@ -257,13 +257,6 @@ gpiobus_alloc_ivars(struct gpiobus_ivar *devi)
 	    M_NOWAIT | M_ZERO);
 	if (devi->pins == NULL)
 		return (ENOMEM);
-	devi->flags = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF,
-	    M_NOWAIT | M_ZERO);
-	if (devi->flags == NULL) {
-		free(devi->pins, M_DEVBUF);
-		return (ENOMEM);
-	}
-
 	return (0);
 }
 
@@ -271,14 +264,11 @@ void
 gpiobus_free_ivars(struct gpiobus_ivar *devi)
 {
 
-	if (devi->flags) {
-		free(devi->flags, M_DEVBUF);
-		devi->flags = NULL;
-	}
 	if (devi->pins) {
 		free(devi->pins, M_DEVBUF);
 		devi->pins = NULL;
 	}
+	devi->npins = 0;
 }
 
 int
@@ -328,6 +318,34 @@ gpiobus_release_pin(device_t bus, uint32_t pin)
 }
 
 static int
+gpiobus_acquire_child_pins(device_t dev, device_t child)
+{
+	struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
+	int i;
+
+	for (i = 0; i < devi->npins; i++) {
+		/* Reserve the GPIO pin. */
+		if (gpiobus_acquire_pin(dev, devi->pins[i]) != 0) {
+			device_printf(child, "cannot acquire pin %d\n",
+			    devi->pins[i]);
+			while (--i >= 0) {
+				(void)gpiobus_release_pin(dev,
+				    devi->pins[i]);
+			}
+			gpiobus_free_ivars(devi);
+			return (EBUSY);
+		}
+	}
+	for (i = 0; i < devi->npins; i++) {
+		/* Use the child name as pin name. */
+		GPIOBUS_PIN_SETNAME(dev, devi->pins[i],
+		    device_get_nameunit(child));
+
+	}
+	return (0);
+}
+
+static int
 gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask)
 {
 	struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
@@ -351,17 +369,66 @@ gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask)
 	for (i = 0; i < 32; i++) {
 		if ((mask & (1 << i)) == 0)
 			continue;
-		/* Reserve the GPIO pin. */
-		if (gpiobus_acquire_pin(sc->sc_busdev, i) != 0) {
-			gpiobus_free_ivars(devi);
-			return (EINVAL);
-		}
 		devi->pins[npins++] = i;
-		/* Use the child name as pin name. */
-		GPIOBUS_PIN_SETNAME(sc->sc_busdev, i,
-		    device_get_nameunit(child));
 	}
 
+	if (gpiobus_acquire_child_pins(sc->sc_busdev, child) != 0)
+		return (EINVAL);
+	return (0);
+}
+
+static int
+gpiobus_parse_pin_list(struct gpiobus_softc *sc, device_t child,
+    const char *pins)
+{
+	struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
+	const char *p;
+	char *endp;
+	unsigned long pin;
+	int i, npins;
+
+	npins = 0;
+	p = pins;
+	for (;;) {
+		pin = strtoul(p, &endp, 0);
+		if (endp == p)
+			break;
+		npins++;
+		if (*endp == '\0')
+			break;
+		p = endp + 1;
+	}
+
+	if (*endp != '\0') {
+		device_printf(child, "garbage in the pin list: %s\n", endp);
+		return (EINVAL);
+	}
+	if (npins == 0) {
+		device_printf(child, "empty pin list\n");
+		return (EINVAL);
+	}
+
+	devi->npins = npins;
+	if (gpiobus_alloc_ivars(devi) != 0) {
+		device_printf(child, "cannot allocate device ivars\n");
+		return (EINVAL);
+	}
+
+	i = 0;
+	p = pins;
+	for (;;) {
+		pin = strtoul(p, &endp, 0);
+
+		devi->pins[i] = pin;
+
+		if (*endp == '\0')
+			break;
+		i++;
+		p = endp + 1;
+	}
+
+	if (gpiobus_acquire_child_pins(sc->sc_busdev, child) != 0)
+		return (EINVAL);
 	return (0);
 }
 
@@ -541,15 +608,26 @@ gpiobus_hinted_child(device_t bus, const char *dname, int dunit)
 	struct gpiobus_softc *sc = GPIOBUS_SOFTC(bus);
 	struct gpiobus_ivar *devi;
 	device_t child;
-	int irq, pins;
+	const char *pins;
+	int irq, pinmask;
 
 	child = BUS_ADD_CHILD(bus, 0, dname, dunit);
 	devi = GPIOBUS_IVAR(child);
-	resource_int_value(dname, dunit, "pins", &pins);
-	if (gpiobus_parse_pins(sc, child, pins)) {
-		resource_list_free(&devi->rl);
-		free(devi, M_DEVBUF);
-		device_delete_child(bus, child);
+	if (resource_int_value(dname, dunit, "pins", &pinmask) == 0) {
+		if (gpiobus_parse_pins(sc, child, pinmask)) {
+			resource_list_free(&devi->rl);
+			free(devi, M_DEVBUF);
+			device_delete_child(bus, child);
+			return;
+		}
+	}
+	else if (resource_string_value(dname, dunit, "pin_list", &pins) == 0) {
+		if (gpiobus_parse_pin_list(sc, child, pins)) {
+			resource_list_free(&devi->rl);
+			free(devi, M_DEVBUF);
+			device_delete_child(bus, child);
+			return;
+		}
 	}
 	if (resource_int_value(dname, dunit, "irq", &irq) == 0) {
 		if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0)
@@ -576,6 +654,61 @@ gpiobus_set_resource(device_t dev, device_t child, int type, int rid,
 	return (0);
 }
 
+static int
+gpiobus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct gpiobus_ivar *devi;
+
+	devi = GPIOBUS_IVAR(child);
+        switch (which) {
+	case GPIOBUS_IVAR_NPINS:
+		*result = devi->npins;
+		break;
+	case GPIOBUS_IVAR_PINS:
+		/* Children do not ever need to directly examine this. */
+		return (ENOTSUP);
+        default:
+                return (ENOENT);
+        }
+
+	return (0);
+}
+
+static int
+gpiobus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+	struct gpiobus_ivar *devi;
+	const uint32_t *ptr;
+	int i;
+
+	devi = GPIOBUS_IVAR(child);
+        switch (which) {
+	case GPIOBUS_IVAR_NPINS:
+		/* GPIO ivars are set once. */
+		if (devi->npins != 0) {
+			return (EBUSY);
+		}
+		devi->npins = value;
+		if (gpiobus_alloc_ivars(devi) != 0) {
+			device_printf(child, "cannot allocate device ivars\n");
+			devi->npins = 0;
+			return (ENOMEM);
+		}
+		break;
+	case GPIOBUS_IVAR_PINS:
+		ptr = (const uint32_t *)value;
+		for (i = 0; i < devi->npins; i++)
+			devi->pins[i] = ptr[i];
+		if (gpiobus_acquire_child_pins(dev, child) != 0)
+			return (EBUSY);
+		break;
+        default:
+                return (ENOENT);
+        }
+
+        return (0);
+}
+
 static struct resource *
 gpiobus_alloc_resource(device_t bus, device_t child, int type, int *rid,
     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
@@ -835,6 +968,8 @@ static device_method_t gpiobus_methods[] = {
 	DEVMETHOD(bus_child_pnpinfo_str, gpiobus_child_pnpinfo_str),
 	DEVMETHOD(bus_child_location_str, gpiobus_child_location_str),
 	DEVMETHOD(bus_hinted_child,	gpiobus_hinted_child),
+	DEVMETHOD(bus_read_ivar,        gpiobus_read_ivar),
+	DEVMETHOD(bus_write_ivar,       gpiobus_write_ivar),
 
 	/* GPIO protocol */
 	DEVMETHOD(gpiobus_acquire_bus,	gpiobus_acquire_bus),
diff --git a/freebsd/sys/dev/gpio/gpiobusvar.h b/freebsd/sys/dev/gpio/gpiobusvar.h
index 2967729..3ba8993 100644
--- a/freebsd/sys/dev/gpio/gpiobusvar.h
+++ b/freebsd/sys/dev/gpio/gpiobusvar.h
@@ -107,10 +107,22 @@ struct gpiobus_ivar
 {
 	struct resource_list	rl;	/* isr resource list */
 	uint32_t	npins;	/* pins total */
-	uint32_t	*flags;	/* pins flags */
 	uint32_t	*pins;	/* pins map */
 };
 
+enum gpiobus_ivars {
+	GPIOBUS_IVAR_NPINS	= 10500,
+	GPIOBUS_IVAR_PINS,
+};
+
+#define GPIOBUS_ACCESSOR(var, ivar, type)                                 \
+        __BUS_ACCESSOR(gpiobus, var, GPIOBUS, ivar, type)
+
+GPIOBUS_ACCESSOR(npins,		NPINS,		uint32_t)
+GPIOBUS_ACCESSOR(pins,		PINS,		const uint32_t *)
+
+#undef GPIOBUS_ACCESSOR
+
 #ifdef FDT
 struct ofw_gpiobus_devinfo {
 	struct gpiobus_ivar	opd_dinfo;
diff --git a/freebsd/sys/dev/gpio/ofw_gpiobus.c b/freebsd/sys/dev/gpio/ofw_gpiobus.c
index ac0ea9b..1cf3aa8 100644
--- a/freebsd/sys/dev/gpio/ofw_gpiobus.c
+++ b/freebsd/sys/dev/gpio/ofw_gpiobus.c
@@ -327,10 +327,8 @@ ofw_gpiobus_setup_devinfo(device_t bus, device_t child, phandle_t node)
 		ofw_gpiobus_destroy_devinfo(bus, dinfo);
 		return (NULL);
 	}
-	for (i = 0; i < devi->npins; i++) {
-		devi->flags[i] = pins[i].flags;
+	for (i = 0; i < devi->npins; i++)
 		devi->pins[i] = pins[i].pin;
-	}
 	free(pins, M_DEVBUF);
 	/* Parse the interrupt resources. */
 	if (ofw_bus_intr_to_rl(bus, node, &dinfo->opd_dinfo.rl, NULL) != 0) {
diff --git a/freebsd/sys/dev/mmc/mmcsd.c b/freebsd/sys/dev/mmc/mmcsd.c
index e469c1d..077f8d7 100644
--- a/freebsd/sys/dev/mmc/mmcsd.c
+++ b/freebsd/sys/dev/mmc/mmcsd.c
@@ -813,7 +813,7 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt,
 		    speed / 1000000, (speed / 100000) % 10,
 		    mmcsd_bus_bit_width(dev), sc->max_data);
 	} else if (type == EXT_CSD_PART_CONFIG_ACC_RPMB) {
-		printf("%s: %ju%sB partion %d%s at %s\n", part->name, bytes,
+		printf("%s: %ju%sB partition %d%s at %s\n", part->name, bytes,
 		    unit, type, ro ? " (read-only)" : "",
 		    device_get_nameunit(dev));
 	} else {
@@ -849,12 +849,12 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt,
 			}
 		}
 		if (ext == NULL)
-			printf("%s%d: %ju%sB partion %d%s%s at %s\n",
+			printf("%s%d: %ju%sB partition %d%s%s at %s\n",
 			    part->name, cnt, bytes, unit, type, enh ?
 			    " enhanced" : "", ro ? " (read-only)" : "",
 			    device_get_nameunit(dev));
 		else
-			printf("%s%d: %ju%sB partion %d extended 0x%x "
+			printf("%s%d: %ju%sB partition %d extended 0x%x "
 			    "(%s)%s at %s\n", part->name, cnt, bytes, unit,
 			    type, extattr, ext, ro ? " (read-only)" : "",
 			    device_get_nameunit(dev));
diff --git a/freebsd/sys/dev/nvme/nvme.h b/freebsd/sys/dev/nvme/nvme.h
index ae48a82..0d4a18b 100644
--- a/freebsd/sys/dev/nvme/nvme.h
+++ b/freebsd/sys/dev/nvme/nvme.h
@@ -40,6 +40,7 @@
 
 #define	NVME_PASSTHROUGH_CMD		_IOWR('n', 0, struct nvme_pt_command)
 #define	NVME_RESET_CONTROLLER		_IO('n', 1)
+#define	NVME_GET_NSID			_IOR('n', 2, struct nvme_get_nsid)
 
 #define	NVME_IO_TEST			_IOWR('n', 100, struct nvme_io_test)
 #define	NVME_BIO_TEST			_IOWR('n', 101, struct nvme_io_test)
@@ -69,15 +70,39 @@
 #define NVME_CAP_LO_REG_AMS_MASK			(0x3)
 #define NVME_CAP_LO_REG_TO_SHIFT			(24)
 #define NVME_CAP_LO_REG_TO_MASK				(0xFF)
+#define NVME_CAP_LO_MQES(x) \
+	(((x) >> NVME_CAP_LO_REG_MQES_SHIFT) & NVME_CAP_LO_REG_MQES_MASK)
+#define NVME_CAP_LO_CQR(x) \
+	(((x) >> NVME_CAP_LO_REG_CQR_SHIFT) & NVME_CAP_LO_REG_CQR_MASK)
+#define NVME_CAP_LO_AMS(x) \
+	(((x) >> NVME_CAP_LO_REG_AMS_SHIFT) & NVME_CAP_LO_REG_AMS_MASK)
+#define NVME_CAP_LO_TO(x) \
+	(((x) >> NVME_CAP_LO_REG_TO_SHIFT) & NVME_CAP_LO_REG_TO_MASK)
 
 #define NVME_CAP_HI_REG_DSTRD_SHIFT			(0)
 #define NVME_CAP_HI_REG_DSTRD_MASK			(0xF)
+#define NVME_CAP_HI_REG_NSSRS_SHIFT			(4)
+#define NVME_CAP_HI_REG_NSSRS_MASK			(0x1)
 #define NVME_CAP_HI_REG_CSS_NVM_SHIFT			(5)
 #define NVME_CAP_HI_REG_CSS_NVM_MASK			(0x1)
+#define NVME_CAP_HI_REG_BPS_SHIFT			(13)
+#define NVME_CAP_HI_REG_BPS_MASK			(0x1)
 #define NVME_CAP_HI_REG_MPSMIN_SHIFT			(16)
 #define NVME_CAP_HI_REG_MPSMIN_MASK			(0xF)
 #define NVME_CAP_HI_REG_MPSMAX_SHIFT			(20)
 #define NVME_CAP_HI_REG_MPSMAX_MASK			(0xF)
+#define NVME_CAP_HI_REG_PMRS_SHIFT			(24)
+#define NVME_CAP_HI_REG_PMRS_MASK			(0x1)
+#define NVME_CAP_HI_REG_CMBS_SHIFT			(25)
+#define NVME_CAP_HI_REG_CMBS_MASK			(0x1)
+#define NVME_CAP_HI_DSTRD(x) \
+	(((x) >> NVME_CAP_HI_REG_DSTRD_SHIFT) & NVME_CAP_HI_REG_DSTRD_MASK)
+#define NVME_CAP_HI_CSS_NVM(x) \
+	(((x) >> NVME_CAP_HI_REG_CSS_NVM_SHIFT) & NVME_CAP_HI_REG_CSS_NVM_MASK)
+#define NVME_CAP_HI_MPSMIN(x) \
+	(((x) >> NVME_CAP_HI_REG_MPSMIN_SHIFT) & NVME_CAP_HI_REG_MPSMIN_MASK)
+#define NVME_CAP_HI_MPSMAX(x) \
+	(((x) >> NVME_CAP_HI_REG_MPSMAX_SHIFT) & NVME_CAP_HI_REG_MPSMAX_MASK)
 
 #define NVME_CC_REG_EN_SHIFT				(0)
 #define NVME_CC_REG_EN_MASK				(0x1)
@@ -100,6 +125,10 @@
 #define NVME_CSTS_REG_CFS_MASK				(0x1)
 #define NVME_CSTS_REG_SHST_SHIFT			(2)
 #define NVME_CSTS_REG_SHST_MASK				(0x3)
+#define NVME_CSTS_REG_NVSRO_SHIFT			(4)
+#define NVME_CSTS_REG_NVSRO_MASK			(0x1)
+#define NVME_CSTS_REG_PP_SHIFT				(5)
+#define NVME_CSTS_REG_PP_MASK				(0x1)
 
 #define NVME_CSTS_GET_SHST(csts)			(((csts) >> NVME_CSTS_REG_SHST_SHIFT) & NVME_CSTS_REG_SHST_MASK)
 
@@ -119,6 +148,8 @@
 #define NVME_STATUS_SC_MASK				(0xFF)
 #define NVME_STATUS_SCT_SHIFT				(9)
 #define NVME_STATUS_SCT_MASK				(0x7)
+#define NVME_STATUS_CRD_SHIFT				(12)
+#define NVME_STATUS_CRD_MASK				(0x3)
 #define NVME_STATUS_M_SHIFT				(14)
 #define NVME_STATUS_M_MASK				(0x1)
 #define NVME_STATUS_DNR_SHIFT				(15)
@@ -159,6 +190,9 @@
 /* SR-IOV Virtual Function */
 #define NVME_CTRLR_DATA_MIC_SRIOVVF_SHIFT		(2)
 #define NVME_CTRLR_DATA_MIC_SRIOVVF_MASK		(0x1)
+/* Asymmetric Namespace Access Reporting */
+#define NVME_CTRLR_DATA_MIC_ANAR_SHIFT			(3)
+#define NVME_CTRLR_DATA_MIC_ANAR_MASK			(0x1)
 
 /** OACS - optional admin command support */
 /* supports security send/receive commands */
@@ -188,6 +222,9 @@
 /* supports Doorbell Buffer Config */
 #define NVME_CTRLR_DATA_OACS_DBBUFFER_SHIFT		(8)
 #define NVME_CTRLR_DATA_OACS_DBBUFFER_MASK		(0x1)
+/* supports Get LBA Status */
+#define NVME_CTRLR_DATA_OACS_GETLBA_SHIFT		(9)
+#define NVME_CTRLR_DATA_OACS_GETLBA_MASK		(0x1)
 
 /** firmware updates */
 /* first slot is read-only */
@@ -196,6 +233,9 @@
 /* number of firmware slots */
 #define NVME_CTRLR_DATA_FRMW_NUM_SLOTS_SHIFT		(1)
 #define NVME_CTRLR_DATA_FRMW_NUM_SLOTS_MASK		(0x7)
+/* firmware activation without reset */
+#define NVME_CTRLR_DATA_FRMW_ACT_WO_RESET_SHIFT		(4)
+#define NVME_CTRLR_DATA_FRMW_ACT_WO_RESET_MASK		(0x1)
 
 /** log page attributes */
 /* per namespace smart/health log page */
@@ -212,6 +252,26 @@
 #define NVME_CTRLR_DATA_APSTA_APST_SUPP_SHIFT		(0)
 #define NVME_CTRLR_DATA_APSTA_APST_SUPP_MASK		(0x1)
 
+/** Sanitize Capabilities */
+/* Crypto Erase Support  */
+#define NVME_CTRLR_DATA_SANICAP_CES_SHIFT		(0)
+#define NVME_CTRLR_DATA_SANICAP_CES_MASK		(0x1)
+/* Block Erase Support */
+#define NVME_CTRLR_DATA_SANICAP_BES_SHIFT		(1)
+#define NVME_CTRLR_DATA_SANICAP_BES_MASK		(0x1)
+/* Overwrite Support */
+#define NVME_CTRLR_DATA_SANICAP_OWS_SHIFT		(2)
+#define NVME_CTRLR_DATA_SANICAP_OWS_MASK		(0x1)
+/* No-Deallocate Inhibited  */
+#define NVME_CTRLR_DATA_SANICAP_NDI_SHIFT		(29)
+#define NVME_CTRLR_DATA_SANICAP_NDI_MASK		(0x1)
+/* No-Deallocate Modifies Media After Sanitize */
+#define NVME_CTRLR_DATA_SANICAP_NODMMAS_SHIFT		(30)
+#define NVME_CTRLR_DATA_SANICAP_NODMMAS_MASK		(0x3)
+#define NVME_CTRLR_DATA_SANICAP_NODMMAS_UNDEF		(0)
+#define NVME_CTRLR_DATA_SANICAP_NODMMAS_NO		(1)
+#define NVME_CTRLR_DATA_SANICAP_NODMMAS_YES		(2)
+
 /** submission queue entry size */
 #define NVME_CTRLR_DATA_SQES_MIN_SHIFT			(0)
 #define NVME_CTRLR_DATA_SQES_MIN_MASK			(0xF)
@@ -239,6 +299,8 @@
 #define NVME_CTRLR_DATA_ONCS_RESERV_MASK		(0x1)
 #define NVME_CTRLR_DATA_ONCS_TIMESTAMP_SHIFT		(6)
 #define NVME_CTRLR_DATA_ONCS_TIMESTAMP_MASK		(0x1)
+#define NVME_CTRLR_DATA_ONCS_VERIFY_SHIFT		(7)
+#define NVME_CTRLR_DATA_ONCS_VERIFY_MASK		(0x1)
 
 /** Fused Operation Support */
 #define NVME_CTRLR_DATA_FUSES_CNW_SHIFT		(0)
@@ -253,8 +315,15 @@
 #define NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_MASK		(0x1)
 
 /** volatile write cache */
+/* volatile write cache present */
 #define NVME_CTRLR_DATA_VWC_PRESENT_SHIFT		(0)
 #define NVME_CTRLR_DATA_VWC_PRESENT_MASK		(0x1)
+/* flush all namespaces supported */
+#define NVME_CTRLR_DATA_VWC_ALL_SHIFT			(1)
+#define NVME_CTRLR_DATA_VWC_ALL_MASK			(0x3)
+#define NVME_CTRLR_DATA_VWC_ALL_UNKNOWN			(0)
+#define NVME_CTRLR_DATA_VWC_ALL_NO			(2)
+#define NVME_CTRLR_DATA_VWC_ALL_YES			(3)
 
 /** namespace features */
 /* thin provisioning */
@@ -269,6 +338,9 @@
 /* NGUID and EUI64 fields are not reusable */
 #define NVME_NS_DATA_NSFEAT_NO_ID_REUSE_SHIFT		(3)
 #define NVME_NS_DATA_NSFEAT_NO_ID_REUSE_MASK		(0x1)
+/* NPWG, NPWA, NPDG, NPDA, and NOWS are valid */
+#define NVME_NS_DATA_NSFEAT_NPVALID_SHIFT		(4)
+#define NVME_NS_DATA_NSFEAT_NPVALID_MASK		(0x1)
 
 /** formatted lba size */
 #define NVME_NS_DATA_FLBAS_FORMAT_SHIFT			(0)
@@ -387,6 +459,35 @@ enum nvme_critical_warning_state {
 #define NVME_FIRMWARE_PAGE_AFI_SLOT_SHIFT		(0)
 #define NVME_FIRMWARE_PAGE_AFI_SLOT_MASK		(0x7)
 
+/* Commands Supported and Effects */
+#define	NVME_CE_PAGE_CSUP_SHIFT				(0)
+#define	NVME_CE_PAGE_CSUP_MASK				(0x1)
+#define	NVME_CE_PAGE_LBCC_SHIFT				(1)
+#define	NVME_CE_PAGE_LBCC_MASK				(0x1)
+#define	NVME_CE_PAGE_NCC_SHIFT				(2)
+#define	NVME_CE_PAGE_NCC_MASK				(0x1)
+#define	NVME_CE_PAGE_NIC_SHIFT				(3)
+#define	NVME_CE_PAGE_NIC_MASK				(0x1)
+#define	NVME_CE_PAGE_CCC_SHIFT				(4)
+#define	NVME_CE_PAGE_CCC_MASK				(0x1)
+#define	NVME_CE_PAGE_CSE_SHIFT				(16)
+#define	NVME_CE_PAGE_CSE_MASK				(0x7)
+#define	NVME_CE_PAGE_UUID_SHIFT				(19)
+#define	NVME_CE_PAGE_UUID_MASK				(0x1)
+
+/* Sanitize Status */
+#define	NVME_SS_PAGE_SSTAT_STATUS_SHIFT			(0)
+#define	NVME_SS_PAGE_SSTAT_STATUS_MASK			(0x7)
+#define	NVME_SS_PAGE_SSTAT_STATUS_NEVER			(0)
+#define	NVME_SS_PAGE_SSTAT_STATUS_COMPLETED		(1)
+#define	NVME_SS_PAGE_SSTAT_STATUS_INPROG		(2)
+#define	NVME_SS_PAGE_SSTAT_STATUS_FAILED		(3)
+#define	NVME_SS_PAGE_SSTAT_STATUS_COMPLETEDWD		(4)
+#define	NVME_SS_PAGE_SSTAT_PASSES_SHIFT			(3)
+#define	NVME_SS_PAGE_SSTAT_PASSES_MASK			(0x1f)
+#define	NVME_SS_PAGE_SSTAT_GDE_SHIFT			(8)
+#define	NVME_SS_PAGE_SSTAT_GDE_MASK			(0x1)
+
 /* CC register SHN field values */
 enum shn_value {
 	NVME_SHN_NORMAL		= 0x1,
@@ -402,34 +503,37 @@ enum shst_value {
 
 struct nvme_registers
 {
-	/** controller capabilities */
-	uint32_t		cap_lo;
-	uint32_t		cap_hi;
-
-	uint32_t		vs;	/* version */
-	uint32_t		intms;	/* interrupt mask set */
-	uint32_t		intmc;	/* interrupt mask clear */
-
-	/** controller configuration */
-	uint32_t		cc;
-
-	uint32_t		reserved1;
-
-	/** controller status */
-	uint32_t		csts;
-
-	uint32_t		reserved2;
-
-	/** admin queue attributes */
-	uint32_t		aqa;
-
-	uint64_t		asq;	/* admin submission queue base addr */
-	uint64_t		acq;	/* admin completion queue base addr */
-	uint32_t		reserved3[0x3f2];
-
+	uint32_t	cap_lo; /* controller capabilities */
+	uint32_t	cap_hi;
+	uint32_t	vs;	/* version */
+	uint32_t	intms;	/* interrupt mask set */
+	uint32_t	intmc;	/* interrupt mask clear */
+	uint32_t	cc;	/* controller configuration */
+	uint32_t	reserved1;
+	uint32_t	csts;	/* controller status */
+	uint32_t	nssr;	/* NVM Subsystem Reset */
+	uint32_t	aqa;	/* admin queue attributes */
+	uint64_t	asq;	/* admin submission queue base addr */
+	uint64_t	acq;	/* admin completion queue base addr */
+	uint32_t	cmbloc;	/* Controller Memory Buffer Location */
+	uint32_t	cmbsz;	/* Controller Memory Buffer Size */
+	uint32_t	bpinfo;	/* Boot Partition Information */
+	uint32_t	bprsel;	/* Boot Partition Read Select */
+	uint64_t	bpmbl;	/* Boot Partition Memory Buffer Location */
+	uint64_t	cmbmsc;	/* Controller Memory Buffer Memory Space Control */
+	uint32_t	cmbsts;	/* Controller Memory Buffer Status */
+	uint8_t		reserved3[3492]; /* 5Ch - DFFh */
+	uint32_t	pmrcap;	/* Persistent Memory Capabilities */
+	uint32_t	pmrctl;	/* Persistent Memory Region Control */
+	uint32_t	pmrsts;	/* Persistent Memory Region Status */
+	uint32_t	pmrebs;	/* Persistent Memory Region Elasticity Buffer Size */
+	uint32_t	pmrswtp; /* Persistent Memory Region Sustained Write Throughput */
+	uint32_t	pmrmsc_lo; /* Persistent Memory Region Controller Memory Space Control */
+	uint32_t	pmrmsc_hi;
+	uint8_t		reserved4[484]; /* E1Ch - FFFh */
 	struct {
-	    uint32_t		sq_tdbl; /* submission queue tail doorbell */
-	    uint32_t		cq_hdbl; /* completion queue head doorbell */
+	    uint32_t	sq_tdbl; /* submission queue tail doorbell */
+	    uint32_t	cq_hdbl; /* completion queue head doorbell */
 	} doorbell[1] __packed;
 } __packed;
 
@@ -504,6 +608,7 @@ enum nvme_status_code_type {
 	NVME_SCT_GENERIC		= 0x0,
 	NVME_SCT_COMMAND_SPECIFIC	= 0x1,
 	NVME_SCT_MEDIA_ERROR		= 0x2,
+	NVME_SCT_PATH_RELATED		= 0x3,
 	/* 0x3-0x6 - reserved */
 	NVME_SCT_VENDOR_SPECIFIC	= 0x7,
 };
@@ -542,6 +647,9 @@ enum nvme_generic_command_status_code {
 	NVME_SC_SANITIZE_IN_PROGRESS		= 0x1d,
 	NVME_SC_SGL_DATA_BLOCK_GRAN_INVALID	= 0x1e,
 	NVME_SC_NOT_SUPPORTED_IN_CMB		= 0x1f,
+	NVME_SC_NAMESPACE_IS_WRITE_PROTECTED	= 0x20,
+	NVME_SC_COMMAND_INTERRUPTED		= 0x21,
+	NVME_SC_TRANSIENT_TRANSPORT_ERROR	= 0x22,
 
 	NVME_SC_LBA_OUT_OF_RANGE		= 0x80,
 	NVME_SC_CAPACITY_EXCEEDED		= 0x81,
@@ -587,6 +695,9 @@ enum nvme_command_specific_status_code {
 	NVME_SC_INVALID_SEC_CTRLR_STATE		= 0x20,
 	NVME_SC_INVALID_NUM_OF_CTRLR_RESRC	= 0x21,
 	NVME_SC_INVALID_RESOURCE_ID		= 0x22,
+	NVME_SC_SANITIZE_PROHIBITED_WPMRE	= 0x23,
+	NVME_SC_ANA_GROUP_ID_INVALID		= 0x24,
+	NVME_SC_ANA_ATTACH_FAILED		= 0x25,
 
 	NVME_SC_CONFLICTING_ATTRIBUTES		= 0x80,
 	NVME_SC_INVALID_PROTECTION_INFO		= 0x81,
@@ -605,6 +716,17 @@ enum nvme_media_error_status_code {
 	NVME_SC_DEALLOCATED_OR_UNWRITTEN	= 0x87,
 };
 
+/* path related status codes */
+enum nvme_path_related_status_code {
+	NVME_SC_INTERNAL_PATH_ERROR		= 0x00,
+	NVME_SC_ASYMMETRIC_ACCESS_PERSISTENT_LOSS = 0x01,
+	NVME_SC_ASYMMETRIC_ACCESS_INACCESSIBLE	= 0x02,
+	NVME_SC_ASYMMETRIC_ACCESS_TRANSITION	= 0x03,
+	NVME_SC_CONTROLLER_PATHING_ERROR	= 0x60,
+	NVME_SC_HOST_PATHING_ERROR		= 0x70,
+	NVME_SC_COMMAND_ABOTHED_BY_HOST		= 0x71,
+};
+
 /* admin opcodes */
 enum nvme_admin_opcode {
 	NVME_OPC_DELETE_IO_SQ			= 0x00,
@@ -624,20 +746,27 @@ enum nvme_admin_opcode {
 	/* 0x0e-0x0f - reserved */
 	NVME_OPC_FIRMWARE_ACTIVATE		= 0x10,
 	NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD	= 0x11,
+	/* 0x12-0x13 - reserved */
 	NVME_OPC_DEVICE_SELF_TEST		= 0x14,
 	NVME_OPC_NAMESPACE_ATTACHMENT		= 0x15,
+	/* 0x16-0x17 - reserved */
 	NVME_OPC_KEEP_ALIVE			= 0x18,
 	NVME_OPC_DIRECTIVE_SEND			= 0x19,
 	NVME_OPC_DIRECTIVE_RECEIVE		= 0x1a,
+	/* 0x1b - reserved */
 	NVME_OPC_VIRTUALIZATION_MANAGEMENT	= 0x1c,
 	NVME_OPC_NVME_MI_SEND			= 0x1d,
 	NVME_OPC_NVME_MI_RECEIVE		= 0x1e,
+	/* 0x1f-0x7b - reserved */
 	NVME_OPC_DOORBELL_BUFFER_CONFIG		= 0x7c,
 
 	NVME_OPC_FORMAT_NVM			= 0x80,
 	NVME_OPC_SECURITY_SEND			= 0x81,
 	NVME_OPC_SECURITY_RECEIVE		= 0x82,
+	/* 0x83 - reserved */
 	NVME_OPC_SANITIZE			= 0x84,
+	/* 0x85 - reserved */
+	NVME_OPC_GET_LBA_STATUS			= 0x86,
 };
 
 /* nvme nvm opcodes */
@@ -648,11 +777,11 @@ enum nvme_nvm_opcode {
 	/* 0x03 - reserved */
 	NVME_OPC_WRITE_UNCORRECTABLE		= 0x04,
 	NVME_OPC_COMPARE			= 0x05,
-	/* 0x06 - reserved */
+	/* 0x06-0x07 - reserved */
 	NVME_OPC_WRITE_ZEROES			= 0x08,
-	/* 0x07 - reserved */
 	NVME_OPC_DATASET_MANAGEMENT		= 0x09,
-	/* 0x0a-0x0c - reserved */
+	/* 0x0a-0x0b - reserved */
+	NVME_OPC_VERIFY				= 0x0c,
 	NVME_OPC_RESERVATION_REGISTER		= 0x0d,
 	NVME_OPC_RESERVATION_REPORT		= 0x0e,
 	/* 0x0f-0x10 - reserved */
@@ -680,10 +809,21 @@ enum nvme_feature {
 	NVME_FEAT_KEEP_ALIVE_TIMER		= 0x0F,
 	NVME_FEAT_HOST_CONTROLLED_THERMAL_MGMT	= 0x10,
 	NVME_FEAT_NON_OP_POWER_STATE_CONFIG	= 0x11,
-	/* 0x12-0x77 - reserved */
+	NVME_FEAT_READ_RECOVERY_LEVEL_CONFIG	= 0x12,
+	NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG = 0x13,
+	NVME_FEAT_PREDICTABLE_LATENCY_MODE_WINDOW = 0x14,
+	NVME_FEAT_LBA_STATUS_INFORMATION_ATTRIBUTES = 0x15,
+	NVME_FEAT_HOST_BEHAVIOR_SUPPORT		= 0x16,
+	NVME_FEAT_SANITIZE_CONFIG		= 0x17,
+	NVME_FEAT_ENDURANCE_GROUP_EVENT_CONFIGURATION = 0x18,
+	/* 0x19-0x77 - reserved */
 	/* 0x78-0x7f - NVMe Management Interface */
 	NVME_FEAT_SOFTWARE_PROGRESS_MARKER	= 0x80,
-	/* 0x81-0xBF - command set specific (reserved) */
+	NVME_FEAT_HOST_IDENTIFIER		= 0x81,
+	NVME_FEAT_RESERVATION_NOTIFICATION_MASK	= 0x82,
+	NVME_FEAT_RESERVATION_PERSISTENCE	= 0x83,
+	NVME_FEAT_NAMESPACE_WRITE_PROTECTION_CONFIG = 0x84,
+	/* 0x85-0xBF - command set specific (reserved) */
 	/* 0xC0-0xFF - vendor specific */
 };
 
@@ -777,12 +917,27 @@ struct nvme_controller_data {
 	/** Controller Attributes */
 	uint32_t		ctratt;	/* bitfield really */
 
-	uint8_t			reserved1[12];
+	/** Read Recovery Levels Supported */
+	uint16_t		rrls;
+
+	uint8_t			reserved1[9];
+
+	/** Controller Type */
+	uint8_t			cntrltype;
 
 	/** FRU Globally Unique Identifier */
 	uint8_t			fguid[16];
 
-	uint8_t			reserved2[128];
+	/** Command Retry Delay Time 1 */
+	uint16_t		crdt1;
+
+	/** Command Retry Delay Time 2 */
+	uint16_t		crdt2;
+
+	/** Command Retry Delay Time 3 */
+	uint16_t		crdt3;
+
+	uint8_t			reserved2[122];
 
 	/* bytes 256-511: admin command set attributes */
 
@@ -862,7 +1017,34 @@ struct nvme_controller_data {
 	/** Sanitize Capabilities */
 	uint32_t		sanicap; /* Really a bitfield */
 
-	uint8_t			reserved3[180];
+	/** Host Memory Buffer Minimum Descriptor Entry Size */
+	uint32_t		hmminds;
+
+	/** Host Memory Maximum Descriptors Entries */
+	uint16_t		hmmaxd;
+
+	/** NVM Set Identifier Maximum */
+	uint16_t		nsetidmax;
+
+	/** Endurance Group Identifier Maximum */
+	uint16_t		endgidmax;
+
+	/** ANA Transition Time */
+	uint8_t			anatt;
+
+	/** Asymmetric Namespace Access Capabilities */
+	uint8_t			anacap;
+
+	/** ANA Group Identifier Maximum */
+	uint32_t		anagrpmax;
+
+	/** Number of ANA Group Identifiers */
+	uint32_t		nanagrpid;
+
+	/** Persistent Event Log Size */
+	uint32_t		pels;
+
+	uint8_t			reserved3[156];
 	/* bytes 512-703: nvm command set attributes */
 
 	/** submission queue entry size */
@@ -897,7 +1079,9 @@ struct nvme_controller_data {
 
 	/** NVM Vendor Specific Command Configuration */
 	uint8_t			nvscc;
-	uint8_t			reserved5;
+
+	/** Namespace Write Protection Capabilities */
+	uint8_t			nwpc;
 
 	/** Atomic Compare & Write Unit */
 	uint16_t		acwu;
@@ -906,8 +1090,11 @@ struct nvme_controller_data {
 	/** SGL Support */
 	uint32_t		sgls;
 
+	/** Maximum Number of Allowed Namespaces */
+	uint32_t		mnan;
+
 	/* bytes 540-767: Reserved */
-	uint8_t			reserved7[228];
+	uint8_t			reserved7[224];
 
 	/** NVM Subsystem NVMe Qualified Name */
 	uint8_t			subnqn[256];
@@ -992,8 +1179,38 @@ struct nvme_namespace_data {
 	/** NVM Capacity */
 	uint8_t			nvmcap[16];
 
-	/* bytes 64-103: Reserved */
-	uint8_t			reserved5[40];
+	/** Namespace Preferred Write Granularity  */
+	uint16_t		npwg;
+
+	/** Namespace Preferred Write Alignment */
+	uint16_t		npwa;
+
+	/** Namespace Preferred Deallocate Granularity */
+	uint16_t		npdg;
+
+	/** Namespace Preferred Deallocate Alignment */
+	uint16_t		npda;
+
+	/** Namespace Optimal Write Size */
+	uint16_t		nows;
+
+	/* bytes 74-91: Reserved */
+	uint8_t			reserved5[18];
+
+	/** ANA Group Identifier */
+	uint32_t		anagrpid;
+
+	/* bytes 96-98: Reserved */
+	uint8_t			reserved6[3];
+
+	/** Namespace Attributes */
+	uint8_t			nsattr;
+
+	/** NVM Set Identifier */
+	uint16_t		nvmsetid;
+
+	/** Endurance Group Identifier */
+	uint16_t		endgid;
 
 	/** Namespace Globally Unique Identifier */
 	uint8_t			nguid[16];
@@ -1004,7 +1221,7 @@ struct nvme_namespace_data {
 	/** lba format support */
 	uint32_t		lbaf[16];
 
-	uint8_t			reserved6[192];
+	uint8_t			reserved7[192];
 
 	uint8_t			vendor_specific[3712];
 } __packed __aligned(4);
@@ -1019,9 +1236,21 @@ enum nvme_log_page {
 	NVME_LOG_FIRMWARE_SLOT		= 0x03,
 	NVME_LOG_CHANGED_NAMESPACE	= 0x04,
 	NVME_LOG_COMMAND_EFFECT		= 0x05,
+	NVME_LOG_DEVICE_SELF_TEST	= 0x06,
+	NVME_LOG_TELEMETRY_HOST_INITIATED = 0x07,
+	NVME_LOG_TELEMETRY_CONTROLLER_INITIATED = 0x08,
+	NVME_LOG_ENDURANCE_GROUP_INFORMATION = 0x09,
+	NVME_LOG_PREDICTABLE_LATENCY_PER_NVM_SET = 0x0a,
+	NVME_LOG_PREDICTABLE_LATENCY_EVENT_AGGREGATE = 0x0b,
+	NVME_LOG_ASYMMETRIC_NAMESPAVE_ACCESS = 0x0c,
+	NVME_LOG_PERSISTENT_EVENT_LOG	= 0x0d,
+	NVME_LOG_LBA_STATUS_INFORMATION	= 0x0e,
+	NVME_LOG_ENDURANCE_GROUP_EVENT_AGGREGATE = 0x0f,
 	/* 0x06-0x7F - reserved */
 	/* 0x80-0xBF - I/O command set specific */
 	NVME_LOG_RES_NOTIFICATION	= 0x80,
+	NVME_LOG_SANITIZE_STATUS	= 0x81,
+	/* 0x82-0xBF - reserved */
 	/* 0xC0-0xFF - vendor specific */
 
 	/*
@@ -1050,7 +1279,11 @@ struct nvme_error_information_entry {
 	uint64_t		lba;
 	uint32_t		nsid;
 	uint8_t			vendor_specific;
-	uint8_t			reserved[35];
+	uint8_t			trtype;
+	uint16_t		reserved30;
+	uint64_t		csi;
+	uint16_t		ttsi;
+	uint8_t			reserved[22];
 } __packed __aligned(4);
 
 _Static_assert(sizeof(struct nvme_error_information_entry) == 64, "bad size for nvme_error_information_entry");
@@ -1086,8 +1319,16 @@ struct nvme_health_information_page {
 	uint32_t		warning_temp_time;
 	uint32_t		error_temp_time;
 	uint16_t		temp_sensor[8];
-
-	uint8_t			reserved2[296];
+	/* Thermal Management Temperature 1 Transition Count */
+	uint32_t		tmt1tc;
+	/* Thermal Management Temperature 2 Transition Count */
+	uint32_t		tmt2tc;
+	/* Total Time For Thermal Management Temperature 1 */
+	uint32_t		ttftmt1;
+	/* Total Time For Thermal Management Temperature 2 */
+	uint32_t		ttftmt2;
+
+	uint8_t			reserved2[280];
 } __packed __aligned(4);
 
 _Static_assert(sizeof(struct nvme_health_information_page) == 512, "bad size for nvme_health_information_page");
@@ -1108,6 +1349,43 @@ struct nvme_ns_list {
 
 _Static_assert(sizeof(struct nvme_ns_list) == 4096, "bad size for nvme_ns_list");
 
+struct nvme_command_effects_page {
+	uint32_t		acs[256];
+	uint32_t		iocs[256];
+	uint8_t			reserved[2048];
+} __packed __aligned(4);
+
+_Static_assert(sizeof(struct nvme_command_effects_page) == 4096,
+    "bad size for nvme_command_effects_page");
+
+struct nvme_res_notification_page {
+	uint64_t		log_page_count;
+	uint8_t			log_page_type;
+	uint8_t			available_log_pages;
+	uint8_t			reserved2;
+	uint32_t		nsid;
+	uint8_t			reserved[48];
+} __packed __aligned(4);
+
+_Static_assert(sizeof(struct nvme_res_notification_page) == 64,
+    "bad size for nvme_res_notification_page");
+
+struct nvme_sanitize_status_page {
+	uint16_t		sprog;
+	uint16_t		sstat;
+	uint32_t		scdw10;
+	uint32_t		etfo;
+	uint32_t		etfbe;
+	uint32_t		etfce;
+	uint32_t		etfownd;
+	uint32_t		etfbewnd;
+	uint32_t		etfcewnd;
+	uint8_t			reserved[480];
+} __packed __aligned(4);
+
+_Static_assert(sizeof(struct nvme_sanitize_status_page) == 512,
+    "bad size for nvme_sanitize_status_page");
+
 struct intel_log_temp_stats
 {
 	uint64_t	current;
@@ -1123,6 +1401,56 @@ struct intel_log_temp_stats
 
 _Static_assert(sizeof(struct intel_log_temp_stats) == 13 * 8, "bad size for intel_log_temp_stats");
 
+struct nvme_resv_reg_ctrlr
+{
+	uint16_t		ctrlr_id;	/* Controller ID */
+	uint8_t			rcsts;		/* Reservation Status */
+	uint8_t			reserved3[5];
+	uint64_t		hostid;		/* Host Identifier */
+	uint64_t		rkey;		/* Reservation Key */
+} __packed __aligned(4);
+
+_Static_assert(sizeof(struct nvme_resv_reg_ctrlr) == 24, "bad size for nvme_resv_reg_ctrlr");
+
+struct nvme_resv_reg_ctrlr_ext
+{
+	uint16_t		ctrlr_id;	/* Controller ID */
+	uint8_t			rcsts;		/* Reservation Status */
+	uint8_t			reserved3[5];
+	uint64_t		rkey;		/* Reservation Key */
+	uint64_t		hostid[2];	/* Host Identifier */
+	uint8_t			reserved32[32];
+} __packed __aligned(4);
+
+_Static_assert(sizeof(struct nvme_resv_reg_ctrlr_ext) == 64, "bad size for nvme_resv_reg_ctrlr_ext");
+
+struct nvme_resv_status
+{
+	uint32_t		gen;		/* Generation */
+	uint8_t			rtype;		/* Reservation Type */
+	uint8_t			regctl[2];	/* Number of Registered Controllers */
+	uint8_t			reserved7[2];
+	uint8_t			ptpls;		/* Persist Through Power Loss State */
+	uint8_t			reserved10[14];
+	struct nvme_resv_reg_ctrlr	ctrlr[0];
+} __packed __aligned(4);
+
+_Static_assert(sizeof(struct nvme_resv_status) == 24, "bad size for nvme_resv_status");
+
+struct nvme_resv_status_ext
+{
+	uint32_t		gen;		/* Generation */
+	uint8_t			rtype;		/* Reservation Type */
+	uint8_t			regctl[2];	/* Number of Registered Controllers */
+	uint8_t			reserved7[2];
+	uint8_t			ptpls;		/* Persist Through Power Loss State */
+	uint8_t			reserved10[14];
+	uint8_t			reserved24[40];
+	struct nvme_resv_reg_ctrlr_ext	ctrlr[0];
+} __packed __aligned(4);
+
+_Static_assert(sizeof(struct nvme_resv_status_ext) == 64, "bad size for nvme_resv_status_ext");
+
 #define NVME_TEST_MAX_THREADS	128
 
 struct nvme_io_test {
@@ -1198,6 +1526,11 @@ struct nvme_pt_command {
 	struct mtx *		driver_lock;
 };
 
+struct nvme_get_nsid {
+	char		cdev[SPECNAMELEN + 1];
+	uint32_t	nsid;
+};
+
 #define nvme_completion_is_error(cpl)					\
 	(NVME_STATUS_GET_SC((cpl)->status) != 0 || NVME_STATUS_GET_SCT((cpl)->status) != 0)
 
@@ -1206,6 +1539,7 @@ void	nvme_strvis(uint8_t *dst, const uint8_t *src, int dstlen, int srclen);
 #ifdef _KERNEL
 
 struct bio;
+struct thread;
 
 struct nvme_namespace;
 struct nvme_controller;
@@ -1295,6 +1629,8 @@ uint32_t	nvme_ns_get_stripesize(struct nvme_namespace *ns);
 
 int	nvme_ns_bio_process(struct nvme_namespace *ns, struct bio *bp,
 			    nvme_cb_fn_t cb_fn);
+int	nvme_ns_ioctl_process(struct nvme_namespace *ns, u_long cmd,
+    caddr_t arg, int flag, struct thread *td);
 
 /*
  * Command building helper functions -- shared with CAM
@@ -1386,6 +1722,10 @@ void	nvme_controller_data_swapbytes(struct nvme_controller_data *s)
 	s->rtd3e = le32toh(s->rtd3e);
 	s->oaes = le32toh(s->oaes);
 	s->ctratt = le32toh(s->ctratt);
+	s->rrls = le16toh(s->rrls);
+	s->crdt1 = le16toh(s->crdt1);
+	s->crdt2 = le16toh(s->crdt2);
+	s->crdt3 = le16toh(s->crdt3);
 	s->oacs = le16toh(s->oacs);
 	s->wctemp = le16toh(s->wctemp);
 	s->cctemp = le16toh(s->cctemp);
@@ -1399,6 +1739,13 @@ void	nvme_controller_data_swapbytes(struct nvme_controller_data *s)
 	s->mntmt = le16toh(s->mntmt);
 	s->mxtmt = le16toh(s->mxtmt);
 	s->sanicap = le32toh(s->sanicap);
+	s->hmminds = le32toh(s->hmminds);
+	s->hmmaxd = le16toh(s->hmmaxd);
+	s->nsetidmax = le16toh(s->nsetidmax);
+	s->endgidmax = le16toh(s->endgidmax);
+	s->anagrpmax = le32toh(s->anagrpmax);
+	s->nanagrpid = le32toh(s->nanagrpid);
+	s->pels = le32toh(s->pels);
 	s->maxcmd = le16toh(s->maxcmd);
 	s->nn = le32toh(s->nn);
 	s->oncs = le16toh(s->oncs);
@@ -1407,6 +1754,7 @@ void	nvme_controller_data_swapbytes(struct nvme_controller_data *s)
 	s->awupf = le16toh(s->awupf);
 	s->acwu = le16toh(s->acwu);
 	s->sgls = le32toh(s->sgls);
+	s->mnan = le32toh(s->mnan);
 	for (i = 0; i < 32; i++)
 		nvme_power_state_swapbytes(&s->power_state[i]);
 }
@@ -1426,6 +1774,14 @@ void	nvme_namespace_data_swapbytes(struct nvme_namespace_data *s)
 	s->nabo = le16toh(s->nabo);
 	s->nabspf = le16toh(s->nabspf);
 	s->noiob = le16toh(s->noiob);
+	s->npwg = le16toh(s->npwg);
+	s->npwa = le16toh(s->npwa);
+	s->npdg = le16toh(s->npdg);
+	s->npda = le16toh(s->npda);
+	s->nows = le16toh(s->nows);
+	s->anagrpid = le32toh(s->anagrpid);
+	s->nvmsetid = le16toh(s->nvmsetid);
+	s->endgid = le16toh(s->endgid);
 	for (i = 0; i < 16; i++)
 		s->lbaf[i] = le32toh(s->lbaf[i]);
 }
@@ -1441,6 +1797,8 @@ void	nvme_error_information_entry_swapbytes(struct nvme_error_information_entry
 	s->error_location = le16toh(s->error_location);
 	s->lba = le64toh(s->lba);
 	s->nsid = le32toh(s->nsid);
+	s->csi = le64toh(s->csi);
+	s->ttsi = le16toh(s->ttsi);
 }
 
 static inline
@@ -1481,6 +1839,10 @@ void	nvme_health_information_page_swapbytes(struct nvme_health_information_page
 	s->error_temp_time = le32toh(s->error_temp_time);
 	for (i = 0; i < 8; i++)
 		s->temp_sensor[i] = le16toh(s->temp_sensor[i]);
+	s->tmt1tc = le32toh(s->tmt1tc);
+	s->tmt2tc = le32toh(s->tmt2tc);
+	s->ttftmt1 = le32toh(s->ttftmt1);
+	s->ttftmt2 = le32toh(s->ttftmt2);
 }
 
 
@@ -1503,6 +1865,38 @@ void	nvme_ns_list_swapbytes(struct nvme_ns_list *s)
 }
 
 static inline
+void	nvme_command_effects_page_swapbytes(struct nvme_command_effects_page *s)
+{
+	int i;
+
+	for (i = 0; i < 256; i++)
+		s->acs[i] = le32toh(s->acs[i]);
+	for (i = 0; i < 256; i++)
+		s->iocs[i] = le32toh(s->iocs[i]);
+}
+
+static inline
+void	nvme_res_notification_page_swapbytes(struct nvme_res_notification_page *s)
+{
+	s->log_page_count = le64toh(s->log_page_count);
+	s->nsid = le32toh(s->nsid);
+}
+
+static inline
+void	nvme_sanitize_status_page_swapbytes(struct nvme_sanitize_status_page *s)
+{
+	s->sprog = le16toh(s->sprog);
+	s->sstat = le16toh(s->sstat);
+	s->scdw10 = le32toh(s->scdw10);
+	s->etfo = le32toh(s->etfo);
+	s->etfbe = le32toh(s->etfbe);
+	s->etfce = le32toh(s->etfce);
+	s->etfownd = le32toh(s->etfownd);
+	s->etfbewnd = le32toh(s->etfbewnd);
+	s->etfcewnd = le32toh(s->etfcewnd);
+}
+
+static inline
 void	intel_log_temp_stats_swapbytes(struct intel_log_temp_stats *s)
 {
 
@@ -1517,4 +1911,34 @@ void	intel_log_temp_stats_swapbytes(struct intel_log_temp_stats *s)
 	s->est_offset = le64toh(s->est_offset);
 }
 
+static inline
+void	nvme_resv_status_swapbytes(struct nvme_resv_status *s, size_t size)
+{
+	u_int i, n;
+
+	s->gen = le32toh(s->gen);
+	n = (s->regctl[1] << 8) | s->regctl[0];
+	n = MIN(n, (size - sizeof(s)) / sizeof(s->ctrlr[0]));
+	for (i = 0; i < n; i++) {
+		s->ctrlr[i].ctrlr_id = le16toh(s->ctrlr[i].ctrlr_id);
+		s->ctrlr[i].hostid = le64toh(s->ctrlr[i].hostid);
+		s->ctrlr[i].rkey = le64toh(s->ctrlr[i].rkey);
+	}
+}
+
+static inline
+void	nvme_resv_status_ext_swapbytes(struct nvme_resv_status_ext *s, size_t size)
+{
+	u_int i, n;
+
+	s->gen = le32toh(s->gen);
+	n = (s->regctl[1] << 8) | s->regctl[0];
+	n = MIN(n, (size - sizeof(s)) / sizeof(s->ctrlr[0]));
+	for (i = 0; i < n; i++) {
+		s->ctrlr[i].ctrlr_id = le16toh(s->ctrlr[i].ctrlr_id);
+		s->ctrlr[i].rkey = le64toh(s->ctrlr[i].rkey);
+		nvme_le128toh((void *)s->ctrlr[i].hostid);
+	}
+}
+
 #endif /* __NVME_H__ */
diff --git a/freebsd/sys/dev/ofw/ofw_subr.c b/freebsd/sys/dev/ofw/ofw_subr.c
index 4a20727..7483a2d 100644
--- a/freebsd/sys/dev/ofw/ofw_subr.c
+++ b/freebsd/sys/dev/ofw/ofw_subr.c
@@ -81,7 +81,8 @@ int
 ofw_reg_to_paddr(phandle_t dev, int regno, bus_addr_t *paddr,
     bus_size_t *psize, pcell_t *ppci_hi)
 {
-	pcell_t cell[32], pci_hi;
+	static pcell_t cell[256];
+	pcell_t pci_hi;
 	uint64_t addr, raddr, baddr;
 	uint64_t size, rsize;
 	uint32_t c, nbridge, naddr, nsize;
diff --git a/freebsd/sys/fs/devfs/devfs_vnops.c b/freebsd/sys/fs/devfs/devfs_vnops.c
index 2e16ddf..86808e2 100644
--- a/freebsd/sys/fs/devfs/devfs_vnops.c
+++ b/freebsd/sys/fs/devfs/devfs_vnops.c
@@ -53,6 +53,7 @@
 #include <sys/filio.h>
 #include <sys/jail.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mman.h>
diff --git a/freebsd/sys/kern/init_main.c b/freebsd/sys/kern/init_main.c
index 224c9f6..258fa8c 100644
--- a/freebsd/sys/kern/init_main.c
+++ b/freebsd/sys/kern/init_main.c
@@ -852,11 +852,9 @@ start_init(void *dummy)
 }
 
 /*
- * Like kproc_create(), but runs in its own address space.
- * We do this early to reserve pid 1.
- *
- * Note special case - do not make it runnable yet.  Other work
- * in progress will change this more.
+ * Like kproc_create(), but runs in its own address space.  We do this
+ * early to reserve pid 1.  Note special case - do not make it
+ * runnable yet, init execution is started when userspace can be served.
  */
 static void
 create_init(const void *udata __unused)
diff --git a/freebsd/sys/kern/kern_event.c b/freebsd/sys/kern/kern_event.c
index f1d6ef8..d9ec03c 100644
--- a/freebsd/sys/kern/kern_event.c
+++ b/freebsd/sys/kern/kern_event.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/capsicum.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/rwlock.h>
diff --git a/freebsd/sys/kern/kern_sysctl.c b/freebsd/sys/kern/kern_sysctl.c
index 08e9552..b7ba41e 100644
--- a/freebsd/sys/kern/kern_sysctl.c
+++ b/freebsd/sys/kern/kern_sysctl.c
@@ -1706,6 +1706,30 @@ retry:
 }
 
 /*
+ * Convert seconds to a struct timeval.  Intended for use with
+ * intervals and thus does not permit negative seconds.
+ */
+int
+sysctl_sec_to_timeval(SYSCTL_HANDLER_ARGS)
+{
+	struct timeval *tv;
+	int error, secs;
+
+	tv = arg1;
+	secs = tv->tv_sec;
+
+	error = sysctl_handle_int(oidp, &secs, 0, req);
+	if (error || req->newptr == NULL)
+		return (error);
+
+	if (secs < 0)
+		return (EINVAL);
+	tv->tv_sec = secs;
+
+	return (0);
+}
+
+/*
  * Transfer functions to/from kernel space.
  * XXX: rather untested at this point
  */
diff --git a/freebsd/sys/kern/subr_bus.c b/freebsd/sys/kern/subr_bus.c
index 362e891..bfeb1c3 100644
--- a/freebsd/sys/kern/subr_bus.c
+++ b/freebsd/sys/kern/subr_bus.c
@@ -5957,8 +5957,9 @@ devctl2_init(void)
  */
 static int obsolete_panic = 0;
 SYSCTL_INT(_debug, OID_AUTO, obsolete_panic, CTLFLAG_RWTUN, &obsolete_panic, 0,
-    "Bus debug level");
-/* 0 - don't panic, 1 - panic if already obsolete, 2 - panic if deprecated */
+    "Panic when obsolete features are used (0 = never, 1 = if osbolete, "
+    "2 = if deprecated)");
+
 static void
 gone_panic(int major, int running, const char *msg)
 {
diff --git a/freebsd/sys/kern/sys_pipe.c b/freebsd/sys/kern/sys_pipe.c
index d714af8..cdfff76 100755
--- a/freebsd/sys/kern/sys_pipe.c
+++ b/freebsd/sys/kern/sys_pipe.c
@@ -1687,7 +1687,7 @@ pipe_poll(struct file *fp, int events, struct ucred *active_cred,
 	    (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND);
 #ifndef __rtems__
 	if (rpipe->pipe_state & PIPE_NAMED && fp->f_flag & FREAD && levents &&
-	    fp->f_seqcount == rpipe->pipe_wgen)
+	    fp->f_pipegen == rpipe->pipe_wgen)
 #else /* __rtems__ */
 	if (rpipe->pipe_state & PIPE_NAMED && rtems_bsd_libio_flags_to_fflag(fp->f_io.flags) & FREAD && levents)
 #endif /* __rtems__ */
diff --git a/freebsd/sys/kern/uipc_mbuf2.c b/freebsd/sys/kern/uipc_mbuf2.c
index 7dd2840..6f98b0a 100644
--- a/freebsd/sys/kern/uipc_mbuf2.c
+++ b/freebsd/sys/kern/uipc_mbuf2.c
@@ -218,7 +218,7 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
 		goto ok;
 	}
 	if ((off == 0 || offp) && M_LEADINGSPACE(n->m_next) >= hlen
-	 && writable) {
+	 && writable && n->m_next->m_len >= tlen) {
 		n->m_next->m_data -= hlen;
 		n->m_next->m_len += hlen;
 		bcopy(mtod(n, caddr_t) + off, mtod(n->m_next, caddr_t), hlen);
diff --git a/freebsd/sys/kern/uipc_usrreq.c b/freebsd/sys/kern/uipc_usrreq.c
index 6b34dcb..c4df64a 100644
--- a/freebsd/sys/kern/uipc_usrreq.c
+++ b/freebsd/sys/kern/uipc_usrreq.c
@@ -2306,30 +2306,53 @@ unp_init(void)
 }
 
 #ifndef __rtems__
+static void
+unp_internalize_cleanup_rights(struct mbuf *control)
+{
+	struct cmsghdr *cp;
+	struct mbuf *m;
+	void *data;
+	socklen_t datalen;
+
+	for (m = control; m != NULL; m = m->m_next) {
+		cp = mtod(m, struct cmsghdr *);
+		if (cp->cmsg_level != SOL_SOCKET ||
+		    cp->cmsg_type != SCM_RIGHTS)
+			continue;
+		data = CMSG_DATA(cp);
+		datalen = (caddr_t)cp + cp->cmsg_len - (caddr_t)data;
+		unp_freerights(data, datalen / sizeof(struct filedesc *));
+	}
+}
+
 static int
 unp_internalize(struct mbuf **controlp, struct thread *td)
 {
-	struct mbuf *control = *controlp;
-	struct proc *p = td->td_proc;
-	struct filedesc *fdesc = p->p_fd;
+	struct mbuf *control, **initial_controlp;
+	struct proc *p;
+	struct filedesc *fdesc;
 	struct bintime *bt;
-	struct cmsghdr *cm = mtod(control, struct cmsghdr *);
+	struct cmsghdr *cm;
 	struct cmsgcred *cmcred;
 	struct filedescent *fde, **fdep, *fdev;
 	struct file *fp;
 	struct timeval *tv;
 	struct timespec *ts;
-	int i, *fdp;
 	void *data;
-	socklen_t clen = control->m_len, datalen;
-	int error, oldfds;
+	socklen_t clen, datalen;
+	int i, error, *fdp, oldfds;
 	u_int newlen;
 
 	UNP_LINK_UNLOCK_ASSERT();
 
+	p = td->td_proc;
+	fdesc = p->p_fd;
 	error = 0;
+	control = *controlp;
+	clen = control->m_len;
 	*controlp = NULL;
-	while (cm != NULL) {
+	initial_controlp = controlp;
+	for (cm = mtod(control, struct cmsghdr *); cm != NULL;) {
 		if (sizeof(*cm) > clen || cm->cmsg_level != SOL_SOCKET
 		    || cm->cmsg_len > clen || cm->cmsg_len < sizeof(*cm)) {
 			error = EINVAL;
@@ -2480,6 +2503,8 @@ unp_internalize(struct mbuf **controlp, struct thread *td)
 	}
 
 out:
+	if (error != 0 && initial_controlp != NULL)
+		unp_internalize_cleanup_rights(*initial_controlp);
 	m_freem(control);
 	return (error);
 }
diff --git a/freebsd/sys/net/ieee_oui.h b/freebsd/sys/net/ieee_oui.h
index f543f56..e582ee6 100644
--- a/freebsd/sys/net/ieee_oui.h
+++ b/freebsd/sys/net/ieee_oui.h
@@ -77,4 +77,9 @@
  */
 #define	OUI_FREEBSD_GENERATED_MASK	0x10ffff
 #define	OUI_FREEBSD_GENERATED_LOW	OUI_FREEBSD(0x100000)
-#define	OUI_FREEBSD_GENERATED_HIGH	OUI_FREEBSD(OU_FREEBSD_GENERATED_MASK)
+#define	OUI_FREEBSD_GENERATED_HIGH	OUI_FREEBSD(OUI_FREEBSD_GENERATED_MASK)
+
+/* Allocate 16 bits for emulated NVMe devices */
+#define OUI_FREEBSD_NVME_MASK		0x20ffff
+#define OUI_FREEBSD_NVME_LOW		OUI_FREEBSD(0x200000)
+#define OUI_FRREBSD_NVME_HIGH		OUI_FREEBSD(OUI_FREEBSD_NVME_MASK)
diff --git a/freebsd/sys/net/if_spppsubr.c b/freebsd/sys/net/if_spppsubr.c
index f5b78de..d73befe 100644
--- a/freebsd/sys/net/if_spppsubr.c
+++ b/freebsd/sys/net/if_spppsubr.c
@@ -4809,7 +4809,7 @@ sppp_keepalive(void *dummy)
 		sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ,
 			 ++sp->pp_seq[IDX_LCP],	sp->pp_rseq[IDX_LCP]);
 	else if (sp->pp_phase >= PHASE_AUTHENTICATE) {
-		long nmagic = htonl (sp->lcp.magic);
+		uint32_t nmagic = htonl(sp->lcp.magic);
 		sp->lcp.echoid = ++sp->pp_seq[IDX_LCP];
 		sppp_cp_send (sp, PPP_LCP, ECHO_REQ,
 			sp->lcp.echoid, 4, &nmagic);
diff --git a/freebsd/sys/net/if_tun.c b/freebsd/sys/net/if_tun.c
index 9c11cbc..c96b216 100644
--- a/freebsd/sys/net/if_tun.c
+++ b/freebsd/sys/net/if_tun.c
@@ -747,12 +747,16 @@ static	int
 tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
     struct thread *td)
 {
-	struct ifreq ifr;
+	struct ifreq ifr, *ifrp;
 	struct tun_softc *tp = dev->si_drv1;
 	struct tuninfo *tunp;
 	int error;
 
 	switch (cmd) {
+	case TUNGIFNAME:
+		ifrp = (struct ifreq *)data;
+		strlcpy(ifrp->ifr_name, TUN2IFP(tp)->if_xname, IFNAMSIZ);
+		break;
 	case TUNSIFINFO:
 		tunp = (struct tuninfo *)data;
 		if (TUN2IFP(tp)->if_type != tunp->type)
diff --git a/freebsd/sys/net/if_tun.h b/freebsd/sys/net/if_tun.h
index 1ea375f..a44c87b 100644
--- a/freebsd/sys/net/if_tun.h
+++ b/freebsd/sys/net/if_tun.h
@@ -40,6 +40,7 @@ struct tuninfo {
 #define	TUNSIFINFO	_IOW('t', 91, struct tuninfo)
 #define	TUNGIFINFO	_IOR('t', 92, struct tuninfo)
 #define	TUNSLMODE	_IOW('t', 93, int)
+#define	TUNGIFNAME	_IOR('t', 93, struct ifreq)
 #define	TUNSIFMODE	_IOW('t', 94, int)
 #define	TUNSIFPID	_IO('t', 95)
 #define	TUNSIFHEAD	_IOW('t', 96, int)
diff --git a/freebsd/sys/net/iflib.h b/freebsd/sys/net/iflib.h
index 7ccd503..2395439 100644
--- a/freebsd/sys/net/iflib.h
+++ b/freebsd/sys/net/iflib.h
@@ -393,6 +393,13 @@ int iflib_device_suspend(device_t);
 int iflib_device_resume(device_t);
 int iflib_device_shutdown(device_t);
 
+/*
+ * Use this instead of iflib_device_probe if the driver should report
+ * BUS_PROBE_VENDOR instead of BUS_PROBE_DEFAULT. (For example, an out-of-tree
+ * driver based on iflib).
+ */
+int iflib_device_probe_vendor(device_t);
+
 
 int iflib_device_iov_init(device_t, uint16_t, const nvlist_t *);
 void iflib_device_iov_uninit(device_t);
diff --git a/freebsd/sys/net/route.c b/freebsd/sys/net/route.c
index 3cd909c..0933c3a 100644
--- a/freebsd/sys/net/route.c
+++ b/freebsd/sys/net/route.c
@@ -1585,6 +1585,8 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
 	switch (req) {
 	case RTM_DELETE:
 		if (netmask) {
+			if (dst->sa_len > sizeof(mdst))
+				return (EINVAL);
 			rt_maskedcopy(dst, (struct sockaddr *)&mdst, netmask);
 			dst = (struct sockaddr *)&mdst;
 		}
diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c
index 77d6fc3..e1fa55c 100644
--- a/freebsd/sys/netinet/tcp_input.c
+++ b/freebsd/sys/netinet/tcp_input.c
@@ -578,6 +578,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
 	int optlen = 0;
 #ifdef INET
 	int len;
+	uint8_t ipttl;
 #endif
 	int tlen = 0, off;
 	int drop_hdrlen;
@@ -700,6 +701,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
 			 * Checksum extended TCP header and data.
 			 */
 			len = off0 + tlen;
+			ipttl = ip->ip_ttl;
 			bzero(ipov->ih_x1, sizeof(ipov->ih_x1));
 			ipov->ih_len = htons(tlen);
 			th->th_sum = in_cksum(m, len);
@@ -708,6 +710,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
 			/* Reset TOS bits */
 			ip->ip_tos = iptos;
 			/* Re-initialization for later version check */
+			ip->ip_ttl = ipttl;
 			ip->ip_v = IPVERSION;
 			ip->ip_hl = off0 >> 2;
 		}
diff --git a/freebsd/sys/netinet/tcp_usrreq.c b/freebsd/sys/netinet/tcp_usrreq.c
index 27ab745..809ea35 100644
--- a/freebsd/sys/netinet/tcp_usrreq.c
+++ b/freebsd/sys/netinet/tcp_usrreq.c
@@ -1580,11 +1580,9 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt)
 	error = 0;
 	inp = sotoinpcb(so);
 	KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL"));
-	INP_WLOCK(inp);
 	if (sopt->sopt_level != IPPROTO_TCP) {
 #ifdef INET6
 		if (inp->inp_vflag & INP_IPV6PROTO) {
-			INP_WUNLOCK(inp);
 			error = ip6_ctloutput(so, sopt);
 			/*
 			 * In case of the IPV6_USE_MIN_MTU socket option,
@@ -1629,12 +1627,12 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt)
 #endif
 #ifdef INET
 		{
-			INP_WUNLOCK(inp);
 			error = ip_ctloutput(so, sopt);
 		}
 #endif
 		return (error);
 	}
+	INP_WLOCK(inp);
 	if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
 		INP_WUNLOCK(inp);
 		return (ECONNRESET);
diff --git a/freebsd/sys/netinet6/ip6_output.c b/freebsd/sys/netinet6/ip6_output.c
index eaae72a..e941ac4 100644
--- a/freebsd/sys/netinet6/ip6_output.c
+++ b/freebsd/sys/netinet6/ip6_output.c
@@ -230,7 +230,20 @@ ip6_fragment(struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto,
 			IP6STAT_INC(ip6s_odropped);
 			return (ENOBUFS);
 		}
-		m->m_flags = m0->m_flags & M_COPYFLAGS;
+
+		/*
+		 * Make sure the complete packet header gets copied
+		 * from the originating mbuf to the newly created
+		 * mbuf. This also ensures that existing firewall
+		 * classification(s), VLAN tags and so on get copied
+		 * to the resulting fragmented packet(s):
+		 */
+		if (m_dup_pkthdr(m, m0, M_NOWAIT) == 0) {
+			m_free(m);
+			IP6STAT_INC(ip6s_odropped);
+			return (ENOBUFS);
+		}
+
 		*mnext = m;
 		mnext = &m->m_nextpkt;
 		m->m_data += max_linkhdr;
@@ -255,8 +268,6 @@ ip6_fragment(struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto,
 		}
 		m_cat(m, m_frgpart);
 		m->m_pkthdr.len = fraglen + hlen + sizeof(*ip6f);
-		m->m_pkthdr.fibnum = m0->m_pkthdr.fibnum;
-		m->m_pkthdr.rcvif = NULL;
 		ip6f->ip6f_reserved = 0;
 		ip6f->ip6f_ident = id;
 		ip6f->ip6f_nxt = nextproto;
diff --git a/freebsd/sys/netinet6/mld6.c b/freebsd/sys/netinet6/mld6.c
index 5b90f0a..a0d045d 100644
--- a/freebsd/sys/netinet6/mld6.c
+++ b/freebsd/sys/netinet6/mld6.c
@@ -141,14 +141,15 @@ static int	mld_v2_enqueue_group_record(struct mbufq *,
 		    struct in6_multi *, const int, const int, const int,
 		    const int);
 static int	mld_v2_input_query(struct ifnet *, const struct ip6_hdr *,
-		    struct mbuf *, const int, const int);
+		    struct mbuf *, struct mldv2_query *, const int, const int);
 static int	mld_v2_merge_state_changes(struct in6_multi *,
 		    struct mbufq *);
 static void	mld_v2_process_group_timers(struct in6_multi_head *,
 		    struct mbufq *, struct mbufq *,
 		    struct in6_multi *, const int);
 static int	mld_v2_process_group_query(struct in6_multi *,
-		    struct mld_ifsoftc *mli, int, struct mbuf *, const int);
+		    struct mld_ifsoftc *mli, int, struct mbuf *,
+		    struct mldv2_query *, const int);
 static int	sysctl_mld_gsr(SYSCTL_HANDLER_ARGS);
 static int	sysctl_mld_ifinfo(SYSCTL_HANDLER_ARGS);
 
@@ -805,16 +806,16 @@ mld_v1_update_group(struct in6_multi *inm, const int timer)
  * Process a received MLDv2 general, group-specific or
  * group-and-source-specific query.
  *
- * Assumes that the query header has been pulled up to sizeof(mldv2_query).
+ * Assumes that mld points to a struct mldv2_query which is stored in
+ * contiguous memory.
  *
  * Return 0 if successful, otherwise an appropriate error code is returned.
  */
 static int
 mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
-    struct mbuf *m, const int off, const int icmp6len)
+    struct mbuf *m, struct mldv2_query *mld, const int off, const int icmp6len)
 {
 	struct mld_ifsoftc	*mli;
-	struct mldv2_query	*mld;
 	struct in6_multi	*inm;
 	uint32_t		 maxdelay, nsrc, qqi;
 	int			 is_general_query;
@@ -846,8 +847,6 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
 
 	CTR2(KTR_MLD, "input v2 query on ifp %p(%s)", ifp, if_name(ifp));
 
-	mld = (struct mldv2_query *)(mtod(m, uint8_t *) + off);
-
 	maxdelay = ntohs(mld->mld_maxdelay);	/* in 1/10ths of a second */
 	if (maxdelay >= 32768) {
 		maxdelay = (MLD_MRC_MANT(maxdelay) | 0x1000) <<
@@ -972,7 +971,7 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
 		 * group-specific or group-and-source query.
 		 */
 		if (mli->mli_v2_timer == 0 || mli->mli_v2_timer >= timer)
-			mld_v2_process_group_query(inm, mli, timer, m, off);
+			mld_v2_process_group_query(inm, mli, timer, m, mld, off);
 
 		/* XXX Clear embedded scope ID as userland won't expect it. */
 		in6_clearscope(&mld->mld_addr);
@@ -993,9 +992,8 @@ out_locked:
  */
 static int
 mld_v2_process_group_query(struct in6_multi *inm, struct mld_ifsoftc *mli,
-    int timer, struct mbuf *m0, const int off)
+    int timer, struct mbuf *m0, struct mldv2_query *mld, const int off)
 {
-	struct mldv2_query	*mld;
 	int			 retval;
 	uint16_t		 nsrc;
 
@@ -1003,7 +1001,6 @@ mld_v2_process_group_query(struct in6_multi *inm, struct mld_ifsoftc *mli,
 	MLD_LOCK_ASSERT();
 
 	retval = 0;
-	mld = (struct mldv2_query *)(mtod(m0, uint8_t *) + off);
 
 	switch (inm->in6m_state) {
 	case MLD_NOT_MEMBER:
@@ -1023,6 +1020,15 @@ mld_v2_process_group_query(struct in6_multi *inm, struct mld_ifsoftc *mli,
 
 	nsrc = ntohs(mld->mld_numsrc);
 
+	/* Length should be checked by calling function. */
+	KASSERT((m0->m_flags & M_PKTHDR) == 0 ||
+	    m0->m_pkthdr.len >= off + sizeof(struct mldv2_query) +
+	    nsrc * sizeof(struct in6_addr),
+	    ("mldv2 packet is too short: (%d bytes < %zd bytes, m=%p)",
+	    m0->m_pkthdr.len, off + sizeof(struct mldv2_query) +
+	    nsrc * sizeof(struct in6_addr), m0));
+
+
 	/*
 	 * Deal with group-specific queries upfront.
 	 * If any group query is already pending, purge any recorded
@@ -1064,28 +1070,20 @@ mld_v2_process_group_query(struct in6_multi *inm, struct mld_ifsoftc *mli,
 	 * report for those sources.
 	 */
 	if (inm->in6m_nsrc > 0) {
-		struct mbuf		*m;
-		uint8_t			*sp;
+		struct in6_addr		 srcaddr;
 		int			 i, nrecorded;
 		int			 soff;
 
-		m = m0;
 		soff = off + sizeof(struct mldv2_query);
 		nrecorded = 0;
 		for (i = 0; i < nsrc; i++) {
-			sp = mtod(m, uint8_t *) + soff;
-			retval = in6m_record_source(inm,
-			    (const struct in6_addr *)sp);
+			m_copydata(m0, soff, sizeof(struct in6_addr),
+			    (caddr_t)&srcaddr);
+			retval = in6m_record_source(inm, &srcaddr);
 			if (retval < 0)
 				break;
 			nrecorded += retval;
 			soff += sizeof(struct in6_addr);
-			if (soff >= m->m_len) {
-				soff = soff - m->m_len;
-				m = m->m_next;
-				if (m == NULL)
-					break;
-			}
 		}
 		if (nrecorded > 0) {
 			CTR1(KTR_MLD,
@@ -1294,8 +1292,8 @@ mld_input(struct mbuf *m, int off, int icmp6len)
 			if (mld_v1_input_query(ifp, ip6, mld) != 0)
 				return (0);
 		} else if (icmp6len >= sizeof(struct mldv2_query)) {
-			if (mld_v2_input_query(ifp, ip6, m, off,
-			    icmp6len) != 0)
+			if (mld_v2_input_query(ifp, ip6, m,
+			    (struct mldv2_query *)mld, off, icmp6len) != 0)
 				return (0);
 		}
 		break;
diff --git a/freebsd/sys/netipsec/ipsec.c b/freebsd/sys/netipsec/ipsec.c
index 116557e..9f30cf3 100644
--- a/freebsd/sys/netipsec/ipsec.c
+++ b/freebsd/sys/netipsec/ipsec.c
@@ -218,6 +218,11 @@ SYSCTL_INT(_net_inet_ipsec, OID_AUTO, filtertunnel,
 SYSCTL_VNET_PCPUSTAT(_net_inet_ipsec, OID_AUTO, ipsecstats, struct ipsecstat,
     ipsec4stat, "IPsec IPv4 statistics.");
 
+struct timeval ipsec_warn_interval = { .tv_sec = 1, .tv_usec = 0 };
+SYSCTL_TIMEVAL_SEC(_net_inet_ipsec, OID_AUTO, crypto_warn_interval, CTLFLAG_RW,
+    &ipsec_warn_interval,
+    "Delay in seconds between warnings of deprecated IPsec crypto algorithms.");
+
 #ifdef REGRESSION
 /*
  * When set to 1, IPsec will send packets with the same sequence number.
diff --git a/freebsd/sys/netipsec/ipsec.h b/freebsd/sys/netipsec/ipsec.h
index eed2d07..b9b6eca 100644
--- a/freebsd/sys/netipsec/ipsec.h
+++ b/freebsd/sys/netipsec/ipsec.h
@@ -287,6 +287,8 @@ VNET_DECLARE(int, crypto_support);
 VNET_DECLARE(int, async_crypto);
 VNET_DECLARE(int, natt_cksum_policy);
 
+extern struct timeval ipsec_warn_interval;
+
 #define	IPSECSTAT_INC(name)	\
     VNET_PCPUSTAT_ADD(struct ipsecstat, ipsec4stat, name, 1)
 #define	V_ip4_esp_trans_deflev	VNET(ip4_esp_trans_deflev)
diff --git a/freebsd/sys/netipsec/key.c b/freebsd/sys/netipsec/key.c
index 4b79f88..20b87b3 100644
--- a/freebsd/sys/netipsec/key.c
+++ b/freebsd/sys/netipsec/key.c
@@ -286,7 +286,7 @@ key_addrprotohash(const union sockaddr_union *src,
 #endif
 	default:
 		hval = 0;
-		ipseclog((LOG_DEBUG, "%s: unknown address family %d",
+		ipseclog((LOG_DEBUG, "%s: unknown address family %d\n",
 		    __func__, dst->sa.sa_family));
 	}
 	return (hval);
@@ -2041,8 +2041,8 @@ key_spdadd(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
 			key_freesp(&newsp);
 		} else {
 			key_freesp(&newsp);
-			ipseclog((LOG_DEBUG, "%s: a SP entry exists already.",
-			    __func__));
+			ipseclog((LOG_DEBUG,
+			    "%s: a SP entry exists already.\n", __func__));
 			return (key_senderror(so, m, EEXIST));
 		}
 	}
@@ -5435,7 +5435,7 @@ key_update(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
 	}
 	/* saidx should match with SA. */
 	if (key_cmpsaidx(&sav->sah->saidx, &saidx, CMP_MODE_REQID) == 0) {
-		ipseclog((LOG_DEBUG, "%s: saidx mismatched for SPI %u",
+		ipseclog((LOG_DEBUG, "%s: saidx mismatched for SPI %u\n",
 		    __func__, ntohl(sav->spi)));
 		key_freesav(&sav);
 		return key_senderror(so, m, ESRCH);
@@ -6911,14 +6911,14 @@ key_acqdone(const struct secasindex *saidx, uint32_t seq)
 	if (acq != NULL) {
 		if (key_cmpsaidx(&acq->saidx, saidx, CMP_EXACTLY) == 0) {
 			ipseclog((LOG_DEBUG,
-			    "%s: Mismatched saidx for ACQ %u", __func__, seq));
+			    "%s: Mismatched saidx for ACQ %u\n", __func__, seq));
 			acq = NULL;
 		} else {
 			acq->created = 0;
 		}
 	} else {
 		ipseclog((LOG_DEBUG,
-		    "%s: ACQ %u is not found.", __func__, seq));
+		    "%s: ACQ %u is not found.\n", __func__, seq));
 	}
 	ACQ_UNLOCK();
 	if (acq == NULL)
diff --git a/freebsd/sys/netipsec/xform_ah.c b/freebsd/sys/netipsec/xform_ah.c
index 88e5130..618fbd9 100644
--- a/freebsd/sys/netipsec/xform_ah.c
+++ b/freebsd/sys/netipsec/xform_ah.c
@@ -111,7 +111,6 @@ SYSCTL_VNET_PCPUSTAT(_net_inet_ah, IPSECCTL_STATS, stats, struct ahstat,
 
 static unsigned char ipseczeroes[256];	/* larger than an ip6 extension hdr */
 static struct timeval md5warn, ripewarn, kpdkmd5warn, kpdksha1warn;
-static struct timeval warninterval = { .tv_sec = 1, .tv_usec = 0 };
 
 static int ah_input_cb(struct cryptop*);
 static int ah_output_cb(struct cryptop*);
@@ -191,19 +190,19 @@ ah_init0(struct secasvar *sav, struct xformsw *xsp, struct cryptoini *cria)
 
 	switch (sav->alg_auth) {
 	case SADB_AALG_MD5HMAC:
-		if (ratecheck(&md5warn, &warninterval))
+		if (ratecheck(&md5warn, &ipsec_warn_interval))
 			gone_in(13, "MD5-HMAC authenticator for IPsec");
 		break;
 	case SADB_X_AALG_RIPEMD160HMAC:
-		if (ratecheck(&ripewarn, &warninterval))
+		if (ratecheck(&ripewarn, &ipsec_warn_interval))
 			gone_in(13, "RIPEMD160-HMAC authenticator for IPsec");
 		break;
 	case SADB_X_AALG_MD5:
-		if (ratecheck(&kpdkmd5warn, &warninterval))
+		if (ratecheck(&kpdkmd5warn, &ipsec_warn_interval))
 			gone_in(13, "Keyed-MD5 authenticator for IPsec");
 		break;
 	case SADB_X_AALG_SHA:
-		if (ratecheck(&kpdksha1warn, &warninterval))
+		if (ratecheck(&kpdksha1warn, &ipsec_warn_interval))
 			gone_in(13, "Keyed-SHA1 authenticator for IPsec");
 		break;
 	}
diff --git a/freebsd/sys/netipsec/xform_esp.c b/freebsd/sys/netipsec/xform_esp.c
index d1a8a50..f5752a9 100644
--- a/freebsd/sys/netipsec/xform_esp.c
+++ b/freebsd/sys/netipsec/xform_esp.c
@@ -97,7 +97,6 @@ SYSCTL_VNET_PCPUSTAT(_net_inet_esp, IPSECCTL_STATS, stats,
     "ESP statistics (struct espstat, netipsec/esp_var.h");
 
 static struct timeval deswarn, blfwarn, castwarn, camelliawarn;
-static struct timeval warninterval = { .tv_sec = 1, .tv_usec = 0 };
 
 static int esp_input_cb(struct cryptop *op);
 static int esp_output_cb(struct cryptop *crp);
@@ -164,19 +163,19 @@ esp_init(struct secasvar *sav, struct xformsw *xsp)
 
 	switch (sav->alg_enc) {
 	case SADB_EALG_DESCBC:
-		if (ratecheck(&deswarn, &warninterval))
+		if (ratecheck(&deswarn, &ipsec_warn_interval))
 			gone_in(13, "DES cipher for IPsec");
 		break;
 	case SADB_X_EALG_BLOWFISHCBC:
-		if (ratecheck(&blfwarn, &warninterval))
+		if (ratecheck(&blfwarn, &ipsec_warn_interval))
 			gone_in(13, "Blowfish cipher for IPsec");
 		break;
 	case SADB_X_EALG_CAST128CBC:
-		if (ratecheck(&castwarn, &warninterval))
+		if (ratecheck(&castwarn, &ipsec_warn_interval))
 			gone_in(13, "CAST cipher for IPsec");
 		break;
 	case SADB_X_EALG_CAMELLIACBC:
-		if (ratecheck(&camelliawarn, &warninterval))
+		if (ratecheck(&camelliawarn, &ipsec_warn_interval))
 			gone_in(13, "Camellia cipher for IPsec");
 		break;
 	}
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_private.h b/freebsd/sys/netpfil/ipfw/ip_fw_private.h
index 491350d..df0985e 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_private.h
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_private.h
@@ -676,6 +676,7 @@ struct ip_fw *ipfw_alloc_rule(struct ip_fw_chain *chain, size_t rulesize);
 void ipfw_free_rule(struct ip_fw *rule);
 int ipfw_match_range(struct ip_fw *rule, ipfw_range_tlv *rt);
 int ipfw_mark_object_kidx(uint32_t *bmask, uint16_t etlv, uint16_t kidx);
+ipfw_insn *ipfw_get_action(struct ip_fw *);
 
 typedef int (sopt_handler_f)(struct ip_fw_chain *ch,
     ip_fw3_opheader *op3, struct sockopt_data *sd);
diff --git a/freebsd/sys/opencrypto/cryptodev.c b/freebsd/sys/opencrypto/cryptodev.c
index 797616b..02a0303 100644
--- a/freebsd/sys/opencrypto/cryptodev.c
+++ b/freebsd/sys/opencrypto/cryptodev.c
@@ -296,7 +296,13 @@ struct fcrypt {
 	int		sesn;
 };
 
+static struct timeval warninterval = { .tv_sec = 60, .tv_usec = 0 };
+SYSCTL_TIMEVAL_SEC(_kern, OID_AUTO, cryptodev_warn_interval, CTLFLAG_RW,
+    &warninterval,
+    "Delay in seconds between warnings of deprecated /dev/crypto algorithms");
+
 #ifndef __rtems__
+>>>>>>> e79fbf70f7e... RTEMS
 static	int cryptof_ioctl(struct file *, u_long, void *,
 		    struct ucred *, struct thread *);
 static	int cryptof_stat(struct file *, struct stat *,
@@ -392,6 +398,8 @@ cryptof_ioctl(
 	struct crypt_op copc;
 	struct crypt_kop kopc;
 #endif
+	static struct timeval arc4warn, blfwarn, castwarn, deswarn, md5warn;
+	static struct timeval skipwarn, tdeswarn;
 
 	switch (cmd) {
 	case CIOCGSESSION:
@@ -412,18 +420,28 @@ cryptof_ioctl(
 		case 0:
 			break;
 		case CRYPTO_DES_CBC:
+			if (ratecheck(&deswarn, &warninterval))
+				gone_in(13, "DES cipher via /dev/crypto");
 			txform = &enc_xform_des;
 			break;
 		case CRYPTO_3DES_CBC:
+			if (ratecheck(&tdeswarn, &warninterval))
+				gone_in(13, "3DES cipher via /dev/crypto");
 			txform = &enc_xform_3des;
 			break;
 		case CRYPTO_BLF_CBC:
+			if (ratecheck(&blfwarn, &warninterval))
+				gone_in(13, "Blowfish cipher via /dev/crypto");
 			txform = &enc_xform_blf;
 			break;
 		case CRYPTO_CAST_CBC:
+			if (ratecheck(&castwarn, &warninterval))
+				gone_in(13, "CAST128 cipher via /dev/crypto");
 			txform = &enc_xform_cast5;
 			break;
 		case CRYPTO_SKIPJACK_CBC:
+			if (ratecheck(&skipwarn, &warninterval))
+				gone_in(13, "Skipjack cipher via /dev/crypto");
 			txform = &enc_xform_skipjack;
 			break;
 		case CRYPTO_AES_CBC:
@@ -436,6 +454,8 @@ cryptof_ioctl(
 			txform = &enc_xform_null;
 			break;
 		case CRYPTO_ARC4:
+			if (ratecheck(&arc4warn, &warninterval))
+				gone_in(13, "ARC4 cipher via /dev/crypto");
 			txform = &enc_xform_arc4;
 			break;
  		case CRYPTO_CAMELLIA_CBC:
@@ -464,6 +484,9 @@ cryptof_ioctl(
 		case 0:
 			break;
 		case CRYPTO_MD5_HMAC:
+			if (ratecheck(&md5warn, &warninterval))
+				gone_in(13,
+				    "MD5-HMAC authenticator via /dev/crypto");
 			thash = &auth_hash_hmac_md5;
 			break;
 		case CRYPTO_POLY1305:
diff --git a/freebsd/sys/sys/ata.h b/freebsd/sys/sys/ata.h
index 0559b35..df87ddb 100644
--- a/freebsd/sys/sys/ata.h
+++ b/freebsd/sys/sys/ata.h
@@ -66,7 +66,8 @@ struct ata_params {
 /*023*/ u_int8_t        revision[8];            /* firmware revision */
 /*027*/ u_int8_t        model[40];              /* model name */
 /*047*/ u_int16_t       sectors_intr;           /* sectors per interrupt */
-/*048*/ u_int16_t       usedmovsd;              /* double word read/write? */
+/*048*/ u_int16_t       tcg;                    /* Trusted Computing Group */
+#define ATA_SUPPORT_TCG                 0x0001
 /*049*/ u_int16_t       capabilities1;
 #define ATA_SUPPORT_DMA                 0x0100
 #define ATA_SUPPORT_LBA                 0x0200
@@ -92,6 +93,12 @@ struct ata_params {
 /*057*/ u_int16_t       current_size_1;
 /*058*/ u_int16_t       current_size_2;
 /*059*/ u_int16_t       multi;
+#define ATA_SUPPORT_BLOCK_ERASE_EXT     0x8000
+#define ATA_SUPPORT_OVERWRITE_EXT       0x4000
+#define ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT 0x2000
+#define ATA_SUPPORT_SANITIZE            0x1000
+#define	ATA_SUPPORT_SANITIZE_ALLOWED	0x0800
+#define	ATA_SUPPORT_ANTIFREEZE_LOCK_EXT	0x0400
 #define ATA_MULTI_VALID                 0x0100
 
 /*060*/ u_int16_t       lba_size_1;
@@ -107,6 +114,7 @@ struct ata_params {
 /*069*/ u_int16_t       support3;
 #define ATA_SUPPORT_RZAT                0x0020
 #define ATA_SUPPORT_DRAT                0x4000
+#define ATA_ENCRYPTS_ALL_USER_DATA      0x0010  /* Self-encrypting drive */
 #define	ATA_SUPPORT_ZONE_MASK		0x0003
 #define	ATA_SUPPORT_ZONE_NR		0x0000
 #define	ATA_SUPPORT_ZONE_HOST_AWARE	0x0001
@@ -236,12 +244,15 @@ struct ata_params {
 #define ATA_SUPPORT_FREEFALL		0x0020
 #define ATA_SUPPORT_SENSE_REPORT	0x0040
 #define ATA_SUPPORT_EPC			0x0080
+#define ATA_SUPPORT_AMAX_ADDR		0x0100
+#define ATA_SUPPORT_DSN			0x0200
 /*120*/ u_int16_t       enabled2;
 #define ATA_ENABLED_WRITEREADVERIFY	0x0002
 #define ATA_ENABLED_WRITEUNCORREXT	0x0004
 #define ATA_ENABLED_FREEFALL		0x0020
 #define ATA_ENABLED_SENSE_REPORT	0x0040
 #define ATA_ENABLED_EPC			0x0080
+#define ATA_ENABLED_DSN			0x0200
 	u_int16_t       reserved121[6];
 /*127*/ u_int16_t       removable_status;
 /*128*/ u_int16_t       security_status;
@@ -259,7 +270,19 @@ struct ata_params {
 /*162*/ u_int16_t       cfa_kms_support;
 /*163*/ u_int16_t       cfa_trueide_modes;
 /*164*/ u_int16_t       cfa_memory_modes;
-	u_int16_t       reserved165[4];
+	u_int16_t       reserved165[3];
+/*168*/ u_int16_t       form_factor;
+#define ATA_FORM_FACTOR_MASK		0x000f
+#define ATA_FORM_FACTOR_NOT_REPORTED	0x0000
+#define ATA_FORM_FACTOR_5_25		0x0001
+#define ATA_FORM_FACTOR_3_5		0x0002
+#define ATA_FORM_FACTOR_2_5		0x0003
+#define ATA_FORM_FACTOR_1_8		0x0004
+#define ATA_FORM_FACTOR_SUB_1_8		0x0005
+#define ATA_FORM_FACTOR_MSATA		0x0006
+#define ATA_FORM_FACTOR_M_2		0x0007
+#define ATA_FORM_FACTOR_MICRO_SSD	0x0008
+#define ATA_FORM_FACTOR_C_FAST		0x0009
 /*169*/	u_int16_t       support_dsm;
 #define ATA_SUPPORT_DSM_TRIM		0x0001
 	u_int16_t       reserved170[6];
@@ -418,6 +441,10 @@ struct ata_params {
 #define		ATA_RFPDMA_ZAC_MGMT_IN	0x02	/* NCQ ZAC mgmt in w/data */
 #define ATA_SEP_ATTN                    0x67    /* SEP request */
 #define ATA_SEEK                        0x70    /* seek */
+#define	ATA_AMAX_ADDR			0x78	/* Accessible Max Address */
+#define		ATA_AMAX_ADDR_GET	0x00	/* GET NATIVE MAX ADDRESS EXT */
+#define		ATA_AMAX_ADDR_SET	0x01	/* SET ACCESSIBLE MAX ADDRESS EXT */
+#define		ATA_AMAX_ADDR_FREEZE	0x02	/* FREEZE ACCESSIBLE MAX ADDRESS EXT */
 #define	ATA_ZAC_MANAGEMENT_OUT		0x9f	/* ZAC management out */
 #define		ATA_ZM_CLOSE_ZONE	0x01	/* close zone */
 #define		ATA_ZM_FINISH_ZONE	0x02	/* finish zone */
@@ -429,6 +456,7 @@ struct ata_params {
 #define ATA_ATAPI_IDENTIFY              0xa1    /* get ATAPI params*/
 #define ATA_SERVICE                     0xa2    /* service command */
 #define ATA_SMART_CMD                   0xb0    /* SMART command */
+#define	ATA_SANITIZE			0xb4	/* sanitize device */
 #define ATA_CFA_ERASE                   0xc0    /* CFA erase */
 #define ATA_READ_MUL                    0xc4    /* read multi */
 #define ATA_WRITE_MUL                   0xc5    /* write multi */
diff --git a/freebsd/sys/sys/bus.h b/freebsd/sys/sys/bus.h
index e2c4fe1..1ac476a 100644
--- a/freebsd/sys/sys/bus.h
+++ b/freebsd/sys/sys/bus.h
@@ -152,6 +152,7 @@ struct devreq {
 
 #include <sys/eventhandler.h>
 #include <sys/kobj.h>
+#include <sys/systm.h>
 
 /**
  * devctl hooks.  Typically one should use the devctl_notify
@@ -808,16 +809,24 @@ DECLARE_MODULE(name##_##busname, name##_##busname##_mod,		\
 static __inline type varp ## _get_ ## var(device_t dev)			\
 {									\
 	uintptr_t v;							\
-	BUS_READ_IVAR(device_get_parent(dev), dev,			\
+	int e;								\
+	e = BUS_READ_IVAR(device_get_parent(dev), dev,			\
 	    ivarp ## _IVAR_ ## ivar, &v);				\
+	KASSERT(e == 0, ("%s failed for %s on bus %s, error = %d",	\
+	    __func__, device_get_nameunit(dev),				\
+	    device_get_nameunit(device_get_parent(dev)), e));		\
 	return ((type) v);						\
 }									\
 									\
 static __inline void varp ## _set_ ## var(device_t dev, type t)		\
 {									\
 	uintptr_t v = (uintptr_t) t;					\
-	BUS_WRITE_IVAR(device_get_parent(dev), dev,			\
+	int e;								\
+	e = BUS_WRITE_IVAR(device_get_parent(dev), dev,			\
 	    ivarp ## _IVAR_ ## ivar, v);				\
+	KASSERT(e == 0, ("%s failed for %s on bus %s, error = %d",	\
+	    __func__, device_get_nameunit(dev),				\
+	    device_get_nameunit(device_get_parent(dev)), e));		\
 }
 #else /* __rtems__ */
 #define __BUS_ACCESSOR(varp, var, ivarp, ivar, type)			\
diff --git a/freebsd/sys/sys/file.h b/freebsd/sys/sys/file.h
index 20beac2..22e6c8d 100644
--- a/freebsd/sys/sys/file.h
+++ b/freebsd/sys/sys/file.h
@@ -184,7 +184,10 @@ struct file {
 	/*
 	 *  DTYPE_VNODE specific fields.
 	 */
-	int		f_seqcount;	/* (a) Count of sequential accesses. */
+	union {
+		int16_t	f_seqcount;	/* (a) Count of sequential accesses. */
+		int	f_pipegen;
+	};
 	off_t		f_nextoff;	/* next expected read/write offset. */
 	union {
 		struct cdev_privdata *fvn_cdevpriv;
diff --git a/freebsd/sys/sys/mount.h b/freebsd/sys/sys/mount.h
index c2780bb..edc66f0 100644
--- a/freebsd/sys/sys/mount.h
+++ b/freebsd/sys/sys/mount.h
@@ -296,6 +296,7 @@ void          __mnt_vnode_markerfree_active(struct vnode **mvp, struct mount *);
 #define	MNT_NOCLUSTERW	0x0000000080000000ULL /* disable cluster write */
 #define	MNT_SUJ		0x0000000100000000ULL /* using journaled soft updates */
 #define	MNT_AUTOMOUNTED	0x0000000200000000ULL /* mounted by automountd(8) */
+#define	MNT_UNTRUSTED	0x0000000800000000ULL /* filesys metadata untrusted */
 
 /*
  * NFS export related mount flags.
@@ -333,7 +334,8 @@ void          __mnt_vnode_markerfree_active(struct vnode **mvp, struct mount *);
 			MNT_NOCLUSTERW	| MNT_SUIDDIR	| MNT_SOFTDEP	| \
 			MNT_IGNORE	| MNT_EXPUBLIC	| MNT_NOSYMFOLLOW | \
 			MNT_GJOURNAL	| MNT_MULTILABEL | MNT_ACLS	| \
-			MNT_NFS4ACLS	| MNT_AUTOMOUNTED | MNT_VERIFIED)
+			MNT_NFS4ACLS	| MNT_AUTOMOUNTED | MNT_VERIFIED | \
+			MNT_UNTRUSTED)
 
 /* Mask of flags that can be updated. */
 #define	MNT_UPDATEMASK (MNT_NOSUID	| MNT_NOEXEC	| \
@@ -342,7 +344,7 @@ void          __mnt_vnode_markerfree_active(struct vnode **mvp, struct mount *);
 			MNT_NOSYMFOLLOW	| MNT_IGNORE	| \
 			MNT_NOCLUSTERR	| MNT_NOCLUSTERW | MNT_SUIDDIR	| \
 			MNT_ACLS	| MNT_USER	| MNT_NFS4ACLS	| \
-			MNT_AUTOMOUNTED)
+			MNT_AUTOMOUNTED | MNT_UNTRUSTED)
 
 /*
  * External filesystem command modifier flags.
@@ -396,6 +398,7 @@ void          __mnt_vnode_markerfree_active(struct vnode **mvp, struct mount *);
 #define	MNTK_MARKER		0x00001000
 #define	MNTK_UNMAPPED_BUFS	0x00002000
 #define	MNTK_USES_BCACHE	0x00004000 /* FS uses the buffer cache. */
+#define	MNTK_TEXT_REFS		0x00008000 /* Keep use ref for text */
 #define MNTK_NOASYNC	0x00800000	/* disable async */
 #define MNTK_UNMOUNT	0x01000000	/* unmount in progress */
 #define	MNTK_MWAIT	0x02000000	/* waiting for unmount to finish */
diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h
index f27f550..a69d91b 100644
--- a/freebsd/sys/sys/proc.h
+++ b/freebsd/sys/sys/proc.h
@@ -382,7 +382,11 @@ struct thread {
 	vm_offset_t	td_kstack;	/* (a) Kernel VA of kstack. */
 	int		td_kstack_pages; /* (a) Size of the kstack. */
 	volatile u_int	td_critnest;	/* (k*) Critical section nest level. */
+#ifdef __amd64__
+	uint32_t	td_md_pad0[16];
+#else
 	struct mdthread td_md;		/* (k) Any machine-dependent fields. */
+#endif
 	struct kaudit_record	*td_ar;	/* (k) Active audit record, if any. */
 	struct lpohead	td_lprof[2];	/* (a) lock profiling objects. */
 	struct kdtrace_thread	*td_dtrace; /* (*) DTrace-specific data. */
@@ -400,6 +404,9 @@ struct thread {
 	int		td_oncpu;	/* (t) Which cpu we are on. */
 	void		*td_lkpi_task;	/* LinuxKPI task struct pointer */
 	int		td_pmcpend;
+#ifdef __amd64__
+	struct mdthread td_md;		/* (k) Any machine-dependent fields. */
+#endif
 #endif /* __rtems__ */
 };
 
diff --git a/freebsd/sys/sys/sysctl.h b/freebsd/sys/sys/sysctl.h
index 4b2bfd7..3ad6647 100644
--- a/freebsd/sys/sys/sysctl.h
+++ b/freebsd/sys/sys/sysctl.h
@@ -216,6 +216,8 @@ int sysctl_handle_counter_u64_array(SYSCTL_HANDLER_ARGS);
 int sysctl_handle_uma_zone_max(SYSCTL_HANDLER_ARGS);
 int sysctl_handle_uma_zone_cur(SYSCTL_HANDLER_ARGS);
 
+int sysctl_sec_to_timeval(SYSCTL_HANDLER_ARGS);
+
 int sysctl_dpcpu_int(SYSCTL_HANDLER_ARGS);
 int sysctl_dpcpu_long(SYSCTL_HANDLER_ARGS);
 int sysctl_dpcpu_quad(SYSCTL_HANDLER_ARGS);
@@ -855,6 +857,24 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
 	    NULL);							\
 })
 
+/* OID expressing a struct timeval as seconds */
+#define	SYSCTL_TIMEVAL_SEC(parent, nbr, name, access, ptr, descr)	\
+	SYSCTL_OID(parent, nbr, name,					\
+	    CTLTYPE_INT | CTLFLAG_MPSAFE | CTLFLAG_RD | (access),	\
+	    (ptr), 0, sysctl_sec_to_timeval, "I", descr);		\
+	CTASSERT(((access) & CTLTYPE) == 0 ||				\
+	    ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_INT)
+#define	SYSCTL_ADD_TIMEVAL_SEC(ctx, parent, nbr, name, access, ptr, descr) \
+({									\
+	struct timeval *__ptr = (ptr);					\
+	CTASSERT(((access) & CTLTYPE) == 0 ||				\
+	    ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_INT);		\
+	sysctl_add_oid(ctx, parent, nbr, name,				\
+	    CTLTYPE_INT | CTLFLAG_MPSAFE | CTLFLAG_RD | (access),	\
+	    __ptr, 0, sysctl_sec_to_timeval, "I", __DESCR(descr),	\
+	    NULL);							\
+})
+
 /*
  * A macro to generate a read-only sysctl to indicate the presence of optional
  * kernel features.
diff --git a/freebsd/sys/sys/vnode.h b/freebsd/sys/sys/vnode.h
index 465762b..d88ff30 100644
--- a/freebsd/sys/sys/vnode.h
+++ b/freebsd/sys/sys/vnode.h
@@ -234,6 +234,7 @@ struct xvnode {
  *	VI_DOOMED is doubly protected by the interlock and vnode lock.  Both
  *	are required for writing but the status may be checked with either.
  */
+#define	VI_TEXT_REF	0x0001	/* Text ref grabbed use ref */
 #define	VI_MOUNT	0x0020	/* Mount in progress */
 #define	VI_DOOMED	0x0080	/* This vnode is being recycled */
 #define	VI_FREE		0x0100	/* This vnode is on the freelist */
@@ -827,27 +828,30 @@ void	vop_rename_fail(struct vop_rename_args *ap);
 
 #define VOP_LOCK(vp, flags) VOP_LOCK1(vp, flags, __FILE__, __LINE__)
 
-#ifdef	INVARIANTS
+#ifdef INVARIANTS
 #define	VOP_ADD_WRITECOUNT_CHECKED(vp, cnt)				\
 do {									\
 	int error_;							\
 									\
 	error_ = VOP_ADD_WRITECOUNT((vp), (cnt));			\
-	MPASS(error_ == 0);						\
+	VNASSERT(error_ == 0, (vp), ("VOP_ADD_WRITECOUNT returned %d",	\
+	    error_));							\
 } while (0)
 #define	VOP_SET_TEXT_CHECKED(vp)					\
 do {									\
 	int error_;							\
 									\
 	error_ = VOP_SET_TEXT((vp));					\
-	MPASS(error_ == 0);						\
+	VNASSERT(error_ == 0, (vp), ("VOP_SET_TEXT returned %d",	\
+	    error_));							\
 } while (0)
 #define	VOP_UNSET_TEXT_CHECKED(vp)					\
 do {									\
 	int error_;							\
 									\
 	error_ = VOP_UNSET_TEXT((vp));					\
-	MPASS(error_ == 0);						\
+	VNASSERT(error_ == 0, (vp), ("VOP_UNSET_TEXT returned %d",	\
+	    error_));							\
 } while (0)
 #else
 #define	VOP_ADD_WRITECOUNT_CHECKED(vp, cnt)	VOP_ADD_WRITECOUNT((vp), (cnt))
diff --git a/freebsd/usr.bin/netstat/ipsec.c b/freebsd/usr.bin/netstat/ipsec.c
index 97111b4..644519a 100644
--- a/freebsd/usr.bin/netstat/ipsec.c
+++ b/freebsd/usr.bin/netstat/ipsec.c
@@ -137,33 +137,18 @@ static struct val2str ipsec_ahnames[] = {
 	{ SADB_AALG_NONE, "none", },
 	{ SADB_AALG_MD5HMAC, "hmac-md5", },
 	{ SADB_AALG_SHA1HMAC, "hmac-sha1", },
-	{ SADB_X_AALG_MD5, "md5", },
-	{ SADB_X_AALG_SHA, "sha", },
+	{ SADB_X_AALG_MD5, "keyed-md5", },
+	{ SADB_X_AALG_SHA, "keyed-sha1", },
 	{ SADB_X_AALG_NULL, "null", },
-#ifdef SADB_X_AALG_SHA2_256
 	{ SADB_X_AALG_SHA2_256, "hmac-sha2-256", },
-#endif
-#ifdef SADB_X_AALG_SHA2_384
 	{ SADB_X_AALG_SHA2_384, "hmac-sha2-384", },
-#endif
-#ifdef SADB_X_AALG_SHA2_512
 	{ SADB_X_AALG_SHA2_512, "hmac-sha2-512", },
-#endif
-#ifdef SADB_X_AALG_RIPEMD160HMAC
 	{ SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", },
-#endif
-#ifdef SADB_X_AALG_AES_XCBC_MAC
 	{ SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", },
-#endif
-#ifdef SADB_X_AALG_AES128GMAC
+	{ SADB_X_AALG_TCP_MD5, "tcp-md5", },
 	{ SADB_X_AALG_AES128GMAC, "aes-gmac-128", },
-#endif
-#ifdef SADB_X_AALG_AES192GMAC
 	{ SADB_X_AALG_AES192GMAC, "aes-gmac-192", },
-#endif
-#ifdef SADB_X_AALG_AES256GMAC
 	{ SADB_X_AALG_AES256GMAC, "aes-gmac-256", },
-#endif
 	{ -1, NULL },
 };
 
@@ -174,15 +159,11 @@ static struct val2str ipsec_espnames[] = {
 	{ SADB_EALG_NULL, "null", },
 	{ SADB_X_EALG_CAST128CBC, "cast128-cbc", },
 	{ SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", },
-#ifdef SADB_X_EALG_RIJNDAELCBC
 	{ SADB_X_EALG_RIJNDAELCBC, "rijndael-cbc", },
-#endif
-#ifdef SADB_X_EALG_AESCTR
+	{ SADB_X_EALG_CAMELLIACBC, "camellia-cbc", },
 	{ SADB_X_EALG_AESCTR, "aes-ctr", },
-#endif
-#ifdef SADB_X_EALG_AESGCM16
 	{ SADB_X_EALG_AESGCM16, "aes-gcm-16", },
-#endif
+	{ SADB_X_EALG_AESGMAC, "aes-gmac", },
 	{ -1, NULL },
 };
 
diff --git a/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h b/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h
index cd38c7c..77b166b 100644
--- a/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h
+++ b/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h
@@ -415,6 +415,7 @@
 #define	bus_dma_tag_create _bsd_bus_dma_tag_create
 #define	bus_dma_tag_destroy _bsd_bus_dma_tag_destroy
 #define	bus_enumerate_hinted_children _bsd_bus_enumerate_hinted_children
+#define	bus_free_resource _bsd_bus_free_resource
 #define	bus_generic_activate_resource _bsd_bus_generic_activate_resource
 #define	bus_generic_add_child _bsd_bus_generic_add_child
 #define	bus_generic_adjust_resource _bsd_bus_generic_adjust_resource
@@ -2448,6 +2449,7 @@
 #define	ipsec_setspidx_inpcb _bsd_ipsec_setspidx_inpcb
 #define	ipsec_updateid _bsd_ipsec_updateid
 #define	ipsec_updatereplay _bsd_ipsec_updatereplay
+#define	ipsec_warn_interval _bsd_ipsec_warn_interval
 #define	ip_slowtimo _bsd_ip_slowtimo
 #define	ip_srcroute _bsd_ip_srcroute
 #define	ipstat _bsd_ipstat
@@ -4464,6 +4466,7 @@
 #define	SHA512_Update _bsd_SHA512_Update
 #define	simplebus_add_device _bsd_simplebus_add_device
 #define	simplebus_driver _bsd_simplebus_driver
+#define	simplebus_fill_ranges _bsd_simplebus_fill_ranges
 #define	simplebus_init _bsd_simplebus_init
 #define	simplebus_setup_dinfo _bsd_simplebus_setup_dinfo
 #define	SipHash_End _bsd_SipHash_End
@@ -4506,8 +4509,6 @@
 #define	Skein_512_Output _bsd_Skein_512_Output
 #define	Skein_512_Process_Block _bsd_Skein_512_Process_Block
 #define	Skein_512_Update _bsd_Skein_512_Update
-#define	Skein_Get64_LSB_First _bsd_Skein_Get64_LSB_First
-#define	Skein_Put64_LSB_First _bsd_Skein_Put64_LSB_First
 #define	skipjack_backwards _bsd_skipjack_backwards
 #define	skipjack_forwards _bsd_skipjack_forwards
 #define	sl_compress_init _bsd_sl_compress_init
@@ -4767,6 +4768,7 @@
 #define	sysctl_remove_name _bsd_sysctl_remove_name
 #define	sysctl_remove_oid _bsd_sysctl_remove_oid
 #define	sysctl_rename_oid _bsd_sysctl_rename_oid
+#define	sysctl_sec_to_timeval _bsd_sysctl_sec_to_timeval
 #define	sysctl___security _bsd_sysctl___security
 #define	sysctl___sysctl _bsd_sysctl___sysctl
 #define	sysctl_unregister_oid _bsd_sysctl_unregister_oid



More information about the vc mailing list