[rtems-libbsd commit] Update to FreeBSD 9.3

Sebastian Huber sebh at rtems.org
Fri Feb 13 09:48:14 UTC 2015


Module:    rtems-libbsd
Branch:    master
Commit:    7eeb079d84bc4abe9897be0047fc28a754e46ecd
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=7eeb079d84bc4abe9897be0047fc28a754e46ecd

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Feb  2 14:27:13 2015 +0100

Update to FreeBSD 9.3

---

 freebsd-org                                     |    2 +-
 freebsd/include/rpc/auth.h                      |   49 +-
 freebsd/include/rpc/auth_des.h                  |   53 +-
 freebsd/include/rpc/auth_unix.h                 |   49 +-
 freebsd/include/rpc/clnt.h                      |   69 +-
 freebsd/include/rpc/clnt_soc.h                  |   53 +-
 freebsd/include/rpc/pmap_clnt.h                 |   49 +-
 freebsd/include/rpc/pmap_prot.h                 |   49 +-
 freebsd/include/rpc/rpc.h                       |   49 +-
 freebsd/include/rpc/rpc_msg.h                   |   49 +-
 freebsd/include/rpc/rpcb_clnt.h                 |   53 +-
 freebsd/include/rpc/rpcb_prot.x                 |   49 +-
 freebsd/include/rpc/rpcent.h                    |   53 +-
 freebsd/include/rpc/svc.h                       |   49 +-
 freebsd/include/rpc/svc_auth.h                  |   49 +-
 freebsd/include/rpc/svc_soc.h                   |   53 +-
 freebsd/include/rpc/xdr.h                       |   49 +-
 freebsd/lib/libc/net/getaddrinfo.c              |  111 +-
 freebsd/lib/libipsec/ipsec_dump_policy.c        |    1 +
 freebsd/sbin/ifconfig/af_inet.c                 |    4 +-
 freebsd/sbin/ifconfig/ifgroup.c                 |    4 +-
 freebsd/sbin/route/keywords                     |    2 +
 freebsd/sbin/route/route.c                      |   24 +-
 freebsd/sys/cam/ata/ata_all.h                   |    2 +
 freebsd/sys/cam/cam.h                           |    4 +-
 freebsd/sys/cam/cam_ccb.h                       |   17 +-
 freebsd/sys/cam/cam_debug.h                     |   17 +-
 freebsd/sys/cam/cam_periph.h                    |    3 +-
 freebsd/sys/cam/cam_xpt.h                       |    4 +
 freebsd/sys/cam/cam_xpt_sim.h                   |    4 -
 freebsd/sys/cam/scsi/scsi_all.c                 |   32 +-
 freebsd/sys/cam/scsi/scsi_all.h                 |    4 +
 freebsd/sys/cam/scsi/scsi_da.h                  |   32 +
 freebsd/sys/contrib/pf/net/pf_lb.c              |   53 +-
 freebsd/sys/dev/bce/if_bce.c                    |   28 +-
 freebsd/sys/dev/bce/if_bcefw.h                  |    8 +-
 freebsd/sys/dev/bce/if_bcereg.h                 |   10 +-
 freebsd/sys/dev/bge/if_bge.c                    |  217 +++-
 freebsd/sys/dev/bge/if_bgereg.h                 |   25 +-
 freebsd/sys/dev/e1000/e1000_defines.h           |    2 +-
 freebsd/sys/dev/e1000/if_em.c                   |    9 +-
 freebsd/sys/dev/e1000/if_igb.c                  |   14 +-
 freebsd/sys/dev/e1000/if_lem.c                  |   10 +-
 freebsd/sys/dev/fxp/if_fxpreg.h                 |    2 +-
 freebsd/sys/dev/mii/brgphy.c                    |    3 +
 freebsd/sys/dev/pci/pci.c                       |  283 +++--
 freebsd/sys/dev/pci/pci_pci.c                   |  508 +++++++--
 freebsd/sys/dev/pci/pci_private.h               |    2 +
 freebsd/sys/dev/pci/pci_user.c                  |  128 ++-
 freebsd/sys/dev/pci/pcib_private.h              |    3 +-
 freebsd/sys/dev/pci/pcireg.h                    |    9 +
 freebsd/sys/dev/pci/pcivar.h                    |    9 +
 freebsd/sys/dev/re/if_re.c                      |   84 +-
 freebsd/sys/dev/usb/controller/ehci.c           |  112 +-
 freebsd/sys/dev/usb/controller/ohci.c           |    5 +-
 freebsd/sys/dev/usb/controller/usb_controller.c |   67 +-
 freebsd/sys/dev/usb/controller/xhcireg.h        |    3 +-
 freebsd/sys/dev/usb/quirk/usb_quirk.c           |   11 +
 freebsd/sys/dev/usb/storage/umass.c             |    4 +-
 freebsd/sys/dev/usb/usb.h                       |    3 +
 freebsd/sys/dev/usb/usb_bus.h                   |    1 +
 freebsd/sys/dev/usb/usb_busdma.c                |   27 +-
 freebsd/sys/dev/usb/usb_controller.h            |    1 +
 freebsd/sys/dev/usb/usb_core.h                  |    2 +
 freebsd/sys/dev/usb/usb_dev.c                   |  254 ++++-
 freebsd/sys/dev/usb/usb_device.c                |  116 ++-
 freebsd/sys/dev/usb/usb_device.h                |   17 +-
 freebsd/sys/dev/usb/usb_freebsd.h               |    3 +
 freebsd/sys/dev/usb/usb_generic.c               |   84 +-
 freebsd/sys/dev/usb/usb_hub.c                   |  395 ++++++-
 freebsd/sys/dev/usb/usb_hub.h                   |    7 +
 freebsd/sys/dev/usb/usb_ioctl.h                 |   64 +-
 freebsd/sys/dev/usb/usb_msctest.c               |   74 +-
 freebsd/sys/dev/usb/usb_process.c               |   12 +
 freebsd/sys/dev/usb/usb_process.h               |    1 +
 freebsd/sys/dev/usb/usb_request.c               |   80 +-
 freebsd/sys/dev/usb/usb_transfer.c              |   59 +-
 freebsd/sys/dev/usb/usbdi.h                     |    3 +
 freebsd/sys/i386/include/machine/specialreg.h   |    6 +
 freebsd/sys/kern/init_main.c                    |   16 +-
 freebsd/sys/kern/kern_event.c                   |  131 ++-
 freebsd/sys/kern/kern_linker.c                  |  197 ++--
 freebsd/sys/kern/kern_mbuf.c                    |  137 ++-
 freebsd/sys/kern/kern_mib.c                     |    7 +
 freebsd/sys/kern/kern_time.c                    |  242 ++++-
 freebsd/sys/kern/kern_timeout.c                 |   16 +-
 freebsd/sys/kern/subr_lock.c                    |    4 +-
 freebsd/sys/kern/subr_rman.c                    |   31 +-
 freebsd/sys/kern/subr_sbuf.c                    |    5 +-
 freebsd/sys/kern/subr_taskqueue.c               |   36 +-
 freebsd/sys/kern/sys_generic.c                  |    4 +
 freebsd/sys/kern/uipc_sockbuf.c                 |   78 +-
 freebsd/sys/kern/uipc_socket.c                  |   59 +-
 freebsd/sys/kern/uipc_syscalls.c                |   61 +-
 freebsd/sys/kern/uipc_usrreq.c                  |   19 +-
 freebsd/sys/mips/include/machine/cpufunc.h      |    2 +-
 freebsd/sys/net/ieee8023ad_lacp.c               |   41 +-
 freebsd/sys/net/if.c                            |    4 +-
 freebsd/sys/net/if_lagg.c                       |   19 +-
 freebsd/sys/net/if_media.h                      |    5 +-
 freebsd/sys/net/if_spppsubr.c                   |    2 +-
 freebsd/sys/net/if_tap.c                        |    6 +-
 freebsd/sys/net/if_tun.c                        |    1 +
 freebsd/sys/net/if_vlan.c                       |    2 +
 freebsd/sys/net/radix.c                         |  415 ++++----
 freebsd/sys/net/radix.h                         |    6 +-
 freebsd/sys/net/radix_mpath.c                   |   86 +-
 freebsd/sys/net/route.c                         |  167 ++-
 freebsd/sys/net/route.h                         |    9 +-
 freebsd/sys/net/rtsock.c                        |  198 ++--
 freebsd/sys/net80211/ieee80211.h                |    1 +
 freebsd/sys/net80211/ieee80211_proto.h          |    3 +
 freebsd/sys/netinet/if_ether.c                  |    8 +-
 freebsd/sys/netinet/in.c                        |   52 +-
 freebsd/sys/netinet/in_mcast.c                  |   30 +-
 freebsd/sys/netinet/in_pcb.c                    |    2 +-
 freebsd/sys/netinet/ip_icmp.c                   |    1 +
 freebsd/sys/netinet/ip_input.c                  |    5 +-
 freebsd/sys/netinet/ip_mroute.c                 |   20 +-
 freebsd/sys/netinet/ip_output.c                 |   16 +-
 freebsd/sys/netinet/sctp.h                      |   79 +-
 freebsd/sys/netinet/sctp_asconf.c               |   92 +-
 freebsd/sys/netinet/sctp_auth.c                 |  137 +--
 freebsd/sys/netinet/sctp_auth.h                 |   15 +-
 freebsd/sys/netinet/sctp_bsd_addr.c             |   13 +-
 freebsd/sys/netinet/sctp_constants.h            |   16 +-
 freebsd/sys/netinet/sctp_dtrace_define.h        |  261 ++---
 freebsd/sys/netinet/sctp_indata.c               |  725 ++++---------
 freebsd/sys/netinet/sctp_input.c                |  128 ++-
 freebsd/sys/netinet/sctp_os_bsd.h               |   26 +-
 freebsd/sys/netinet/sctp_output.c               |  302 ++++--
 freebsd/sys/netinet/sctp_pcb.c                  |  229 ++--
 freebsd/sys/netinet/sctp_pcb.h                  |    2 +-
 freebsd/sys/netinet/sctp_structs.h              |    4 +-
 freebsd/sys/netinet/sctp_sysctl.c               |   17 +-
 freebsd/sys/netinet/sctp_sysctl.h               |    8 +-
 freebsd/sys/netinet/sctp_timer.c                |   48 +-
 freebsd/sys/netinet/sctp_uio.h                  |    4 -
 freebsd/sys/netinet/sctp_usrreq.c               |  176 ++--
 freebsd/sys/netinet/sctputil.c                  |  138 ++-
 freebsd/sys/netinet/sctputil.h                  |    4 +-
 freebsd/sys/netinet/tcp_input.c                 |    6 +-
 freebsd/sys/netinet/tcp_reass.c                 |    7 +-
 freebsd/sys/netinet/tcp_subr.c                  |    6 +-
 freebsd/sys/netinet6/frag6.c                    |    5 +-
 freebsd/sys/netinet6/icmp6.c                    |    1 +
 freebsd/sys/netinet6/in6.c                      |    1 +
 freebsd/sys/netinet6/in6_mcast.c                |   69 +-
 freebsd/sys/netinet6/in6_pcb.c                  |    2 +-
 freebsd/sys/netinet6/ip6_forward.c              |    7 +-
 freebsd/sys/netinet6/ip6_input.c                |   16 +-
 freebsd/sys/netinet6/ip6_mroute.c               |  596 +++++------
 freebsd/sys/netinet6/ip6_mroute.h               |    5 -
 freebsd/sys/netinet6/nd6.c                      |   17 +-
 freebsd/sys/netinet6/nd6_nbr.c                  |    4 +-
 freebsd/sys/netinet6/sctp6_usrreq.c             |    4 +-
 freebsd/sys/netpfil/ipfw/ip_dummynet.c          |    2 +-
 freebsd/sys/netpfil/ipfw/ip_fw2.c               |   39 +-
 freebsd/sys/netpfil/ipfw/ip_fw_log.c            |   11 +-
 freebsd/sys/netpfil/ipfw/ip_fw_nat.c            |   76 +-
 freebsd/sys/netpfil/ipfw/ip_fw_private.h        |   24 +-
 freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c        |   14 +-
 freebsd/sys/netpfil/ipfw/ip_fw_table.c          |    8 +-
 freebsd/sys/opencrypto/deflate.c                |    8 +-
 freebsd/sys/pci/if_rlreg.h                      |   29 +-
 freebsd/sys/rpc/types.h                         |   51 +-
 freebsd/sys/sys/_rmlock.h                       |    5 +-
 freebsd/sys/sys/_rwlock.h                       |    3 -
 freebsd/sys/sys/ata.h                           |    7 +
 freebsd/sys/sys/bus_dma.h                       |    7 -
 freebsd/sys/sys/conf.h                          |    1 +
 freebsd/sys/sys/eventhandler.h                  |   18 +
 freebsd/sys/sys/eventvar.h                      |    2 +-
 freebsd/sys/sys/kernel.h                        |    4 +-
 freebsd/sys/sys/linker.h                        |    4 -
 freebsd/sys/sys/lockmgr.h                       |    1 +
 freebsd/sys/sys/mbuf.h                          |   23 +-
 freebsd/sys/sys/mman.h                          |   11 +
 freebsd/sys/sys/pciio.h                         |   21 +
 freebsd/sys/sys/proc.h                          |   10 +-
 freebsd/sys/sys/refcount.h                      |    3 -
 freebsd/sys/sys/rmlock.h                        |   22 +
 freebsd/sys/sys/rwlock.h                        |    3 -
 freebsd/sys/sys/sdt.h                           |  420 +++++---
 freebsd/sys/sys/sockbuf.h                       |    2 +
 freebsd/sys/sys/sysctl.h                        |    1 +
 freebsd/sys/sys/sysproto.h                      |   20 +-
 freebsd/sys/sys/systm.h                         |    2 +
 freebsd/sys/sys/taskqueue.h                     |    1 +
 freebsd/sys/sys/tty.h                           |    2 +
 freebsd/sys/sys/user.h                          |   11 +-
 freebsd/sys/vm/uma_core.c                       |   11 +-
 freebsd/sys/vm/vm.h                             |    1 +
 freebsd/sys/vm/vm_extern.h                      |    4 +-
 freebsd/usr.bin/netstat/main.c                  |   32 +-
 rtemsbsd/include/rtems/bsd/local/miidevs.h      |    5 +
 rtemsbsd/include/rtems/bsd/local/usbdevs.h      |  247 ++++-
 rtemsbsd/include/rtems/bsd/local/usbdevs_data.h | 1268 ++++++++++++++++++++++-
 rtemsbsd/include/rtems/bsd/sys/param.h          |    2 +-
 rtemsbsd/rtems/rtems-bsd-mutex.c                |    1 +
 rtemsbsd/rtems/rtems-bsd-thread.c               |    2 +-
 201 files changed, 7721 insertions(+), 3941 deletions(-)

diff --git a/freebsd-org b/freebsd-org
index 74d8320..a5feb68 160000
--- a/freebsd-org
+++ b/freebsd-org
@@ -1 +1 @@
-Subproject commit 74d8320d56de778817fa39bc074b177c93945481
+Subproject commit a5feb686027eafe7ae45360846ff5ae4cd64fed7
diff --git a/freebsd/include/rpc/auth.h b/freebsd/include/rpc/auth.h
index b19addc..5503762 100644
--- a/freebsd/include/rpc/auth.h
+++ b/freebsd/include/rpc/auth.h
@@ -1,32 +1,31 @@
 /*	$NetBSD: auth.h,v 1.15 2000/06/02 22:57:55 fvdl Exp $	*/
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)auth.h 1.17 88/02/08 SMI
  *	from: @(#)auth.h	2.3 88/08/07 4.0 RPCSRC
diff --git a/freebsd/include/rpc/auth_des.h b/freebsd/include/rpc/auth_des.h
index fff4ebf..58b34d7 100644
--- a/freebsd/include/rpc/auth_des.h
+++ b/freebsd/include/rpc/auth_des.h
@@ -1,32 +1,31 @@
 /*	@(#)auth_des.h	2.2 88/07/29 4.0 RPCSRC; from 1.3 88/02/08 SMI */
 /*	$FreeBSD$ */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  * 
  *	from: @(#)auth_des.h 2.2 88/07/29 4.0 RPCSRC
  *	from: @(#)auth_des.h 1.14    94/04/25 SMI
diff --git a/freebsd/include/rpc/auth_unix.h b/freebsd/include/rpc/auth_unix.h
index b005bac..fa47e8b 100644
--- a/freebsd/include/rpc/auth_unix.h
+++ b/freebsd/include/rpc/auth_unix.h
@@ -1,30 +1,29 @@
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)auth_unix.h 1.8 88/02/08 SMI
  *	from: @(#)auth_unix.h	2.2 88/07/29 4.0 RPCSRC
diff --git a/freebsd/include/rpc/clnt.h b/freebsd/include/rpc/clnt.h
index 1c85a4a..66533e2 100644
--- a/freebsd/include/rpc/clnt.h
+++ b/freebsd/include/rpc/clnt.h
@@ -1,49 +1,31 @@
 /*	$NetBSD: clnt.h,v 1.14 2000/06/02 22:57:55 fvdl Exp $	*/
 
-/*
- * The contents of this file are subject to the Sun Standards
- * License Version 1.0 the (the "License";) You may not use
- * this file except in compliance with the License.  You may
- * obtain a copy of the License at lib/libc/rpc/LICENSE
- *
- * Software distributed under the License is distributed on
- * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
- * express or implied.  See the License for the specific
- * language governing rights and limitations under the License.
- *
- * The Original Code is Copyright 1998 by Sun Microsystems, Inc
- *
- * The Initial Developer of the Original Code is:  Sun
- * Microsystems, Inc.
- *
- * All Rights Reserved.
- *
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2010, Oracle America, Inc.
+ * All rights reserved.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the "Oracle America, Inc." nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)clnt.h 1.31 94/04/29 SMI
  *	from: @(#)clnt.h	2.1 88/07/29 4.0 RPCSRC
@@ -52,9 +34,6 @@
 
 /*
  * clnt.h - Client side remote procedure call interface.
- *
- * Copyright (c) 1986-1991,1994-1999 by Sun Microsystems, Inc.
- * All rights reserved.
  */
 
 #ifndef _RPC_CLNT_H_
diff --git a/freebsd/include/rpc/clnt_soc.h b/freebsd/include/rpc/clnt_soc.h
index 1e7a0de..6536a4b 100644
--- a/freebsd/include/rpc/clnt_soc.h
+++ b/freebsd/include/rpc/clnt_soc.h
@@ -1,33 +1,32 @@
 /*	$NetBSD: clnt_soc.h,v 1.1 2000/06/02 22:57:55 fvdl Exp $	*/
 /*	$FreeBSD$ */
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
diff --git a/freebsd/include/rpc/pmap_clnt.h b/freebsd/include/rpc/pmap_clnt.h
index 89f1614..e8314f6 100644
--- a/freebsd/include/rpc/pmap_clnt.h
+++ b/freebsd/include/rpc/pmap_clnt.h
@@ -1,32 +1,31 @@
 /*	$NetBSD: pmap_clnt.h,v 1.9 2000/06/02 22:57:55 fvdl Exp $	*/
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)pmap_clnt.h 1.11 88/02/08 SMI 
  *	from: @(#)pmap_clnt.h	2.1 88/07/29 4.0 RPCSRC
diff --git a/freebsd/include/rpc/pmap_prot.h b/freebsd/include/rpc/pmap_prot.h
index 366832a..d880c40 100644
--- a/freebsd/include/rpc/pmap_prot.h
+++ b/freebsd/include/rpc/pmap_prot.h
@@ -1,32 +1,31 @@
 /*	$NetBSD: pmap_prot.h,v 1.8 2000/06/02 22:57:55 fvdl Exp $	*/
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)pmap_prot.h 1.14 88/02/08 SMI 
  *	from: @(#)pmap_prot.h	2.1 88/07/29 4.0 RPCSRC
diff --git a/freebsd/include/rpc/rpc.h b/freebsd/include/rpc/rpc.h
index 725b542..e7a3dc8 100644
--- a/freebsd/include/rpc/rpc.h
+++ b/freebsd/include/rpc/rpc.h
@@ -1,32 +1,31 @@
 /*	$NetBSD: rpc.h,v 1.13 2000/06/02 22:57:56 fvdl Exp $	*/
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)rpc.h 1.9 88/02/08 SMI
  *	from: @(#)rpc.h	2.4 89/07/11 4.0 RPCSRC
diff --git a/freebsd/include/rpc/rpc_msg.h b/freebsd/include/rpc/rpc_msg.h
index 354b341..6e8d074 100644
--- a/freebsd/include/rpc/rpc_msg.h
+++ b/freebsd/include/rpc/rpc_msg.h
@@ -1,32 +1,31 @@
 /*	$NetBSD: rpc_msg.h,v 1.11 2000/06/02 22:57:56 fvdl Exp $	*/
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)rpc_msg.h 1.7 86/07/16 SMI
  *	from: @(#)rpc_msg.h	2.1 88/07/29 4.0 RPCSRC
diff --git a/freebsd/include/rpc/rpcb_clnt.h b/freebsd/include/rpc/rpcb_clnt.h
index fa64a85..4552787 100644
--- a/freebsd/include/rpc/rpcb_clnt.h
+++ b/freebsd/include/rpc/rpcb_clnt.h
@@ -1,33 +1,32 @@
 /*	$NetBSD: rpcb_clnt.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $	*/
 /*	$FreeBSD$ */
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
diff --git a/freebsd/include/rpc/rpcb_prot.x b/freebsd/include/rpc/rpcb_prot.x
index c574841..a34bcc1 100644
--- a/freebsd/include/rpc/rpcb_prot.x
+++ b/freebsd/include/rpc/rpcb_prot.x
@@ -1,32 +1,31 @@
-%/*
+%/*-
 % * $FreeBSD$
 % *
-% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
-% * unrestricted use provided that this legend is included on all tape
-% * media and as a part of the software program in whole or part.  Users
-% * may copy or modify Sun RPC without charge, but are not authorized
-% * to license or distribute it to anyone else except as part of a product or
-% * program developed by the user.
-% *
-% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
-% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
-% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
-% *
-% * Sun RPC is provided with no support and without any obligation on the
-% * part of Sun Microsystems, Inc. to assist in its use, correction,
-% * modification or enhancement.
-% *
-% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
-% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
-% * OR ANY PART THEREOF.
+% * Copyright (c) 2009, Sun Microsystems, Inc.
+% * All rights reserved.
 % *
-% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
-% * or profits or other special, indirect and consequential damages, even if
-% * Sun has been advised of the possibility of such damages.
+% * Redistribution and use in source and binary forms, with or without
+% * modification, are permitted provided that the following conditions are met:
+% * - Redistributions of source code must retain the above copyright notice,
+% *   this list of conditions and the following disclaimer.
+% * - Redistributions in binary form must reproduce the above copyright notice,
+% *   this list of conditions and the following disclaimer in the documentation
+% *   and/or other materials provided with the distribution.
+% * - Neither the name of Sun Microsystems, Inc. nor the names of its
+% *   contributors may be used to endorse or promote products derived
+% *   from this software without specific prior written permission.
 % *
-% * Sun Microsystems, Inc.
-% * 2550 Garcia Avenue
-% * Mountain View, California  94043
+% * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+% * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+% * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+% * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+% * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+% * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+% * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+% * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+% * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+% * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+% * POSSIBILITY OF SUCH DAMAGE.
 % */
 %/*
 % * Copyright (c) 1988 by Sun Microsystems, Inc.
diff --git a/freebsd/include/rpc/rpcent.h b/freebsd/include/rpc/rpcent.h
index 876b488..405ba67 100644
--- a/freebsd/include/rpc/rpcent.h
+++ b/freebsd/include/rpc/rpcent.h
@@ -1,33 +1,32 @@
 /*	$NetBSD: rpcent.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $	*/
 /*	$FreeBSD$ */
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
diff --git a/freebsd/include/rpc/svc.h b/freebsd/include/rpc/svc.h
index 8466ef8..2af5550 100644
--- a/freebsd/include/rpc/svc.h
+++ b/freebsd/include/rpc/svc.h
@@ -1,32 +1,31 @@
 /*	$NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $	*/
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)svc.h 1.35 88/12/17 SMI
  *	from: @(#)svc.h      1.27    94/04/25 SMI
diff --git a/freebsd/include/rpc/svc_auth.h b/freebsd/include/rpc/svc_auth.h
index 41fc82b..87b8efe 100644
--- a/freebsd/include/rpc/svc_auth.h
+++ b/freebsd/include/rpc/svc_auth.h
@@ -1,32 +1,31 @@
 /*	$NetBSD: svc_auth.h,v 1.8 2000/06/02 22:57:57 fvdl Exp $	*/
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)svc_auth.h 1.6 86/07/16 SMI
  *	@(#)svc_auth.h	2.1 88/07/29 4.0 RPCSRC
diff --git a/freebsd/include/rpc/svc_soc.h b/freebsd/include/rpc/svc_soc.h
index 6c528db..311c832 100644
--- a/freebsd/include/rpc/svc_soc.h
+++ b/freebsd/include/rpc/svc_soc.h
@@ -1,33 +1,32 @@
 /*	$NetBSD: svc_soc.h,v 1.1 2000/06/02 22:57:57 fvdl Exp $	*/
 /*	$FreeBSD$ */
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
diff --git a/freebsd/include/rpc/xdr.h b/freebsd/include/rpc/xdr.h
index ada5c5b..9456f70 100644
--- a/freebsd/include/rpc/xdr.h
+++ b/freebsd/include/rpc/xdr.h
@@ -1,32 +1,31 @@
 /*	$NetBSD: xdr.h,v 1.19 2000/07/17 05:00:45 matt Exp $	*/
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)xdr.h 1.19 87/04/22 SMI
  *	from: @(#)xdr.h	2.2 88/07/29 4.0 RPCSRC
diff --git a/freebsd/lib/libc/net/getaddrinfo.c b/freebsd/lib/libc/net/getaddrinfo.c
index 5c1965b..fbffd6b 100644
--- a/freebsd/lib/libc/net/getaddrinfo.c
+++ b/freebsd/lib/libc/net/getaddrinfo.c
@@ -64,12 +64,15 @@ __FBSDID("$FreeBSD$");
 #include <sys/socket.h>
 #include <net/if.h>
 #include <netinet/in.h>
+#include <net/if_types.h>
+#include <ifaddrs.h>
 #include <sys/queue.h>
 #ifdef INET6
 #include <net/if_var.h>
 #include <sys/sysctl.h>
 #include <sys/ioctl.h>
-#include <netinet6/in6_var.h>	/* XXX */
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
 #endif
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
@@ -246,6 +249,9 @@ static int get_portmatch(const struct addrinfo *, const char *);
 static int get_port(struct addrinfo *, const char *, int);
 static const struct afd *find_afd(int);
 static int addrconfig(struct addrinfo *);
+#ifdef INET6
+static int is_ifdisabled(char *);
+#endif
 static void set_source(struct ai_order *, struct policyhead *);
 static int comp_dst(const void *, const void *);
 #ifdef INET6
@@ -1003,7 +1009,8 @@ comp_dst(const void *arg1, const void *arg2)
 	 * We compare the match length in a same AF only.
 	 */
 	if (dst1->aio_ai->ai_addr->sa_family ==
-	    dst2->aio_ai->ai_addr->sa_family) {
+	    dst2->aio_ai->ai_addr->sa_family &&
+	    dst1->aio_ai->ai_addr->sa_family != AF_INET) {
 		if (dst1->aio_matchlen > dst2->aio_matchlen) {
 			return(-1);
 		}
@@ -1522,10 +1529,11 @@ find_afd(int af)
 }
 
 /*
- * post-2553: AI_ADDRCONFIG check.  if we use getipnodeby* as backend, backend
- * will take care of it.
- * the semantics of AI_ADDRCONFIG is not defined well.  we are not sure
- * if the code is right or not.
+ * RFC 3493: AI_ADDRCONFIG check.  Determines which address families are
+ * configured on the local system and correlates with pai->ai_family value.
+ * If an address family is not configured on the system, it will not be
+ * queried for.  For this purpose, loopback addresses are not considered
+ * configured addresses.
  *
  * XXX PF_UNSPEC -> PF_INET6 + PF_INET mapping needs to be in sync with
  * _dns_getaddrinfo.
@@ -1533,37 +1541,80 @@ find_afd(int af)
 static int
 addrconfig(struct addrinfo *pai)
 {
-	int s, af;
+	struct ifaddrs *ifaddrs, *ifa;
+	struct sockaddr_in *sin;
+#ifdef INET6
+	struct sockaddr_in6 *sin6;
+#endif
+	int seen_inet = 0, seen_inet6 = 0;
 
-	/*
-	 * TODO:
-	 * Note that implementation dependent test for address
-	 * configuration should be done everytime called
-	 * (or apropriate interval),
-	 * because addresses will be dynamically assigned or deleted.
-	 */
-	af = pai->ai_family;
-	if (af == AF_UNSPEC) {
-		if ((s = _socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
-			af = AF_INET;
-		else {
-			_close(s);
-			if ((s = _socket(AF_INET, SOCK_DGRAM, 0)) < 0)
-				af = AF_INET6;
-			else
-				_close(s);
+	if (getifaddrs(&ifaddrs) != 0)
+		return (0);
+
+	for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr == NULL || (ifa->ifa_flags & IFF_UP) == 0)
+			continue;
+		switch (ifa->ifa_addr->sa_family) {
+		case AF_INET:
+			if (seen_inet)
+				continue;
+			sin = (struct sockaddr_in *)(ifa->ifa_addr);
+			if (IN_LOOPBACK(htonl(sin->sin_addr.s_addr)))
+				continue;
+			seen_inet = 1;
+			break;
+#ifdef INET6
+		case AF_INET6:
+			if (seen_inet6)
+				continue;
+			sin6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
+			if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
+				continue;
+			if ((ifa->ifa_flags & IFT_LOOP) != 0 &&
+			    IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
+				continue;
+			if (is_ifdisabled(ifa->ifa_name))
+				continue;
+			seen_inet6 = 1;
+			break;
+#endif
 		}
 	}
-	if (af != AF_UNSPEC) {
-		if ((s = _socket(af, SOCK_DGRAM, 0)) < 0)
-			return 0;
-		_close(s);
+	freeifaddrs(ifaddrs);
+
+	switch(pai->ai_family) {
+	case AF_INET6:
+		return (seen_inet6);
+	case AF_INET:
+		return (seen_inet);
+	case AF_UNSPEC:
+		if (seen_inet == seen_inet6)
+			return (seen_inet);
+		pai->ai_family = seen_inet ? AF_INET : AF_INET6;
+		return (1);
 	}
-	pai->ai_family = af;
-	return 1;
+	return (1);
 }
 
 #ifdef INET6
+static int
+is_ifdisabled(char *name)
+{
+	struct in6_ndireq nd;
+	int fd;
+
+	if ((fd = _socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
+		return (-1);
+	memset(&nd, 0, sizeof(nd));
+	strlcpy(nd.ifname, name, sizeof(nd.ifname));
+	if (_ioctl(fd, SIOCGIFINFO_IN6, &nd) < 0) {
+		_close(fd);
+		return (-1);
+	}
+	_close(fd);
+	return ((nd.ndi.flags & ND6_IFF_IFDISABLED) != 0);
+}
+
 /* convert a string to a scope identifier. XXX: IPv6 specific */
 static int
 ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid)
diff --git a/freebsd/lib/libipsec/ipsec_dump_policy.c b/freebsd/lib/libipsec/ipsec_dump_policy.c
index 33d4bb1..a12727b 100644
--- a/freebsd/lib/libipsec/ipsec_dump_policy.c
+++ b/freebsd/lib/libipsec/ipsec_dump_policy.c
@@ -201,6 +201,7 @@ ipsec_dump_ipsecrequest(buf, len, xisr, bound)
 		break;
 	case IPPROTO_TCP:
 		proto = "tcp";
+		break;
 	default:
 		__ipsec_errcode = EIPSEC_INVAL_PROTO;
 		return NULL;
diff --git a/freebsd/sbin/ifconfig/af_inet.c b/freebsd/sbin/ifconfig/af_inet.c
index 0e6ace1..3e9ac8e 100644
--- a/freebsd/sbin/ifconfig/af_inet.c
+++ b/freebsd/sbin/ifconfig/af_inet.c
@@ -106,8 +106,7 @@ in_getaddr(const char *s, int which)
 	struct netent *np;
 
 	sin->sin_len = sizeof(*sin);
-	if (which != MASK)
-		sin->sin_family = AF_INET;
+	sin->sin_family = AF_INET;
 
 	if (which == ADDR) {
 		char *p = NULL;
@@ -126,6 +125,7 @@ in_getaddr(const char *s, int which)
 				*p = '/';
 				errx(1, "%s: bad value (width %s)", s, errstr);
 			}
+			min->sin_family = AF_INET;
 			min->sin_len = sizeof(*min);
 			min->sin_addr.s_addr = htonl(~((1LL << (32 - masklen)) - 1) & 
 				              0xffffffff);
diff --git a/freebsd/sbin/ifconfig/ifgroup.c b/freebsd/sbin/ifconfig/ifgroup.c
index daffb3b..c8dae3b 100644
--- a/freebsd/sbin/ifconfig/ifgroup.c
+++ b/freebsd/sbin/ifconfig/ifgroup.c
@@ -62,7 +62,7 @@ setifgroup(const char *group_name, int d, int s, const struct afswtch *rafp)
 
 	if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ)
 		errx(1, "setifgroup: group name too long");
-	if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1)
+	if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1 && errno != EEXIST)
 		err(1," SIOCAIFGROUP");
 }
 
@@ -80,7 +80,7 @@ unsetifgroup(const char *group_name, int d, int s, const struct afswtch *rafp)
 
 	if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ)
 		errx(1, "unsetifgroup: group name too long");
-	if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1)
+	if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1 && errno != ENOENT)
 		err(1, "SIOCDIFGROUP");
 }
 
diff --git a/freebsd/sbin/route/keywords b/freebsd/sbin/route/keywords
index adfba7c..676f781 100644
--- a/freebsd/sbin/route/keywords
+++ b/freebsd/sbin/route/keywords
@@ -1,6 +1,8 @@
 #	@(#)keywords	8.2 (Berkeley) 3/19/94
 # $FreeBSD$
 
+4
+6
 add
 atalk
 blackhole
diff --git a/freebsd/sbin/route/route.c b/freebsd/sbin/route/route.c
index 158445d..05b4f5a 100644
--- a/freebsd/sbin/route/route.c
+++ b/freebsd/sbin/route/route.c
@@ -177,7 +177,7 @@ usage(const char *cp)
 	if (cp != NULL)
 		warnx("bad keyword: %s", cp);
 	(void) fprintf(stderr,
-	    "usage: route [-dnqtv] command [[modifiers] args]\n");
+	    "usage: route [-46dnqtv] command [[modifiers] args]\n");
 	exit(EX_USAGE);
 	/* NOTREACHED */
 }
@@ -263,8 +263,24 @@ main(int argc, char **argv)
 	if (argc < 2)
 		usage(NULL);
 
-	while ((ch = getopt(argc, argv, "nqdtv")) != -1)
+	while ((ch = getopt(argc, argv, "46nqdtv")) != -1)
 		switch(ch) {
+		case '4':
+#ifdef INET
+			c->af = AF_INET;
+			c->aflen = sizeof(struct sockaddr_in);
+#else
+			errx(1, "IPv4 support is not compiled in");
+#endif
+			break;
+		case '6':
+#ifdef INET6
+			c->af = AF_INET6;
+			c->aflen = sizeof(struct sockaddr_in6);
+#else
+			errx(1, "IPv6 support is not compiled in");
+#endif
+			break;
 		case 'n':
 			c->nflag = 1;
 			break;
@@ -485,10 +501,12 @@ flushroutes(struct rt_ctx *c, int argc, char *argv[])
 		if (**argv != '-')
 			usage(*argv);
 		switch (keyword(*argv + 1)) {
+		case K_4:
 		case K_INET:
 			c->af = AF_INET;
 			break;
 #ifdef INET6
+		case K_6:
 		case K_INET6:
 			c->af = AF_INET6;
 			break;
@@ -903,11 +921,13 @@ newroute(struct rt_ctx *c, int argc, char **argv)
 				c->af = AF_LINK;
 				c->aflen = sizeof(struct sockaddr_dl);
 				break;
+			case K_4:
 			case K_INET:
 				c->af = AF_INET;
 				c->aflen = sizeof(struct sockaddr_in);
 				break;
 #ifdef INET6
+			case K_6:
 			case K_INET6:
 				c->af = AF_INET6;
 				c->aflen = sizeof(struct sockaddr_in6);
diff --git a/freebsd/sys/cam/ata/ata_all.h b/freebsd/sys/cam/ata/ata_all.h
index 25732b6..91e941c 100644
--- a/freebsd/sys/cam/ata/ata_all.h
+++ b/freebsd/sys/cam/ata/ata_all.h
@@ -109,6 +109,7 @@ int	ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb);
 int	ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb);
 
 void	ata_print_ident(struct ata_params *ident_data);
+void	ata_print_ident_short(struct ata_params *ident_data);
 
 uint32_t	ata_logical_sector_size(struct ata_params *ident_data);
 uint64_t	ata_physical_sector_size(struct ata_params *ident_data);
@@ -143,6 +144,7 @@ int	ata_identify_match(caddr_t identbuffer, caddr_t table_entry);
 int	ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry);
 
 void	semb_print_ident(struct sep_identify_data *ident_data);
+void	semb_print_ident_short(struct sep_identify_data *ident_data);
 
 void semb_receive_diagnostic_results(struct ccb_ataio *ataio,
 	u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
diff --git a/freebsd/sys/cam/cam.h b/freebsd/sys/cam/cam.h
index af57f1a..499fffa 100644
--- a/freebsd/sys/cam/cam.h
+++ b/freebsd/sys/cam/cam.h
@@ -84,15 +84,15 @@ typedef struct {
 #define CAM_PRIORITY_BUS	((CAM_RL_BUS << 8) + 0x80)
 #define CAM_PRIORITY_XPT	((CAM_RL_XPT << 8) + 0x80)
 #define CAM_PRIORITY_DEV	((CAM_RL_DEV << 8) + 0x80)
+#define CAM_PRIORITY_OOB	(CAM_RL_DEV << 8)
 #define CAM_PRIORITY_NORMAL	((CAM_RL_NORMAL << 8) + 0x80)
 #define CAM_PRIORITY_NONE	(u_int32_t)-1
-#define CAM_PRIORITY_TO_RL(x)	((x) >> 8)
-#define CAM_RL_TO_PRIORITY(x)	((x) << 8)
 	u_int32_t generation;
 	int       index;
 #define CAM_UNQUEUED_INDEX	-1
 #define CAM_ACTIVE_INDEX	-2	
 #define CAM_DONEQ_INDEX		-3	
+#define CAM_EXTRAQ_INDEX	INT_MAX
 } cam_pinfo;
 
 /*
diff --git a/freebsd/sys/cam/cam_ccb.h b/freebsd/sys/cam/cam_ccb.h
index 893c646..4222de9 100644
--- a/freebsd/sys/cam/cam_ccb.h
+++ b/freebsd/sys/cam/cam_ccb.h
@@ -154,8 +154,6 @@ typedef enum {
 				/* Path statistics (error counts, etc.) */
 	XPT_GDEV_STATS		= 0x0c,
 				/* Device statistics (error counts, etc.) */
-	XPT_FREEZE_QUEUE	= 0x0d,
-				/* Freeze device queue */
 	XPT_DEV_ADVINFO		= 0x0e,
 				/* Get/Set Device advanced information */
 /* SCSI Control Functions: 0x10->0x1F */
@@ -592,6 +590,7 @@ typedef enum {
 	PIM_NO_6_BYTE	= 0x08,	/* Do not send 6-byte commands */
 	PIM_SEQSCAN	= 0x04,	/* Do bus scans sequentially, not in parallel */
 	PIM_UNMAPPED	= 0x02,
+	PIM_NOSCAN	= 0x01	/* SIM does its own scanning */
 } pi_miscflag;
 
 /* Path Inquiry CCB */
@@ -774,7 +773,6 @@ struct ccb_relsim {
 #define RELSIM_RELEASE_AFTER_TIMEOUT	0x02
 #define RELSIM_RELEASE_AFTER_CMDCMPLT	0x04
 #define RELSIM_RELEASE_AFTER_QEMPTY	0x08
-#define RELSIM_RELEASE_RUNLEVEL		0x10
 	u_int32_t      openings;
 	u_int32_t      release_timeout;	/* Abstract argument. */
 	u_int32_t      qfrozen_cnt;
@@ -1328,6 +1326,19 @@ cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries,
 	smpio->smp_response_len = smp_response_len;
 }
 
+static __inline void
+cam_set_ccbstatus(union ccb *ccb, cam_status status)
+{
+	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
+	ccb->ccb_h.status |= status;
+}
+
+static __inline cam_status
+cam_ccb_status(union ccb *ccb)
+{
+	return ((cam_status)(ccb->ccb_h.status & CAM_STATUS_MASK));
+}
+
 void cam_calc_geometry(struct ccb_calc_geometry *ccg, int extended);
 
 __END_DECLS
diff --git a/freebsd/sys/cam/cam_debug.h b/freebsd/sys/cam/cam_debug.h
index 37acd7d..7b619a2 100644
--- a/freebsd/sys/cam/cam_debug.h
+++ b/freebsd/sys/cam/cam_debug.h
@@ -61,13 +61,13 @@ typedef enum {
 #endif
 
 #ifndef CAM_DEBUG_BUS
-#define CAM_DEBUG_BUS		(-1)
+#define CAM_DEBUG_BUS		CAM_BUS_WILDCARD
 #endif
 #ifndef CAM_DEBUG_TARGET
-#define CAM_DEBUG_TARGET	(-1)
+#define CAM_DEBUG_TARGET	CAM_TARGET_WILDCARD
 #endif
 #ifndef CAM_DEBUG_LUN
-#define CAM_DEBUG_LUN		(-1)
+#define CAM_DEBUG_LUN		CAM_LUN_WILDCARD
 #endif
 
 #ifndef CAM_DEBUG_DELAY
@@ -99,6 +99,17 @@ extern u_int32_t cam_debug_delay;
 			DELAY(cam_debug_delay);		\
 	}
 
+#define	CAM_DEBUG_DEV(dev, flag, printfargs)		\
+	if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)	\
+	 && (cam_dpath != NULL)				\
+	 && (xpt_path_comp_dev(cam_dpath, dev) >= 0)	\
+	 && (xpt_path_comp_dev(cam_dpath, dev) < 2)) {	\
+		xpt_print_device(dev);			\
+		printf printfargs;			\
+		if (cam_debug_delay != 0)		\
+			DELAY(cam_debug_delay);		\
+	}
+
 #define	CAM_DEBUG_PRINT(flag, printfargs)		\
 	if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)) {	\
 		printf("cam_debug: ");			\
diff --git a/freebsd/sys/cam/cam_periph.h b/freebsd/sys/cam/cam_periph.h
index 102dc3c..a58ec94 100644
--- a/freebsd/sys/cam/cam_periph.h
+++ b/freebsd/sys/cam/cam_periph.h
@@ -121,6 +121,7 @@ struct cam_periph {
 #define CAM_PERIPH_NEW_DEV_FOUND	0x10
 #define CAM_PERIPH_RECOVERY_INPROG	0x20
 #define CAM_PERIPH_FREE			0x80
+#define CAM_PERIPH_ANNOUNCED		0x100
 	u_int32_t		 immediate_priority;
 	u_int32_t		 refcount;
 	SLIST_HEAD(, ccb_hdr)	 ccb_list;	/* For "immediate" requests */
@@ -171,8 +172,6 @@ int		cam_periph_ioctl(struct cam_periph *periph, u_long cmd,
 						      cam_flags camflags,
 						      u_int32_t sense_flags));
 void		cam_freeze_devq(struct cam_path *path);
-void		cam_freeze_devq_arg(struct cam_path *path, u_int32_t flags,
-		    uint32_t arg);
 u_int32_t	cam_release_devq(struct cam_path *path, u_int32_t relsim_flags,
 				 u_int32_t opening_reduction, u_int32_t arg,
 				 int getcount_only);
diff --git a/freebsd/sys/cam/cam_xpt.h b/freebsd/sys/cam/cam_xpt.h
index 492fa3a..97933b9 100644
--- a/freebsd/sys/cam/cam_xpt.h
+++ b/freebsd/sys/cam/cam_xpt.h
@@ -35,6 +35,7 @@
 /* Forward Declarations */
 union ccb;
 struct cam_periph;
+struct cam_ed;
 struct cam_sim;
 
 /*
@@ -89,7 +90,10 @@ void			xpt_path_counts(struct cam_path *path, uint32_t *bus_ref,
 					uint32_t *device_ref);
 int			xpt_path_comp(struct cam_path *path1,
 				      struct cam_path *path2);
+int			xpt_path_comp_dev(struct cam_path *path,
+					  struct cam_ed *dev);
 void			xpt_print_path(struct cam_path *path);
+void			xpt_print_device(struct cam_ed *device);
 void			xpt_print(struct cam_path *path, const char *fmt, ...);
 int			xpt_path_string(struct cam_path *path, char *str,
 					size_t str_len);
diff --git a/freebsd/sys/cam/cam_xpt_sim.h b/freebsd/sys/cam/cam_xpt_sim.h
index d32eea7..62ded09 100644
--- a/freebsd/sys/cam/cam_xpt_sim.h
+++ b/freebsd/sys/cam/cam_xpt_sim.h
@@ -47,12 +47,8 @@ u_int32_t	xpt_freeze_devq(struct cam_path *path, u_int count);
 #else /* __rtems__ */
 #define xpt_freeze_devq(path, count) do { } while (0)
 #endif /* __rtems__ */
-u_int32_t	xpt_freeze_devq_rl(struct cam_path *path, cam_rl rl,
-		    u_int count);
 void		xpt_release_devq(struct cam_path *path,
 		    u_int count, int run_queue);
-void		xpt_release_devq_rl(struct cam_path *path, cam_rl rl,
-		    u_int count, int run_queue);
 int		xpt_sim_opened(struct cam_sim *sim);
 void		xpt_done(union ccb *done_ccb);
 void		xpt_batch_start(struct cam_sim *sim);
diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c
index 5b50401..4cad972 100644
--- a/freebsd/sys/cam/scsi/scsi_all.c
+++ b/freebsd/sys/cam/scsi/scsi_all.c
@@ -672,6 +672,10 @@ scsi_op_desc(u_int16_t opcode, struct scsi_inquiry_data *inq_data)
 	if (pd_type == T_RBC)
 		pd_type = T_DIRECT;
 
+	/* Map NODEVICE to Direct Access Device to handle REPORT LUNS, etc. */
+	if (pd_type == T_NODEVICE)
+		pd_type = T_DIRECT;
+
 	opmask = 1 << pd_type;
 
 	for (j = 0; j < num_tables; j++) {
@@ -1121,7 +1125,7 @@ static struct asc_table_entry asc_table[] = {
 	{ SST(0x04, 0x10, SS_RDEF,	/* XXX TBD */
 	    "Logical unit not ready, auxiliary memory not accessible") },
 	/* DT  WRO AEB VF */
-	{ SST(0x04, 0x11, SS_RDEF,	/* XXX TBD */
+	{ SST(0x04, 0x11, SS_TUR | SSQ_MANY | SSQ_DECREMENT_COUNT | EBUSY,
 	    "Logical unit not ready, notify (enable spinup) required") },
 	/*        M    V  */
 	{ SST(0x04, 0x12, SS_RDEF,	/* XXX TBD */
@@ -1652,7 +1656,7 @@ static struct asc_table_entry asc_table[] = {
 	{ SST(0x24, 0x08, SS_RDEF,	/* XXX TBD */
 	    "Invalid XCDB") },
 	/* DTLPWROMAEBKVF */
-	{ SST(0x25, 0x00, SS_FATAL | ENXIO,
+	{ SST(0x25, 0x00, SS_FATAL | ENXIO | SSQ_LOST,
 	    "Logical unit not supported") },
 	/* DTLPWROMAEBKVF */
 	{ SST(0x26, 0x00, SS_FATAL | EINVAL,
@@ -2170,7 +2174,7 @@ static struct asc_table_entry asc_table[] = {
 	{ SST(0x3F, 0x0D, SS_RDEF,
 	    "Volume set reassigned") },
 	/* DTLPWROMAE     */
-	{ SST(0x3F, 0x0E, SS_RDEF,	/* XXX TBD */
+	{ SST(0x3F, 0x0E, SS_RDEF | SSQ_RESCAN ,
 	    "Reported LUNs data has changed") },
 	/* DTLPWROMAEBKVF */
 	{ SST(0x3F, 0x0F, SS_RDEF,	/* XXX TBD */
@@ -3270,6 +3274,7 @@ scsi_error_action(struct ccb_scsiio *csio, struct scsi_inquiry_data *inq_data,
 				action |= SS_RETRY|SSQ_DECREMENT_COUNT|
 					  SSQ_PRINT_SENSE;
 			}
+			action |= SSQ_UA;
 		}
 	}
 	if ((action & SS_MASK) >= SS_START &&
@@ -5256,6 +5261,21 @@ scsi_print_inquiry(struct scsi_inquiry_data *inq_data)
 	       dtype, rstr, qtype);
 }
 
+void
+scsi_print_inquiry_short(struct scsi_inquiry_data *inq_data)
+{
+	char vendor[16], product[48], revision[16];
+
+	cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor),
+		   sizeof(vendor));
+	cam_strvis(product, inq_data->product, sizeof(inq_data->product),
+		   sizeof(product));
+	cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision),
+		   sizeof(revision));
+
+	printf("<%s %s %s>", vendor, product, revision);
+}
+
 #ifndef __rtems__
 /*
  * Table of syncrates that don't follow the "divisible by 4"
@@ -6510,7 +6530,11 @@ scsi_devid_match(uint8_t *lhs, size_t lhs_len, uint8_t *rhs, size_t rhs_len)
 		while (rhs_id <= rhs_last
 		    && (rhs_id->identifier + rhs_id->length) <= rhs_end) {
 
-			if (rhs_id->length == lhs_id->length
+			if ((rhs_id->id_type &
+			     (SVPD_ID_ASSOC_MASK | SVPD_ID_TYPE_MASK)) ==
+			    (lhs_id->id_type &
+			     (SVPD_ID_ASSOC_MASK | SVPD_ID_TYPE_MASK))
+			 && rhs_id->length == lhs_id->length
 			 && memcmp(rhs_id->identifier, lhs_id->identifier,
 				   rhs_id->length) == 0)
 				return (0);
diff --git a/freebsd/sys/cam/scsi/scsi_all.h b/freebsd/sys/cam/scsi/scsi_all.h
index 4fe0b1d..cf84d39 100644
--- a/freebsd/sys/cam/scsi/scsi_all.h
+++ b/freebsd/sys/cam/scsi/scsi_all.h
@@ -88,6 +88,9 @@ typedef enum {
 					    * and text.
 					    */
 	SSQ_PRINT_SENSE		= 0x0800,
+	SSQ_UA			= 0x1000,  /* Broadcast UA. */
+	SSQ_RESCAN		= 0x2000,  /* Rescan target for LUNs. */
+	SSQ_LOST		= 0x4000,  /* Destroy the LUNs. */
 	SSQ_MASK		= 0xff00
 } scsi_sense_action_qualifier;
 
@@ -2309,6 +2312,7 @@ char *		scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string,
 				size_t len);
 
 void		scsi_print_inquiry(struct scsi_inquiry_data *inq_data);
+void		scsi_print_inquiry_short(struct scsi_inquiry_data *inq_data);
 
 u_int		scsi_calc_syncsrate(u_int period_factor);
 u_int		scsi_calc_syncparam(u_int period);
diff --git a/freebsd/sys/cam/scsi/scsi_da.h b/freebsd/sys/cam/scsi/scsi_da.h
index 5799238..4fbd725 100644
--- a/freebsd/sys/cam/scsi/scsi_da.h
+++ b/freebsd/sys/cam/scsi/scsi_da.h
@@ -116,6 +116,31 @@ struct scsi_read_defect_data_10
 	u_int8_t control;
 };
 
+struct scsi_sanitize
+{
+	u_int8_t opcode;
+	u_int8_t byte2;
+#define SSZ_SERVICE_ACTION_OVERWRITE         0x01
+#define SSZ_SERVICE_ACTION_BLOCK_ERASE       0x02
+#define SSZ_SERVICE_ACTION_CRYPTO_ERASE      0x03
+#define SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE 0x1F
+#define SSZ_UNRESTRICTED_EXIT                0x20
+#define SSZ_IMMED                            0x80
+	u_int8_t reserved[5];
+	u_int8_t length[2];
+	u_int8_t control;
+};
+
+struct scsi_sanitize_parameter_list
+{
+	u_int8_t byte1;
+#define SSZPL_INVERT 0x80
+	u_int8_t reserved;
+	u_int8_t length[2];
+	/* Variable length initialization pattern. */
+#define SSZPL_MAX_PATTERN_LENGTH 65535
+};
+
 struct scsi_read_defect_data_12
 {
 	u_int8_t opcode;
@@ -156,6 +181,7 @@ struct scsi_read_defect_data_12
 #define	WRITE_AND_VERIFY	0x2e
 #define	VERIFY			0x2f
 #define READ_DEFECT_DATA_10	0x37
+#define SANITIZE		0x48
 #define READ_DEFECT_DATA_12	0xb7
 
 struct format_defect_list_header
@@ -508,6 +534,12 @@ void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
 		      u_int8_t *data_ptr, u_int32_t dxfer_len,
 		      u_int8_t sense_len, u_int32_t timeout);
 
+void scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries,
+		   void (*cbfcnp)(struct cam_periph *, union ccb *),
+		   u_int8_t tag_action, u_int8_t byte2, u_int16_t control,
+		   u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
+		   u_int32_t timeout);
+
 #endif /* !_KERNEL */
 __END_DECLS
 
diff --git a/freebsd/sys/contrib/pf/net/pf_lb.c b/freebsd/sys/contrib/pf/net/pf_lb.c
index 0c2046c..16faac0 100644
--- a/freebsd/sys/contrib/pf/net/pf_lb.c
+++ b/freebsd/sys/contrib/pf/net/pf_lb.c
@@ -167,8 +167,8 @@ struct pf_rule		*pf_match_translation(struct pf_pdesc *, struct mbuf *,
 			    struct pf_addr *, u_int16_t, struct pf_addr *,
 			    u_int16_t, int);
 int			 pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
-			    struct pf_addr *, struct pf_addr *, u_int16_t,
-			    struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
+			    struct pf_addr *, uint16_t, struct pf_addr *, uint16_t,
+			    struct pf_addr *, uint16_t*, uint16_t, uint16_t,
 			    struct pf_src_node **);
 
 #define mix(a,b,c) \
@@ -320,13 +320,13 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
 
 int
 pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
-    struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
-    struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
-    struct pf_src_node **sn)
+    struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr,
+    uint16_t dport, struct pf_addr *naddr, uint16_t *nport, uint16_t low,
+    uint16_t high, struct pf_src_node **sn)
 {
 	struct pf_state_key_cmp	key;
 	struct pf_addr		init_addr;
-	u_int16_t		cut;
+	uint16_t		cut;
 
 	bzero(&init_addr, sizeof(init_addr));
 	if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
@@ -337,34 +337,38 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
 		high = 65535;
 	}
 
+	bzero(&key,sizeof(key));
+	key.af = af;
+	key.proto = proto;
+	key.port[0] = dport;
+	PF_ACPY(&key.addr[0], daddr, key.af);
+
 	do {
-		key.af = af;
-		key.proto = proto;
-		PF_ACPY(&key.addr[1], daddr, key.af);
-		PF_ACPY(&key.addr[0], naddr, key.af);
-		key.port[1] = dport;
+		PF_ACPY(&key.addr[1], naddr, key.af);
 
 		/*
 		 * port search; start random, step;
 		 * similar 2 portloop in in_pcbbind
 		 */
 		if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
-		    proto == IPPROTO_ICMP)) {
-			key.port[0] = dport;
-			if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
-				return (0);
-		} else if (low == 0 && high == 0) {
-			key.port[0] = *nport;
-			if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
+		    proto == IPPROTO_ICMP) || (low == 0 && high == 0)) {
+			/*
+			* XXX bug: icmp state don't use the id on both sides.
+			* (traceroute -l through nat)
+			*/
+			key.port[1] = sport;
+			if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
+				*nport = sport;
 				return (0);
+			}
 		} else if (low == high) {
-			key.port[0] = htons(low);
+			key.port[1] = htons(low);
 			if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
 				*nport = htons(low);
 				return (0);
 			}
 		} else {
-			u_int16_t tmp;
+			uint16_t tmp;
 
 			if (low > high) {
 				tmp = low;
@@ -379,7 +383,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
 #endif
 			/* low <= cut <= high */
 			for (tmp = cut; tmp <= high; ++(tmp)) {
-				key.port[0] = htons(tmp);
+				key.port[1] = htons(tmp);
 				if (pf_find_state_all(&key, PF_IN, NULL) ==
 #ifdef __FreeBSD__
 				    NULL) {
@@ -391,7 +395,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
 				}
 			}
 			for (tmp = cut - 1; tmp >= low; --(tmp)) {
-				key.port[0] = htons(tmp);
+				key.port[1] = htons(tmp);
 				if (pf_find_state_all(&key, PF_IN, NULL) ==
 #ifdef __FreeBSD__
 				    NULL) {
@@ -657,8 +661,8 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
 		case PF_NORDR:
 			return (NULL);
 		case PF_NAT:
-			if (pf_get_sport(pd->af, pd->proto, r, saddr,
-			    daddr, dport, naddr, nport, r->rpool.proxy_port[0],
+			if (pf_get_sport(pd->af, pd->proto, r, saddr, sport, daddr,
+			    dport, naddr, nport, r->rpool.proxy_port[0],
 			    r->rpool.proxy_port[1], sn)) {
 				DPFPRINTF(PF_DEBUG_MISC,
 				    ("pf: NAT proxy port allocation "
@@ -786,6 +790,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
 			pool_put(&pf_state_key_pl, *skp);
 #endif
 			*skw = *sks = *nkp = *skp = NULL;
+			*sn = NULL;
 			return (NULL);
 		}
 	}
diff --git a/freebsd/sys/dev/bce/if_bce.c b/freebsd/sys/dev/bce/if_bce.c
index dfae5dc..e186590 100644
--- a/freebsd/sys/dev/bce/if_bce.c
+++ b/freebsd/sys/dev/bce/if_bce.c
@@ -1,8 +1,7 @@
 #include <machine/rtems-bsd-kernel-space.h>
 
 /*-
- * Copyright (c) 2006-2010 Broadcom Corporation
- *	David Christensen <davidch at broadcom.com>.  All rights reserved.
+ * Copyright (c) 2006-2014 QLogic Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -13,9 +12,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Broadcom Corporation nor the name of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written consent.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -108,13 +104,13 @@ static const struct bce_type bce_devs[] = {
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x1709,
 		"HP NC371i Multifunction Gigabit Server Adapter" },
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
-		"Broadcom NetXtreme II BCM5706 1000Base-T" },
+		"QLogic NetXtreme II BCM5706 1000Base-T" },
 
 	/* BCM5706S controllers and OEM boards. */
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
 		"HP NC370F Multifunction Gigabit Server Adapter" },
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
-		"Broadcom NetXtreme II BCM5706 1000Base-SX" },
+		"QLogic NetXtreme II BCM5706 1000Base-SX" },
 
 	/* BCM5708C controllers and OEM boards. */
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7037,
@@ -124,7 +120,7 @@ static const struct bce_type bce_devs[] = {
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7045,
 		"HP NC374m PCIe Multifunction Adapter" },
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
-		"Broadcom NetXtreme II BCM5708 1000Base-T" },
+		"QLogic NetXtreme II BCM5708 1000Base-T" },
 
 	/* BCM5708S controllers and OEM boards. */
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x1706,
@@ -134,7 +130,7 @@ static const struct bce_type bce_devs[] = {
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703d,
 		"HP NC373F PCIe Multifunc Giga Server Adapter" },
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
-		"Broadcom NetXtreme II BCM5708 1000Base-SX" },
+		"QLogic NetXtreme II BCM5708 1000Base-SX" },
 
 	/* BCM5709C controllers and OEM boards. */
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7055,
@@ -142,7 +138,7 @@ static const struct bce_type bce_devs[] = {
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7059,
 		"HP NC382T PCIe DP Multifunction Gigabit Server Adapter" },
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  PCI_ANY_ID,  PCI_ANY_ID,
-		"Broadcom NetXtreme II BCM5709 1000Base-T" },
+		"QLogic NetXtreme II BCM5709 1000Base-T" },
 
 	/* BCM5709S controllers and OEM boards. */
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x171d,
@@ -150,11 +146,11 @@ static const struct bce_type bce_devs[] = {
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x7056,
 		"HP NC382i DP Multifunction Gigabit Server Adapter" },
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  PCI_ANY_ID,  PCI_ANY_ID,
-		"Broadcom NetXtreme II BCM5709 1000Base-SX" },
+		"QLogic NetXtreme II BCM5709 1000Base-SX" },
 
 	/* BCM5716 controllers and OEM boards. */
 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5716,  PCI_ANY_ID,  PCI_ANY_ID,
-		"Broadcom NetXtreme II BCM5716 1000Base-T" },
+		"QLogic NetXtreme II BCM5716 1000Base-T" },
 
 	{ 0, 0, 0, 0, NULL }
 };
@@ -5066,9 +5062,11 @@ bce_reset(struct bce_softc *sc, u32 reset_code)
 
 bce_reset_exit:
 	/* Restore EMAC Mode bits needed to keep ASF/IPMI running. */
-	val = REG_RD(sc, BCE_EMAC_MODE);
-	val = (val & ~emac_mode_mask) | emac_mode_save;
-	REG_WR(sc, BCE_EMAC_MODE, val);
+	if (reset_code == BCE_DRV_MSG_CODE_RESET) {
+		val = REG_RD(sc, BCE_EMAC_MODE);
+		val = (val & ~emac_mode_mask) | emac_mode_save;
+		REG_WR(sc, BCE_EMAC_MODE, val);
+	}
 
 	DBEXIT(BCE_VERBOSE_RESET);
 	return (rc);
diff --git a/freebsd/sys/dev/bce/if_bcefw.h b/freebsd/sys/dev/bce/if_bcefw.h
index 8d97b31..fa0d528 100644
--- a/freebsd/sys/dev/bce/if_bcefw.h
+++ b/freebsd/sys/dev/bce/if_bcefw.h
@@ -1,6 +1,5 @@
 /*-
- * Copyright (c) 2006-2011 Broadcom Corporation
- *	David Christensen <davidch at broadcom.com>.  All rights reserved.
+ * Copyright (c) 2006-2014 QLogic Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -10,9 +9,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Broadcom Corporation nor the name of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written consent.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -31,7 +27,7 @@
 
 /*
  * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004-2011 Broadcom Corporation.
+ * source code, Copyright (c) 2004-2014 QLogic Corporation.
  *
  * Permission is hereby granted for the distribution of this firmware data
  * in hexadecimal or equivalent format, provided this copyright notice also
diff --git a/freebsd/sys/dev/bce/if_bcereg.h b/freebsd/sys/dev/bce/if_bcereg.h
index 450180b..0090356 100644
--- a/freebsd/sys/dev/bce/if_bcereg.h
+++ b/freebsd/sys/dev/bce/if_bcereg.h
@@ -1,6 +1,5 @@
 /*-
- * Copyright (c) 2006-2010 Broadcom Corporation
- *	David Christensen <davidch at broadcom.com>.  All rights reserved.
+ * Copyright (c) 2006-2014 QLogic Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -10,9 +9,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Broadcom Corporation nor the name of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written consent.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -6355,8 +6351,8 @@ struct fw_info {
 
 #define BCE_TX_TIMEOUT		5
 
-#define BCE_MAX_SEGMENTS	32
-#define BCE_TSO_MAX_SIZE	65536
+#define BCE_MAX_SEGMENTS	35
+#define BCE_TSO_MAX_SIZE	(65535 + sizeof(struct ether_vlan_header))
 #define BCE_TSO_MAX_SEG_SIZE	4096
 
 #define BCE_DMA_ALIGN		8
diff --git a/freebsd/sys/dev/bge/if_bge.c b/freebsd/sys/dev/bge/if_bge.c
index f9010aa..c0f78a7 100644
--- a/freebsd/sys/dev/bge/if_bge.c
+++ b/freebsd/sys/dev/bge/if_bge.c
@@ -178,6 +178,8 @@ static const struct bge_type {
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5721 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5722 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5723 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5725 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5727 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5750 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5750M },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5751 },
@@ -197,6 +199,7 @@ static const struct bge_type {
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5761E },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5761S },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5761SE },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5762 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5764 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5780 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM5780S },
@@ -219,11 +222,16 @@ static const struct bge_type {
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57760 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57761 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57762 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57764 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57765 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57766 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57767 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57780 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57781 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57782 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57785 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57786 },
+	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57787 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57788 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57790 },
 	{ BCOM_VENDORID,	BCOM_DEVICEID_BCM57791 },
@@ -312,6 +320,7 @@ static const struct bge_revision {
 	{ BGE_CHIPID_BCM5722_A0,	"BCM5722 A0" },
 	{ BGE_CHIPID_BCM5761_A0,	"BCM5761 A0" },
 	{ BGE_CHIPID_BCM5761_A1,	"BCM5761 A1" },
+	{ BGE_CHIPID_BCM5762_A0,	"BCM5762 A0" },
 	{ BGE_CHIPID_BCM5784_A0,	"BCM5784 A0" },
 	{ BGE_CHIPID_BCM5784_A1,	"BCM5784 A1" },
 	/* 5754 and 5787 share the same ASIC ID */
@@ -356,6 +365,7 @@ static const struct bge_revision bge_majorrevs[] = {
 	{ BGE_ASICREV_BCM5717,		"unknown BCM5717" },
 	{ BGE_ASICREV_BCM5719,		"unknown BCM5719" },
 	{ BGE_ASICREV_BCM5720,		"unknown BCM5720" },
+	{ BGE_ASICREV_BCM5762,		"unknown BCM5762" },
 
 	{ 0, NULL }
 };
@@ -1798,6 +1808,20 @@ bge_chipinit(struct bge_softc *sc)
 		pci_write_config(sc->bge_dev, BGE_PCI_MSI_DATA + 2, val, 2);
 	}
 
+	if (sc->bge_asicrev == BGE_ASICREV_BCM57765 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM57766) {
+		/*
+		 * For the 57766 and non Ax versions of 57765, bootcode
+		 * needs to setup the PCIE Fast Training Sequence (FTS)
+		 * value to prevent transmit hangs.
+		 */
+		if (sc->bge_chiprev != BGE_CHIPREV_57765_AX) {
+			CSR_WRITE_4(sc, BGE_CPMU_PADRNG_CTL,
+			    CSR_READ_4(sc, BGE_CPMU_PADRNG_CTL) |
+			    BGE_CPMU_PADRNG_CTL_RDIV2);
+		}
+	}
+
 	/*
 	 * Set up the PCI DMA control register.
 	 */
@@ -1873,8 +1897,9 @@ bge_chipinit(struct bge_softc *sc)
 		 * a status tag update and leave interrupts permanently
 		 * disabled.
 		 */
-		if (sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
-		    sc->bge_asicrev != BGE_ASICREV_BCM57765)
+		if (!BGE_IS_57765_PLUS(sc) &&
+		    sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
+		    sc->bge_asicrev != BGE_ASICREV_BCM5762)
 			dma_rw_ctl |= BGE_PCIDMARWCTL_TAGGED_STATUS_WA;
 	}
 	pci_write_config(sc->bge_dev, BGE_PCI_DMA_RW_CTL, dma_rw_ctl, 4);
@@ -1883,7 +1908,8 @@ bge_chipinit(struct bge_softc *sc)
 	 * Set up general mode register.
 	 */
 	mode_ctl = bge_dma_swap_options(sc);
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5720 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5762) {
 		/* Retain Host-2-BMC settings written by APE firmware. */
 		mode_ctl |= CSR_READ_4(sc, BGE_MODE_CTL) &
 		    (BGE_MODECTL_BYTESWAP_B2HRX_DATA |
@@ -1941,7 +1967,7 @@ bge_blockinit(struct bge_softc *sc)
 	struct bge_rcb *rcb;
 	bus_size_t vrcb;
 	bge_hostaddr taddr;
-	uint32_t dmactl, val;
+	uint32_t dmactl, rdmareg, val;
 	int i, limit;
 
 	/*
@@ -2212,6 +2238,11 @@ bge_blockinit(struct bge_softc *sc)
 	if (!BGE_IS_5705_PLUS(sc))
 		/* 5700 to 5704 had 16 send rings. */
 		limit = BGE_TX_RINGS_EXTSSRAM_MAX;
+	else if (BGE_IS_57765_PLUS(sc) ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5762)
+		limit = 2;
+	else if (BGE_IS_5717_PLUS(sc))
+		limit = 4;
 	else
 		limit = 1;
 	vrcb = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
@@ -2250,6 +2281,7 @@ bge_blockinit(struct bge_softc *sc)
 	} else if (!BGE_IS_5705_PLUS(sc))
 		limit = BGE_RX_RINGS_MAX;
 	else if (sc->bge_asicrev == BGE_ASICREV_BCM5755 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5762 ||
 	    BGE_IS_57765_PLUS(sc))
 		limit = 4;
 	else
@@ -2289,7 +2321,8 @@ bge_blockinit(struct bge_softc *sc)
 
 	/* Set inter-packet gap */
 	val = 0x2620;
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5720)
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5720 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5762)
 		val |= CSR_READ_4(sc, BGE_TX_LENGTHS) &
 		    (BGE_TXLEN_JMB_FRM_LEN_MSK | BGE_TXLEN_CNT_DN_VAL_MSK);
 	CSR_WRITE_4(sc, BGE_TX_LENGTHS, val);
@@ -2453,7 +2486,8 @@ bge_blockinit(struct bge_softc *sc)
 			val |= BGE_RDMAMODE_TSO6_ENABLE;
 	}
 
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5720 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5762) {
 		val |= CSR_READ_4(sc, BGE_RDMA_MODE) &
 			BGE_RDMAMODE_H2BNC_VLAN_DET;
 		/*
@@ -2467,14 +2501,18 @@ bge_blockinit(struct bge_softc *sc)
 	    sc->bge_asicrev == BGE_ASICREV_BCM5784 ||
 	    sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
 	    sc->bge_asicrev == BGE_ASICREV_BCM57780 ||
-	    BGE_IS_5717_PLUS(sc)) {
-		dmactl = CSR_READ_4(sc, BGE_RDMA_RSRVCTRL);
+	    BGE_IS_5717_PLUS(sc) || BGE_IS_57765_PLUS(sc)) {
+		if (sc->bge_asicrev == BGE_ASICREV_BCM5762)
+			rdmareg = BGE_RDMA_RSRVCTRL_REG2;
+		else
+			rdmareg = BGE_RDMA_RSRVCTRL;
+		dmactl = CSR_READ_4(sc, rdmareg);
 		/*
 		 * Adjust tx margin to prevent TX data corruption and
 		 * fix internal FIFO overflow.
 		 */
-		if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
-		    sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
+		if (sc->bge_chipid == BGE_CHIPID_BCM5719_A0 ||
+		    sc->bge_asicrev == BGE_ASICREV_BCM5762) {
 			dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK |
 			    BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK |
 			    BGE_RDMA_RSRVCTRL_TXMRGN_MASK);
@@ -2487,7 +2525,7 @@ bge_blockinit(struct bge_softc *sc)
 		 * The fix is to limit the number of RX BDs
 		 * the hardware would fetch at a fime.
 		 */
-		CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL, dmactl |
+		CSR_WRITE_4(sc, rdmareg, dmactl |
 		    BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
 	}
 
@@ -2505,11 +2543,34 @@ bge_blockinit(struct bge_softc *sc)
 		    CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
 		    BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512 |
 		    BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
+	} else if (sc->bge_asicrev == BGE_ASICREV_BCM5762) {
+		CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL_REG2,
+		    CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL_REG2) |
+		    BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K |
+		    BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
 	}
 
 	CSR_WRITE_4(sc, BGE_RDMA_MODE, val);
 	DELAY(40);
 
+	if (sc->bge_flags & BGE_FLAG_RDMA_BUG) {
+		for (i = 0; i < BGE_NUM_RDMA_CHANNELS / 2; i++) {
+			val = CSR_READ_4(sc, BGE_RDMA_LENGTH + i * 4);
+			if ((val & 0xFFFF) > BGE_FRAMELEN)
+				break;
+			if (((val >> 16) & 0xFFFF) > BGE_FRAMELEN)
+				break;
+		}
+		if (i != BGE_NUM_RDMA_CHANNELS / 2) {
+			val = CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL);
+			if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+				val |= BGE_RDMA_TX_LENGTH_WA_5719;
+			else
+				val |= BGE_RDMA_TX_LENGTH_WA_5720;
+			CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL, val);
+		}
+	}
+
 	/* Turn on RX data completion state machine */
 	CSR_WRITE_4(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);
 
@@ -2636,6 +2697,12 @@ bge_chipid(device_t dev)
 		case BCOM_DEVICEID_BCM5718:
 		case BCOM_DEVICEID_BCM5719:
 		case BCOM_DEVICEID_BCM5720:
+		case BCOM_DEVICEID_BCM5725:
+		case BCOM_DEVICEID_BCM5727:
+		case BCOM_DEVICEID_BCM5762:
+		case BCOM_DEVICEID_BCM57764:
+		case BCOM_DEVICEID_BCM57767:
+		case BCOM_DEVICEID_BCM57787:
 			id = pci_read_config(dev,
 			    BGE_PCI_GEN2_PRODID_ASICREV, 4);
 			break;
@@ -2644,7 +2711,9 @@ bge_chipid(device_t dev)
 		case BCOM_DEVICEID_BCM57765:
 		case BCOM_DEVICEID_BCM57766:
 		case BCOM_DEVICEID_BCM57781:
+		case BCOM_DEVICEID_BCM57782:
 		case BCOM_DEVICEID_BCM57785:
+		case BCOM_DEVICEID_BCM57786:
 		case BCOM_DEVICEID_BCM57791:
 		case BCOM_DEVICEID_BCM57795:
 			id = pci_read_config(dev,
@@ -3259,7 +3328,7 @@ bge_attach(device_t dev)
 	struct bge_softc *sc;
 	uint32_t hwcfg = 0, misccfg, pcistate;
 	u_char eaddr[ETHER_ADDR_LEN];
-	int capmask, error, msicount, reg, rid, trys;
+	int capmask, error, reg, rid, trys;
 
 	sc = device_get_softc(dev);
 	sc->bge_dev = dev;
@@ -3268,11 +3337,11 @@ bge_attach(device_t dev)
 	TASK_INIT(&sc->bge_intr_task, 0, bge_intr_task, sc);
 	callout_init_mtx(&sc->bge_stat_ch, &sc->bge_mtx, 0);
 
-	/*
-	 * Map control/status registers.
-	 */
 	pci_enable_busmaster(dev);
 
+	/*
+	 * Allocate control/status registers.
+	 */
 	rid = PCIR_BAR(0);
 	sc->bge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
 	    RF_ACTIVE);
@@ -3336,6 +3405,7 @@ bge_attach(device_t dev)
 
 	/* Save chipset family. */
 	switch (sc->bge_asicrev) {
+	case BGE_ASICREV_BCM5762:
 	case BGE_ASICREV_BCM57765:
 	case BGE_ASICREV_BCM57766:
 		sc->bge_flags |= BGE_FLAG_57765_PLUS;
@@ -3346,10 +3416,18 @@ bge_attach(device_t dev)
 		sc->bge_flags |= BGE_FLAG_5717_PLUS | BGE_FLAG_5755_PLUS |
 		    BGE_FLAG_575X_PLUS | BGE_FLAG_5705_PLUS | BGE_FLAG_JUMBO |
 		    BGE_FLAG_JUMBO_FRAME;
-		if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
-		    sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
-			/* Jumbo frame on BCM5719 A0 does not work. */
-			sc->bge_flags &= ~BGE_FLAG_JUMBO;
+		if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+		    sc->bge_asicrev == BGE_ASICREV_BCM5720) {
+			/*
+			 * Enable work around for DMA engine miscalculation
+			 * of TXMBUF available space.
+			 */
+			sc->bge_flags |= BGE_FLAG_RDMA_BUG;
+			if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
+			    sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
+				/* Jumbo frame on BCM5719 A0 does not work. */
+				sc->bge_flags &= ~BGE_FLAG_JUMBO;
+			}
 		}
 		break;
 	case BGE_ASICREV_BCM5755:
@@ -3388,6 +3466,7 @@ bge_attach(device_t dev)
 	case BGE_ASICREV_BCM5719:
 	case BGE_ASICREV_BCM5720:
 	case BGE_ASICREV_BCM5761:
+	case BGE_ASICREV_BCM5762:
 		sc->bge_flags |= BGE_FLAG_APE;
 		break;
 	}
@@ -3572,13 +3651,8 @@ bge_attach(device_t dev)
 	rid = 0;
 	if (pci_find_cap(sc->bge_dev, PCIY_MSI, &reg) == 0) {
 		sc->bge_msicap = reg;
-		if (bge_can_use_msi(sc)) {
-			msicount = pci_msi_count(dev);
-			if (msicount > 1)
-				msicount = 1;
-		} else
-			msicount = 0;
-		if (msicount == 1 && pci_alloc_msi(dev, &msicount) == 0) {
+		reg = 1;
+		if (bge_can_use_msi(sc) && pci_alloc_msi(dev, &reg) == 0) {
 			rid = 1;
 			sc->bge_flags |= BGE_FLAG_MSI;
 		}
@@ -3595,7 +3669,7 @@ bge_attach(device_t dev)
 #endif
 
 	sc->bge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
-	    RF_SHAREABLE | RF_ACTIVE);
+	    RF_ACTIVE | (rid != 0 ? 0 : RF_SHAREABLE));
 
 	if (sc->bge_irq == NULL) {
 		device_printf(sc->bge_dev, "couldn't map interrupt\n");
@@ -3938,20 +4012,19 @@ bge_release_resources(struct bge_softc *sc)
 	if (sc->bge_intrhand != NULL)
 		bus_teardown_intr(dev, sc->bge_irq, sc->bge_intrhand);
 
-	if (sc->bge_irq != NULL)
+	if (sc->bge_irq != NULL) {
 		bus_release_resource(dev, SYS_RES_IRQ,
-		    sc->bge_flags & BGE_FLAG_MSI ? 1 : 0, sc->bge_irq);
-
-	if (sc->bge_flags & BGE_FLAG_MSI)
+		    rman_get_rid(sc->bge_irq), sc->bge_irq);
 		pci_release_msi(dev);
+	}
 
 	if (sc->bge_res != NULL)
 		bus_release_resource(dev, SYS_RES_MEMORY,
-		    PCIR_BAR(0), sc->bge_res);
+		    rman_get_rid(sc->bge_res), sc->bge_res);
 
 	if (sc->bge_res2 != NULL)
 		bus_release_resource(dev, SYS_RES_MEMORY,
-		    PCIR_BAR(2), sc->bge_res2);
+		    rman_get_rid(sc->bge_res2), sc->bge_res2);
 
 	if (sc->bge_ifp != NULL)
 		if_free(sc->bge_ifp);
@@ -4767,6 +4840,7 @@ bge_stats_update_regs(struct bge_softc *sc)
 {
 	struct ifnet *ifp;
 	struct bge_mac_stats *stats;
+	uint32_t val;
 
 	ifp = sc->bge_ifp;
 	stats = &sc->bge_mac_stats;
@@ -4867,6 +4941,24 @@ bge_stats_update_regs(struct bge_softc *sc)
 	ifp->if_collisions = (u_long)stats->etherStatsCollisions;
 	ifp->if_ierrors = (u_long)(stats->NoMoreRxBDs + stats->InputDiscards +
 	    stats->InputErrors);
+
+	if (sc->bge_flags & BGE_FLAG_RDMA_BUG) {
+		/*
+		 * If controller transmitted more than BGE_NUM_RDMA_CHANNELS
+		 * frames, it's safe to disable workaround for DMA engine's
+		 * miscalculation of TXMBUF space.
+		 */
+		if (stats->ifHCOutUcastPkts + stats->ifHCOutMulticastPkts +
+		    stats->ifHCOutBroadcastPkts > BGE_NUM_RDMA_CHANNELS) {
+			val = CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL);
+			if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+				val &= ~BGE_RDMA_TX_LENGTH_WA_5719;
+			else
+				val &= ~BGE_RDMA_TX_LENGTH_WA_5720;
+			CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL, val);
+			sc->bge_flags &= ~BGE_FLAG_RDMA_BUG;
+		}
+	}
 }
 
 static void
@@ -5196,17 +5288,51 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
 		csum_flags |= BGE_TXBDFLAG_VLAN_TAG;
 		vlan_tag = m->m_pkthdr.ether_vtag;
 	}
-	for (i = 0; ; i++) {
-		d = &sc->bge_ldata.bge_tx_ring[idx];
-		d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr);
-		d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr);
-		d->bge_len = segs[i].ds_len;
-		d->bge_flags = csum_flags;
-		d->bge_vlan_tag = vlan_tag;
-		d->bge_mss = mss;
-		if (i == nsegs - 1)
-			break;
-		BGE_INC(idx, BGE_TX_RING_CNT);
+
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5762 &&
+	    (m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+		/*
+		 * 5725 family of devices corrupts TSO packets when TSO DMA
+		 * buffers cross into regions which are within MSS bytes of
+		 * a 4GB boundary.  If we encounter the condition, drop the
+		 * packet.
+		 */
+		for (i = 0; ; i++) {
+			d = &sc->bge_ldata.bge_tx_ring[idx];
+			d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr);
+			d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr);
+			d->bge_len = segs[i].ds_len;
+			if (d->bge_addr.bge_addr_lo + segs[i].ds_len + mss <
+			    d->bge_addr.bge_addr_lo)
+				break;
+			d->bge_flags = csum_flags;
+			d->bge_vlan_tag = vlan_tag;
+			d->bge_mss = mss;
+			if (i == nsegs - 1)
+				break;
+			BGE_INC(idx, BGE_TX_RING_CNT);
+		}
+		if (i != nsegs - 1) {
+			bus_dmamap_sync(sc->bge_cdata.bge_tx_mtag, map,
+			    BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, map);
+			m_freem(*m_head);
+			*m_head = NULL;
+			return (EIO);
+		}
+	} else {
+		for (i = 0; ; i++) {
+			d = &sc->bge_ldata.bge_tx_ring[idx];
+			d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr);
+			d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr);
+			d->bge_len = segs[i].ds_len;
+			d->bge_flags = csum_flags;
+			d->bge_vlan_tag = vlan_tag;
+			d->bge_mss = mss;
+			if (i == nsegs - 1)
+				break;
+			BGE_INC(idx, BGE_TX_RING_CNT);
+		}
 	}
 
 	/* Mark the last segment as end of packet... */
@@ -5433,7 +5559,8 @@ bge_init_locked(struct bge_softc *sc)
 	mode = CSR_READ_4(sc, BGE_TX_MODE);
 	if (BGE_IS_5755_PLUS(sc) || sc->bge_asicrev == BGE_ASICREV_BCM5906)
 		mode |= BGE_TXMODE_MBUF_LOCKUP_FIX;
-	if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
+	if (sc->bge_asicrev == BGE_ASICREV_BCM5720 ||
+	    sc->bge_asicrev == BGE_ASICREV_BCM5762) {
 		mode &= ~(BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
 		mode |= CSR_READ_4(sc, BGE_TX_MODE) &
 		    (BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
diff --git a/freebsd/sys/dev/bge/if_bgereg.h b/freebsd/sys/dev/bge/if_bgereg.h
index 09ced54..acac8b2 100644
--- a/freebsd/sys/dev/bge/if_bgereg.h
+++ b/freebsd/sys/dev/bge/if_bgereg.h
@@ -331,6 +331,7 @@
 #define	BGE_CHIPID_BCM5717_B0		0x05717100
 #define	BGE_CHIPID_BCM5719_A0		0x05719000
 #define	BGE_CHIPID_BCM5720_A0		0x05720000
+#define	BGE_CHIPID_BCM5762_A0		0x05762000
 #define	BGE_CHIPID_BCM57765_A0		0x57785000
 #define	BGE_CHIPID_BCM57765_B0		0x57785100
 
@@ -357,6 +358,7 @@
 #define	BGE_ASICREV_BCM5719		0x5719
 #define	BGE_ASICREV_BCM5720		0x5720
 #define	BGE_ASICREV_BCM5761		0x5761
+#define	BGE_ASICREV_BCM5762		0x5762
 #define	BGE_ASICREV_BCM5784		0x5784
 #define	BGE_ASICREV_BCM5785		0x5785
 #define	BGE_ASICREV_BCM57765		0x57785
@@ -378,6 +380,7 @@
 #define	BGE_CHIPREV_5717_AX		0x57170
 #define	BGE_CHIPREV_5717_BX		0x57171
 #define	BGE_CHIPREV_5761_AX		0x57611
+#define	BGE_CHIPREV_57765_AX		0x577850
 #define	BGE_CHIPREV_5784_AX		0x57841
 
 /* PCI DMA Read/Write Control register */
@@ -1289,6 +1292,7 @@
 #define	BGE_CPMU_MUTEX_REQ		0x365C
 #define	BGE_CPMU_MUTEX_GNT		0x3660
 #define	BGE_CPMU_PHY_STRAP		0x3664
+#define	BGE_CPMU_PADRNG_CTL		0x3668
 
 /* Central Power Management Unit (CPMU) register */
 #define	BGE_CPMU_CTRL_LINK_IDLE_MODE	0x00000200
@@ -1328,6 +1332,9 @@
 /* CPMU GPHY Strap register */
 #define	BGE_CPMU_PHY_STRAP_IS_SERDES	0x00000020
 
+/* CPMU Padring Control register */
+#define	BGE_CPMU_PADRNG_CTL_RDIV2	0x00040000
+
 /*
  * Mbuf Cluster Free registers (has nothing to do with BSD mbufs)
  */
@@ -1539,6 +1546,8 @@
  */
 #define	BGE_RDMA_MODE			0x4800
 #define	BGE_RDMA_STATUS			0x4804
+#define	BGE_RDMA_RSRVCTRL_REG2		0x4890
+#define	BGE_RDMA_LSO_CRPTEN_CTRL_REG2	0x48A0
 #define	BGE_RDMA_RSRVCTRL		0x4900
 #define	BGE_RDMA_LSO_CRPTEN_CTRL	0x4910
 
@@ -1586,6 +1595,8 @@
 #define	BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512	0x00020000
 #define	BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K	0x00030000
 #define	BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K	0x000C0000
+#define	BGE_RDMA_TX_LENGTH_WA_5719		0x02000000
+#define	BGE_RDMA_TX_LENGTH_WA_5720		0x00200000
 
 /* BD Read DMA Mode register */
 #define	BGE_RDMA_BD_MODE		0x4A00
@@ -1603,6 +1614,9 @@
 #define	BGE_RDMA_NON_LSO_MODE_RESET	0x00000001
 #define	BGE_RDMA_NON_LSO_MODE_ENABLE	0x00000002
 
+#define	BGE_RDMA_LENGTH			0x4BE0
+#define	BGE_NUM_RDMA_CHANNELS		4
+
 /*
  * Write DMA control registers
  */
@@ -2444,6 +2458,8 @@ struct bge_status_block {
 #define	BCOM_DEVICEID_BCM5721		0x1659
 #define	BCOM_DEVICEID_BCM5722		0x165A
 #define	BCOM_DEVICEID_BCM5723		0x165B
+#define	BCOM_DEVICEID_BCM5725		0x1643
+#define	BCOM_DEVICEID_BCM5727		0x16F3
 #define	BCOM_DEVICEID_BCM5750		0x1676
 #define	BCOM_DEVICEID_BCM5750M		0x167C
 #define	BCOM_DEVICEID_BCM5751		0x1677
@@ -2463,6 +2479,7 @@ struct bge_status_block {
 #define	BCOM_DEVICEID_BCM5761E		0x1680
 #define	BCOM_DEVICEID_BCM5761S		0x1688
 #define	BCOM_DEVICEID_BCM5761SE		0x1689
+#define	BCOM_DEVICEID_BCM5762		0x1687
 #define	BCOM_DEVICEID_BCM5764		0x1684
 #define	BCOM_DEVICEID_BCM5780		0x166A
 #define	BCOM_DEVICEID_BCM5780S		0x166B
@@ -2485,11 +2502,16 @@ struct bge_status_block {
 #define	BCOM_DEVICEID_BCM57760		0x1690
 #define	BCOM_DEVICEID_BCM57761		0x16B0
 #define	BCOM_DEVICEID_BCM57762		0x1682
+#define	BCOM_DEVICEID_BCM57764		0x1642
 #define	BCOM_DEVICEID_BCM57765		0x16B4
 #define	BCOM_DEVICEID_BCM57766		0x1686
+#define	BCOM_DEVICEID_BCM57767		0x1683
 #define	BCOM_DEVICEID_BCM57780		0x1692
 #define	BCOM_DEVICEID_BCM57781		0x16B1
+#define	BCOM_DEVICEID_BCM57782		0x16B7
 #define	BCOM_DEVICEID_BCM57785		0x16B5
+#define	BCOM_DEVICEID_BCM57786		0x16B3
+#define	BCOM_DEVICEID_BCM57787		0x1641
 #define	BCOM_DEVICEID_BCM57788		0x1691
 #define	BCOM_DEVICEID_BCM57790		0x1694
 #define	BCOM_DEVICEID_BCM57791		0x16B2
@@ -2829,7 +2851,7 @@ struct bge_gib {
  */
 
 #define	BGE_NSEG_JUMBO	4
-#define	BGE_NSEG_NEW	32
+#define	BGE_NSEG_NEW	35
 #define	BGE_TSOSEG_SZ	4096
 
 /* Maximum DMA address for controllers that have 40bit DMA address bug. */
@@ -2982,6 +3004,7 @@ struct bge_softc {
 #define	BGE_FLAG_SHORT_DMA_BUG	0x08000000
 #define	BGE_FLAG_4K_RDMA_BUG	0x10000000
 #define	BGE_FLAG_MBOX_REORDER	0x20000000
+#define	BGE_FLAG_RDMA_BUG	0x40000000
 	uint32_t		bge_mfw_flags;	/* Management F/W flags */
 #define	BGE_MFW_ON_RXCPU	0x00000001
 #define	BGE_MFW_ON_APE		0x00000002
diff --git a/freebsd/sys/dev/e1000/e1000_defines.h b/freebsd/sys/dev/e1000/e1000_defines.h
index 48c04b0..0815ea8 100644
--- a/freebsd/sys/dev/e1000/e1000_defines.h
+++ b/freebsd/sys/dev/e1000/e1000_defines.h
@@ -129,7 +129,7 @@
 #define E1000_RXD_ERR_RXE	0x80    /* Rx Data Error */
 #define E1000_RXD_SPC_VLAN_MASK	0x0FFF  /* VLAN ID is in lower 12 bits */
 
-#define E1000_RXDEXT_STATERR_TST	0x00000100 /* Time Stamp taken */
+#define E1000_RXDEXT_STATERR_TST	0x00010000 /* Time Stamp taken */
 #define E1000_RXDEXT_STATERR_LB		0x00040000
 #define E1000_RXDEXT_STATERR_CE		0x01000000
 #define E1000_RXDEXT_STATERR_SE		0x02000000
diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c
index 4c1d346..2a3fe54 100644
--- a/freebsd/sys/dev/e1000/if_em.c
+++ b/freebsd/sys/dev/e1000/if_em.c
@@ -3837,8 +3837,7 @@ em_txeof(struct tx_ring *txr)
 
 	EM_TX_LOCK_ASSERT(txr);
 #ifdef DEV_NETMAP
-	if (netmap_tx_irq(ifp, txr->me |
-	    (NETMAP_LOCKED_ENTER | NETMAP_LOCKED_EXIT)))
+	if (netmap_tx_irq(ifp, txr->me))
 		return;
 #endif /* DEV_NETMAP */
 
@@ -4355,7 +4354,7 @@ em_initialize_receive_unit(struct adapter *adapter)
 		 * preserve the rx buffers passed to userspace.
 		 */
 		if (ifp->if_capenable & IFCAP_NETMAP)
-			rdt -= NA(adapter->ifp)->rx_rings[i].nr_hwavail;
+			rdt -= nm_kr_rxspace(&NA(adapter->ifp)->rx_rings[i]);
 #endif /* DEV_NETMAP */
 		E1000_WRITE_REG(hw, E1000_RDT(i), rdt);
 	}
@@ -4434,8 +4433,10 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
 	EM_RX_LOCK(rxr);
 
 #ifdef DEV_NETMAP
-	if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed))
+	if (netmap_rx_irq(ifp, rxr->me, &processed)) {
+		EM_RX_UNLOCK(rxr);
 		return (FALSE);
+	}
 #endif /* DEV_NETMAP */
 
 	for (i = rxr->next_to_check, processed = 0; count != 0;) {
diff --git a/freebsd/sys/dev/e1000/if_igb.c b/freebsd/sys/dev/e1000/if_igb.c
index e26a867..09da15c 100644
--- a/freebsd/sys/dev/e1000/if_igb.c
+++ b/freebsd/sys/dev/e1000/if_igb.c
@@ -2885,6 +2885,9 @@ igb_setup_msix(struct adapter *adapter)
 	if (queues > maxqueues)
 		queues = maxqueues;
 
+	/* reflect correct sysctl value */
+	igb_num_queues = queues;
+
 	/*
 	** One vector (RX/TX pair) per queue
 	** plus an additional for Link interrupt
@@ -3909,8 +3912,7 @@ igb_txeof(struct tx_ring *txr)
 	IGB_TX_LOCK_ASSERT(txr);
 
 #ifdef DEV_NETMAP
-	if (netmap_tx_irq(ifp, txr->me |
-	    (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
+	if (netmap_tx_irq(ifp, txr->me ))
 		return (FALSE);
 #endif /* DEV_NETMAP */
         if (txr->tx_avail == adapter->num_tx_desc) {
@@ -4571,13 +4573,13 @@ igb_initialize_receive_units(struct adapter *adapter)
 		 * an init() while a netmap client is active must
 		 * preserve the rx buffers passed to userspace.
 		 * In this driver it means we adjust RDT to
-		 * somthing different from next_to_refresh
+		 * something different from next_to_refresh
 		 * (which is not used in netmap mode).
 		 */
 		if (ifp->if_capenable & IFCAP_NETMAP) {
 			struct netmap_adapter *na = NA(adapter->ifp);
 			struct netmap_kring *kring = &na->rx_rings[i];
-			int t = rxr->next_to_refresh - kring->nr_hwavail;
+			int t = rxr->next_to_refresh - nm_kr_rxspace(kring);
 
 			if (t >= adapter->num_rx_desc)
 				t -= adapter->num_rx_desc;
@@ -4765,8 +4767,10 @@ igb_rxeof(struct igb_queue *que, int count, int *done)
 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 
 #ifdef DEV_NETMAP
-	if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed))
+	if (netmap_rx_irq(ifp, rxr->me, &processed)) {
+		IGB_RX_UNLOCK(rxr);
 		return (FALSE);
+	}
 #endif /* DEV_NETMAP */
 
 	/* Main clean loop */
diff --git a/freebsd/sys/dev/e1000/if_lem.c b/freebsd/sys/dev/e1000/if_lem.c
index 5127445..64a1bcc 100644
--- a/freebsd/sys/dev/e1000/if_lem.c
+++ b/freebsd/sys/dev/e1000/if_lem.c
@@ -2680,7 +2680,7 @@ lem_setup_transmit_structures(struct adapter *adapter)
 			void *addr;
 
 			addr = PNMB(slot + si, &paddr);
-			adapter->tx_desc_base[si].buffer_addr = htole64(paddr);
+			adapter->tx_desc_base[i].buffer_addr = htole64(paddr);
 			/* reload the map for netmap mode */
 			netmap_load_map(adapter->txtag, tx_buffer->map, addr);
 		}
@@ -2987,7 +2987,7 @@ lem_txeof(struct adapter *adapter)
 	EM_TX_LOCK_ASSERT(adapter);
 
 #ifdef DEV_NETMAP
-	if (netmap_tx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
+	if (netmap_tx_irq(ifp, 0))
 		return;
 #endif /* DEV_NETMAP */
         if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
@@ -3370,7 +3370,7 @@ lem_initialize_receive_unit(struct adapter *adapter)
 #ifdef DEV_NETMAP
 	/* preserve buffers already made available to clients */
 	if (ifp->if_capenable & IFCAP_NETMAP)
-		rctl -= NA(adapter->ifp)->rx_rings[0].nr_hwavail;
+		rctl -= nm_kr_rxspace(&NA(adapter->ifp)->rx_rings[0]);
 #endif /* DEV_NETMAP */
 	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), rctl);
 
@@ -3456,8 +3456,10 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
 	    BUS_DMASYNC_POSTREAD);
 
 #ifdef DEV_NETMAP
-	if (netmap_rx_irq(ifp, 0 | NETMAP_LOCKED_ENTER, &rx_sent))
+	if (netmap_rx_irq(ifp, 0, &rx_sent)) {
+		EM_RX_UNLOCK(adapter);
 		return (FALSE);
+	}
 #endif /* DEV_NETMAP */
 
 	if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
diff --git a/freebsd/sys/dev/fxp/if_fxpreg.h b/freebsd/sys/dev/fxp/if_fxpreg.h
index cc764b5..7fd60af 100644
--- a/freebsd/sys/dev/fxp/if_fxpreg.h
+++ b/freebsd/sys/dev/fxp/if_fxpreg.h
@@ -250,7 +250,7 @@ struct fxp_cb_ucode {
 /*
  * Number of DMA segments in a TxCB.
  */
-#define FXP_NTXSEG	32
+#define FXP_NTXSEG	35
 
 struct fxp_tbd {
 	uint32_t tb_addr;
diff --git a/freebsd/sys/dev/mii/brgphy.c b/freebsd/sys/dev/mii/brgphy.c
index de1249c..75c1577 100644
--- a/freebsd/sys/dev/mii/brgphy.c
+++ b/freebsd/sys/dev/mii/brgphy.c
@@ -149,6 +149,7 @@ static const struct mii_phydesc brgphys[] = {
 	MII_PHY_DESC(BROADCOM3, BCM5720C),
 	MII_PHY_DESC(BROADCOM3, BCM57765),
 	MII_PHY_DESC(BROADCOM3, BCM57780),
+	MII_PHY_DESC(BROADCOM4, BCM5725C),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5906),
 	MII_PHY_END
 };
@@ -934,6 +935,8 @@ brgphy_reset(struct mii_softc *sc)
 			return;
 		}
 		break;
+	case MII_OUI_BROADCOM4:
+		return;
 	}
 
 	ifp = sc->mii_pdata->mii_ifp;
diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c
index 94eeb84..7dcaa0d 100644
--- a/freebsd/sys/dev/pci/pci.c
+++ b/freebsd/sys/dev/pci/pci.c
@@ -164,7 +164,7 @@ static device_method_t pci_methods[] = {
 	DEVMETHOD(bus_delete_resource,	pci_delete_resource),
 	DEVMETHOD(bus_alloc_resource,	pci_alloc_resource),
 	DEVMETHOD(bus_adjust_resource,	bus_generic_adjust_resource),
-	DEVMETHOD(bus_release_resource,	bus_generic_rl_release_resource),
+	DEVMETHOD(bus_release_resource,	pci_release_resource),
 	DEVMETHOD(bus_activate_resource, pci_activate_resource),
 	DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
 	DEVMETHOD(bus_child_pnpinfo_str, pci_child_pnpinfo_str_method),
@@ -347,6 +347,11 @@ SYSCTL_INT(_hw_pci, OID_AUTO, usb_early_takeover, CTLFLAG_RDTUN,
 Disable this if you depend on BIOS emulation of USB devices, that is\n\
 you use USB devices (like keyboard or mouse) but do not load USB drivers");
 
+static int pci_clear_bars;
+TUNABLE_INT("hw.pci.clear_bars", &pci_clear_bars);
+SYSCTL_INT(_hw_pci, OID_AUTO, clear_bars, CTLFLAG_RDTUN, &pci_clear_bars, 0,
+    "Ignore firmware-assigned resources for BARs.");
+
 static int
 pci_has_quirk(uint32_t devid, int quirk)
 {
@@ -999,7 +1004,7 @@ pci_read_vpd(device_t pcib, pcicfgregs *cfg)
 				state = -2;
 				break;
 			}
-			dflen = byte2;
+			cfg->vpd.vpd_ros[off].len = dflen = byte2;
 			if (dflen == 0 &&
 			    strncmp(cfg->vpd.vpd_ros[off].keyword, "RV",
 			    2) == 0) {
@@ -1200,6 +1205,17 @@ pci_get_vpd_readonly_method(device_t dev, device_t child, const char *kw,
 	return (ENXIO);
 }
 
+struct pcicfg_vpd *
+pci_fetch_vpd_list(device_t dev)
+{
+	struct pci_devinfo *dinfo = device_get_ivars(dev);
+	pcicfgregs *cfg = &dinfo->cfg;
+
+	if (!cfg->vpd.vpd_cached && cfg->vpd.vpd_reg != 0)
+		pci_read_vpd(device_get_parent(device_get_parent(dev)), cfg);
+	return (&cfg->vpd);
+}
+
 /*
  * Find the requested extended capability and return the offset in
  * configuration space via the pointer provided. The function returns
@@ -2668,7 +2684,7 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl,
 	struct pci_map *pm;
 	pci_addr_t base, map, testval;
 	pci_addr_t start, end, count;
-	int barlen, basezero, maprange, mapsize, type;
+	int barlen, basezero, flags, maprange, mapsize, type;
 	uint16_t cmd;
 	struct resource *res;
 
@@ -2774,7 +2790,10 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl,
 	}
 
 	count = (pci_addr_t)1 << mapsize;
-	if (basezero || base == pci_mapbase(testval)) {
+	flags = RF_ALIGNMENT_LOG2(mapsize);
+	if (prefetch)
+		flags |= RF_PREFETCHABLE;
+	if (basezero || base == pci_mapbase(testval) || pci_clear_bars) {
 		start = 0;	/* Let the parent decide. */
 		end = ~0ul;
 	} else {
@@ -2790,7 +2809,7 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl,
 	 * pci_alloc_resource().
 	 */
 	res = resource_list_reserve(rl, bus, dev, type, &reg, start, end, count,
-	    prefetch ? RF_PREFETCHABLE : 0);
+	    flags);
 	if (pci_do_realloc_bars && res == NULL && (start != 0 || end != ~0ul)) {
 		/*
 		 * If the allocation fails, try to allocate a resource for
@@ -2801,7 +2820,7 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl,
 		resource_list_delete(rl, type, reg);
 		resource_list_add(rl, type, reg, 0, ~0ul, count);
 		res = resource_list_reserve(rl, bus, dev, type, &reg, 0, ~0ul,
-		    count, prefetch ? RF_PREFETCHABLE : 0);
+		    count, flags);
 	}
 	if (res == NULL) {
 		/*
@@ -3650,105 +3669,107 @@ static const struct
 {
 	int		class;
 	int		subclass;
+	int		report; /* 0 = bootverbose, 1 = always */
 	const char	*desc;
 } pci_nomatch_tab[] = {
-	{PCIC_OLD,		-1,			"old"},
-	{PCIC_OLD,		PCIS_OLD_NONVGA,	"non-VGA display device"},
-	{PCIC_OLD,		PCIS_OLD_VGA,		"VGA-compatible display device"},
-	{PCIC_STORAGE,		-1,			"mass storage"},
-	{PCIC_STORAGE,		PCIS_STORAGE_SCSI,	"SCSI"},
-	{PCIC_STORAGE,		PCIS_STORAGE_IDE,	"ATA"},
-	{PCIC_STORAGE,		PCIS_STORAGE_FLOPPY,	"floppy disk"},
-	{PCIC_STORAGE,		PCIS_STORAGE_IPI,	"IPI"},
-	{PCIC_STORAGE,		PCIS_STORAGE_RAID,	"RAID"},
-	{PCIC_STORAGE,		PCIS_STORAGE_ATA_ADMA,	"ATA (ADMA)"},
-	{PCIC_STORAGE,		PCIS_STORAGE_SATA,	"SATA"},
-	{PCIC_STORAGE,		PCIS_STORAGE_SAS,	"SAS"},
-	{PCIC_STORAGE,		PCIS_STORAGE_NVM,	"NVM"},
-	{PCIC_NETWORK,		-1,			"network"},
-	{PCIC_NETWORK,		PCIS_NETWORK_ETHERNET,	"ethernet"},
-	{PCIC_NETWORK,		PCIS_NETWORK_TOKENRING,	"token ring"},
-	{PCIC_NETWORK,		PCIS_NETWORK_FDDI,	"fddi"},
-	{PCIC_NETWORK,		PCIS_NETWORK_ATM,	"ATM"},
-	{PCIC_NETWORK,		PCIS_NETWORK_ISDN,	"ISDN"},
-	{PCIC_DISPLAY,		-1,			"display"},
-	{PCIC_DISPLAY,		PCIS_DISPLAY_VGA,	"VGA"},
-	{PCIC_DISPLAY,		PCIS_DISPLAY_XGA,	"XGA"},
-	{PCIC_DISPLAY,		PCIS_DISPLAY_3D,	"3D"},
-	{PCIC_MULTIMEDIA,	-1,			"multimedia"},
-	{PCIC_MULTIMEDIA,	PCIS_MULTIMEDIA_VIDEO,	"video"},
-	{PCIC_MULTIMEDIA,	PCIS_MULTIMEDIA_AUDIO,	"audio"},
-	{PCIC_MULTIMEDIA,	PCIS_MULTIMEDIA_TELE,	"telephony"},
-	{PCIC_MULTIMEDIA,	PCIS_MULTIMEDIA_HDA,	"HDA"},
-	{PCIC_MEMORY,		-1,			"memory"},
-	{PCIC_MEMORY,		PCIS_MEMORY_RAM,	"RAM"},
-	{PCIC_MEMORY,		PCIS_MEMORY_FLASH,	"flash"},
-	{PCIC_BRIDGE,		-1,			"bridge"},
-	{PCIC_BRIDGE,		PCIS_BRIDGE_HOST,	"HOST-PCI"},
-	{PCIC_BRIDGE,		PCIS_BRIDGE_ISA,	"PCI-ISA"},
-	{PCIC_BRIDGE,		PCIS_BRIDGE_EISA,	"PCI-EISA"},
-	{PCIC_BRIDGE,		PCIS_BRIDGE_MCA,	"PCI-MCA"},
-	{PCIC_BRIDGE,		PCIS_BRIDGE_PCI,	"PCI-PCI"},
-	{PCIC_BRIDGE,		PCIS_BRIDGE_PCMCIA,	"PCI-PCMCIA"},
-	{PCIC_BRIDGE,		PCIS_BRIDGE_NUBUS,	"PCI-NuBus"},
-	{PCIC_BRIDGE,		PCIS_BRIDGE_CARDBUS,	"PCI-CardBus"},
-	{PCIC_BRIDGE,		PCIS_BRIDGE_RACEWAY,	"PCI-RACEway"},
-	{PCIC_SIMPLECOMM,	-1,			"simple comms"},
-	{PCIC_SIMPLECOMM,	PCIS_SIMPLECOMM_UART,	"UART"},	/* could detect 16550 */
-	{PCIC_SIMPLECOMM,	PCIS_SIMPLECOMM_PAR,	"parallel port"},
-	{PCIC_SIMPLECOMM,	PCIS_SIMPLECOMM_MULSER,	"multiport serial"},
-	{PCIC_SIMPLECOMM,	PCIS_SIMPLECOMM_MODEM,	"generic modem"},
-	{PCIC_BASEPERIPH,	-1,			"base peripheral"},
-	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_PIC,	"interrupt controller"},
-	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_DMA,	"DMA controller"},
-	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_TIMER,	"timer"},
-	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_RTC,	"realtime clock"},
-	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_PCIHOT,	"PCI hot-plug controller"},
-	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_SDHC,	"SD host controller"},
-	{PCIC_INPUTDEV,		-1,			"input device"},
-	{PCIC_INPUTDEV,		PCIS_INPUTDEV_KEYBOARD,	"keyboard"},
-	{PCIC_INPUTDEV,		PCIS_INPUTDEV_DIGITIZER,"digitizer"},
-	{PCIC_INPUTDEV,		PCIS_INPUTDEV_MOUSE,	"mouse"},
-	{PCIC_INPUTDEV,		PCIS_INPUTDEV_SCANNER,	"scanner"},
-	{PCIC_INPUTDEV,		PCIS_INPUTDEV_GAMEPORT,	"gameport"},
-	{PCIC_DOCKING,		-1,			"docking station"},
-	{PCIC_PROCESSOR,	-1,			"processor"},
-	{PCIC_SERIALBUS,	-1,			"serial bus"},
-	{PCIC_SERIALBUS,	PCIS_SERIALBUS_FW,	"FireWire"},
-	{PCIC_SERIALBUS,	PCIS_SERIALBUS_ACCESS,	"AccessBus"},
-	{PCIC_SERIALBUS,	PCIS_SERIALBUS_SSA,	"SSA"},
-	{PCIC_SERIALBUS,	PCIS_SERIALBUS_USB,	"USB"},
-	{PCIC_SERIALBUS,	PCIS_SERIALBUS_FC,	"Fibre Channel"},
-	{PCIC_SERIALBUS,	PCIS_SERIALBUS_SMBUS,	"SMBus"},
-	{PCIC_WIRELESS,		-1,			"wireless controller"},
-	{PCIC_WIRELESS,		PCIS_WIRELESS_IRDA,	"iRDA"},
-	{PCIC_WIRELESS,		PCIS_WIRELESS_IR,	"IR"},
-	{PCIC_WIRELESS,		PCIS_WIRELESS_RF,	"RF"},
-	{PCIC_INTELLIIO,	-1,			"intelligent I/O controller"},
-	{PCIC_INTELLIIO,	PCIS_INTELLIIO_I2O,	"I2O"},
-	{PCIC_SATCOM,		-1,			"satellite communication"},
-	{PCIC_SATCOM,		PCIS_SATCOM_TV,		"sat TV"},
-	{PCIC_SATCOM,		PCIS_SATCOM_AUDIO,	"sat audio"},
-	{PCIC_SATCOM,		PCIS_SATCOM_VOICE,	"sat voice"},
-	{PCIC_SATCOM,		PCIS_SATCOM_DATA,	"sat data"},
-	{PCIC_CRYPTO,		-1,			"encrypt/decrypt"},
-	{PCIC_CRYPTO,		PCIS_CRYPTO_NETCOMP,	"network/computer crypto"},
-	{PCIC_CRYPTO,		PCIS_CRYPTO_ENTERTAIN,	"entertainment crypto"},
-	{PCIC_DASP,		-1,			"dasp"},
-	{PCIC_DASP,		PCIS_DASP_DPIO,		"DPIO module"},
-	{0, 0,		NULL}
+	{PCIC_OLD,		-1,			1, "old"},
+	{PCIC_OLD,		PCIS_OLD_NONVGA,	1, "non-VGA display device"},
+	{PCIC_OLD,		PCIS_OLD_VGA,		1, "VGA-compatible display device"},
+	{PCIC_STORAGE,		-1,			1, "mass storage"},
+	{PCIC_STORAGE,		PCIS_STORAGE_SCSI,	1, "SCSI"},
+	{PCIC_STORAGE,		PCIS_STORAGE_IDE,	1, "ATA"},
+	{PCIC_STORAGE,		PCIS_STORAGE_FLOPPY,	1, "floppy disk"},
+	{PCIC_STORAGE,		PCIS_STORAGE_IPI,	1, "IPI"},
+	{PCIC_STORAGE,		PCIS_STORAGE_RAID,	1, "RAID"},
+	{PCIC_STORAGE,		PCIS_STORAGE_ATA_ADMA,	1, "ATA (ADMA)"},
+	{PCIC_STORAGE,		PCIS_STORAGE_SATA,	1, "SATA"},
+	{PCIC_STORAGE,		PCIS_STORAGE_SAS,	1, "SAS"},
+	{PCIC_STORAGE,		PCIS_STORAGE_NVM,	1, "NVM"},
+	{PCIC_NETWORK,		-1,			1, "network"},
+	{PCIC_NETWORK,		PCIS_NETWORK_ETHERNET,	1, "ethernet"},
+	{PCIC_NETWORK,		PCIS_NETWORK_TOKENRING,	1, "token ring"},
+	{PCIC_NETWORK,		PCIS_NETWORK_FDDI,	1, "fddi"},
+	{PCIC_NETWORK,		PCIS_NETWORK_ATM,	1, "ATM"},
+	{PCIC_NETWORK,		PCIS_NETWORK_ISDN,	1, "ISDN"},
+	{PCIC_DISPLAY,		-1,			1, "display"},
+	{PCIC_DISPLAY,		PCIS_DISPLAY_VGA,	1, "VGA"},
+	{PCIC_DISPLAY,		PCIS_DISPLAY_XGA,	1, "XGA"},
+	{PCIC_DISPLAY,		PCIS_DISPLAY_3D,	1, "3D"},
+	{PCIC_MULTIMEDIA,	-1,			1, "multimedia"},
+	{PCIC_MULTIMEDIA,	PCIS_MULTIMEDIA_VIDEO,	1, "video"},
+	{PCIC_MULTIMEDIA,	PCIS_MULTIMEDIA_AUDIO,	1, "audio"},
+	{PCIC_MULTIMEDIA,	PCIS_MULTIMEDIA_TELE,	1, "telephony"},
+	{PCIC_MULTIMEDIA,	PCIS_MULTIMEDIA_HDA,	1, "HDA"},
+	{PCIC_MEMORY,		-1,			1, "memory"},
+	{PCIC_MEMORY,		PCIS_MEMORY_RAM,	1, "RAM"},
+	{PCIC_MEMORY,		PCIS_MEMORY_FLASH,	1, "flash"},
+	{PCIC_BRIDGE,		-1,			1, "bridge"},
+	{PCIC_BRIDGE,		PCIS_BRIDGE_HOST,	1, "HOST-PCI"},
+	{PCIC_BRIDGE,		PCIS_BRIDGE_ISA,	1, "PCI-ISA"},
+	{PCIC_BRIDGE,		PCIS_BRIDGE_EISA,	1, "PCI-EISA"},
+	{PCIC_BRIDGE,		PCIS_BRIDGE_MCA,	1, "PCI-MCA"},
+	{PCIC_BRIDGE,		PCIS_BRIDGE_PCI,	1, "PCI-PCI"},
+	{PCIC_BRIDGE,		PCIS_BRIDGE_PCMCIA,	1, "PCI-PCMCIA"},
+	{PCIC_BRIDGE,		PCIS_BRIDGE_NUBUS,	1, "PCI-NuBus"},
+	{PCIC_BRIDGE,		PCIS_BRIDGE_CARDBUS,	1, "PCI-CardBus"},
+	{PCIC_BRIDGE,		PCIS_BRIDGE_RACEWAY,	1, "PCI-RACEway"},
+	{PCIC_SIMPLECOMM,	-1,			1, "simple comms"},
+	{PCIC_SIMPLECOMM,	PCIS_SIMPLECOMM_UART,	1, "UART"},	/* could detect 16550 */
+	{PCIC_SIMPLECOMM,	PCIS_SIMPLECOMM_PAR,	1, "parallel port"},
+	{PCIC_SIMPLECOMM,	PCIS_SIMPLECOMM_MULSER,	1, "multiport serial"},
+	{PCIC_SIMPLECOMM,	PCIS_SIMPLECOMM_MODEM,	1, "generic modem"},
+	{PCIC_BASEPERIPH,	-1,			0, "base peripheral"},
+	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_PIC,	1, "interrupt controller"},
+	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_DMA,	1, "DMA controller"},
+	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_TIMER,	1, "timer"},
+	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_RTC,	1, "realtime clock"},
+	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_PCIHOT,	1, "PCI hot-plug controller"},
+	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_SDHC,	1, "SD host controller"},
+	{PCIC_INPUTDEV,		-1,			1, "input device"},
+	{PCIC_INPUTDEV,		PCIS_INPUTDEV_KEYBOARD,	1, "keyboard"},
+	{PCIC_INPUTDEV,		PCIS_INPUTDEV_DIGITIZER,1, "digitizer"},
+	{PCIC_INPUTDEV,		PCIS_INPUTDEV_MOUSE,	1, "mouse"},
+	{PCIC_INPUTDEV,		PCIS_INPUTDEV_SCANNER,	1, "scanner"},
+	{PCIC_INPUTDEV,		PCIS_INPUTDEV_GAMEPORT,	1, "gameport"},
+	{PCIC_DOCKING,		-1,			1, "docking station"},
+	{PCIC_PROCESSOR,	-1,			1, "processor"},
+	{PCIC_SERIALBUS,	-1,			1, "serial bus"},
+	{PCIC_SERIALBUS,	PCIS_SERIALBUS_FW,	1, "FireWire"},
+	{PCIC_SERIALBUS,	PCIS_SERIALBUS_ACCESS,	1, "AccessBus"},
+	{PCIC_SERIALBUS,	PCIS_SERIALBUS_SSA,	1, "SSA"},
+	{PCIC_SERIALBUS,	PCIS_SERIALBUS_USB,	1, "USB"},
+	{PCIC_SERIALBUS,	PCIS_SERIALBUS_FC,	1, "Fibre Channel"},
+	{PCIC_SERIALBUS,	PCIS_SERIALBUS_SMBUS,	0, "SMBus"},
+	{PCIC_WIRELESS,		-1,			1, "wireless controller"},
+	{PCIC_WIRELESS,		PCIS_WIRELESS_IRDA,	1, "iRDA"},
+	{PCIC_WIRELESS,		PCIS_WIRELESS_IR,	1, "IR"},
+	{PCIC_WIRELESS,		PCIS_WIRELESS_RF,	1, "RF"},
+	{PCIC_INTELLIIO,	-1,			1, "intelligent I/O controller"},
+	{PCIC_INTELLIIO,	PCIS_INTELLIIO_I2O,	1, "I2O"},
+	{PCIC_SATCOM,		-1,			1, "satellite communication"},
+	{PCIC_SATCOM,		PCIS_SATCOM_TV,		1, "sat TV"},
+	{PCIC_SATCOM,		PCIS_SATCOM_AUDIO,	1, "sat audio"},
+	{PCIC_SATCOM,		PCIS_SATCOM_VOICE,	1, "sat voice"},
+	{PCIC_SATCOM,		PCIS_SATCOM_DATA,	1, "sat data"},
+	{PCIC_CRYPTO,		-1,			1, "encrypt/decrypt"},
+	{PCIC_CRYPTO,		PCIS_CRYPTO_NETCOMP,	1, "network/computer crypto"},
+	{PCIC_CRYPTO,		PCIS_CRYPTO_ENTERTAIN,	1, "entertainment crypto"},
+	{PCIC_DASP,		-1,			0, "dasp"},
+	{PCIC_DASP,		PCIS_DASP_DPIO,		1, "DPIO module"},
+	{0, 0, 0,		NULL}
 };
 
 void
 pci_probe_nomatch(device_t dev, device_t child)
 {
-	int i;
+	int i, report;
 	const char *cp, *scp;
 	char *device;
 
 	/*
 	 * Look for a listing for this device in a loaded device database.
 	 */
+	report = 1;
 	if ((device = pci_describe_device(child)) != NULL) {
 		device_printf(dev, "<%s>", device);
 		free(device, M_DEVBUF);
@@ -3763,19 +3784,25 @@ pci_probe_nomatch(device_t dev, device_t child)
 			if (pci_nomatch_tab[i].class == pci_get_class(child)) {
 				if (pci_nomatch_tab[i].subclass == -1) {
 					cp = pci_nomatch_tab[i].desc;
+					report = pci_nomatch_tab[i].report;
 				} else if (pci_nomatch_tab[i].subclass ==
 				    pci_get_subclass(child)) {
 					scp = pci_nomatch_tab[i].desc;
+					report = pci_nomatch_tab[i].report;
 				}
 			}
 		}
-		device_printf(dev, "<%s%s%s>",
-		    cp ? cp : "",
-		    ((cp != NULL) && (scp != NULL)) ? ", " : "",
-		    scp ? scp : "");
+		if (report || bootverbose) {
+			device_printf(dev, "<%s%s%s>",
+			    cp ? cp : "",
+			    ((cp != NULL) && (scp != NULL)) ? ", " : "",
+			    scp ? scp : "");
+		}
+	}
+	if (report || bootverbose) {
+		printf(" at device %d.%d (no driver attached)\n",
+		    pci_get_slot(child), pci_get_function(child));
 	}
-	printf(" at device %d.%d (no driver attached)\n",
-	    pci_get_slot(child), pci_get_function(child));
 	pci_cfg_save(child, device_get_ivars(child), 1);
 }
 
@@ -4078,7 +4105,6 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
 {
 	struct pci_devinfo *dinfo = device_get_ivars(child);
 	struct resource_list *rl = &dinfo->resources;
-	struct resource_list_entry *rle;
 	struct resource *res;
 	struct pci_map *pm;
 	pci_addr_t map, testval;
@@ -4151,23 +4177,16 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
 	 * Allocate enough resource, and then write back the
 	 * appropriate BAR for that resource.
 	 */
-	res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid,
-	    start, end, count, flags & ~RF_ACTIVE);
+	resource_list_add(rl, type, *rid, start, end, count);
+	res = resource_list_reserve(rl, dev, child, type, rid, start, end,
+	    count, flags & ~RF_ACTIVE);
 	if (res == NULL) {
+		resource_list_delete(rl, type, *rid);
 		device_printf(child,
 		    "%#lx bytes of rid %#x res %d failed (%#lx, %#lx).\n",
 		    count, *rid, type, start, end);
 		goto out;
 	}
-	resource_list_add(rl, type, *rid, start, end, count);
-	rle = resource_list_find(rl, type, *rid);
-	if (rle == NULL)
-		panic("pci_reserve_map: unexpectedly can't find resource.");
-	rle->res = res;
-	rle->start = rman_get_start(res);
-	rle->end = rman_get_end(res);
-	rle->count = count;
-	rle->flags = RLE_RESERVED;
 	if (bootverbose)
 		device_printf(child,
 		    "Lazy allocation of %#lx bytes rid %#x type %d at %#lx\n",
@@ -4182,11 +4201,11 @@ struct resource *
 pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
 		   u_long start, u_long end, u_long count, u_int flags)
 {
-	struct pci_devinfo *dinfo = device_get_ivars(child);
-	struct resource_list *rl = &dinfo->resources;
+	struct pci_devinfo *dinfo;
+	struct resource_list *rl;
 	struct resource_list_entry *rle;
 	struct resource *res;
-	pcicfgregs *cfg = &dinfo->cfg;
+	pcicfgregs *cfg;
 
 	if (device_get_parent(child) != dev)
 		return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
@@ -4195,6 +4214,9 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
 	/*
 	 * Perform lazy resource allocation
 	 */
+	dinfo = device_get_ivars(child);
+	rl = &dinfo->resources;
+	cfg = &dinfo->cfg;
 	switch (type) {
 	case SYS_RES_IRQ:
 		/*
@@ -4250,6 +4272,41 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
 }
 
 int
+pci_release_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *r)
+{
+	struct pci_devinfo *dinfo;
+	struct resource_list *rl;
+	pcicfgregs *cfg;
+
+	if (device_get_parent(child) != dev)
+		return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
+		    type, rid, r));
+
+	dinfo = device_get_ivars(child);
+	cfg = &dinfo->cfg;
+#ifdef NEW_PCIB
+	/*
+	 * PCI-PCI bridge I/O window resources are not BARs.  For
+	 * those allocations just pass the request up the tree.
+	 */
+	if (cfg->hdrtype == PCIM_HDRTYPE_BRIDGE &&
+	    (type == SYS_RES_IOPORT || type == SYS_RES_MEMORY)) {
+		switch (rid) {
+		case PCIR_IOBASEL_1:
+		case PCIR_MEMBASE_1:
+		case PCIR_PMBASEL_1:
+			return (bus_generic_release_resource(dev, child, type,
+			    rid, r));
+		}
+	}
+#endif
+
+	rl = &dinfo->resources;
+	return (resource_list_release(rl, dev, child, type, rid, r));
+}
+
+int
 pci_activate_resource(device_t dev, device_t child, int type, int rid,
     struct resource *r)
 {
diff --git a/freebsd/sys/dev/pci/pci_pci.c b/freebsd/sys/dev/pci/pci_pci.c
index bfaabf3..6c159ae 100644
--- a/freebsd/sys/dev/pci/pci_pci.c
+++ b/freebsd/sys/dev/pci/pci_pci.c
@@ -105,13 +105,12 @@ DEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc));
 DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, NULL, NULL);
 
 #ifdef NEW_PCIB
-/*
- * XXX Todo:
- * - properly handle the ISA enable bit.  If it is set, we should change
- *   the behavior of the I/O window resource and rman to not allocate the
- *   blocked ranges (upper 768 bytes of each 1K in the first 64k of the
- *   I/O port address space).
- */
+SYSCTL_DECL(_hw_pci);
+
+static int pci_clear_pcib;
+TUNABLE_INT("hw.pci.clear_pcib", &pci_clear_pcib);
+SYSCTL_INT(_hw_pci, OID_AUTO, clear_pcib, CTLFLAG_RDTUN, &pci_clear_pcib, 0,
+    "Clear firmware-assigned resources for PCI-PCI bridge I/O windows.");
 
 /*
  * Is a resource from a child device sub-allocated from one of our
@@ -191,10 +190,183 @@ pcib_write_windows(struct pcib_softc *sc, int mask)
 	}
 }
 
+/*
+ * This is used to reject I/O port allocations that conflict with an
+ * ISA alias range.
+ */
+static int
+pcib_is_isa_range(struct pcib_softc *sc, u_long start, u_long end, u_long count)
+{
+	u_long next_alias;
+
+	if (!(sc->bridgectl & PCIB_BCR_ISA_ENABLE))
+		return (0);
+
+	/* Only check fixed ranges for overlap. */
+	if (start + count - 1 != end)
+		return (0);
+
+	/* ISA aliases are only in the lower 64KB of I/O space. */
+	if (start >= 65536)
+		return (0);
+
+	/* Check for overlap with 0x000 - 0x0ff as a special case. */
+	if (start < 0x100)
+		goto alias;
+
+	/*
+	 * If the start address is an alias, the range is an alias.
+	 * Otherwise, compute the start of the next alias range and
+	 * check if it is before the end of the candidate range.
+	 */
+	if ((start & 0x300) != 0)
+		goto alias;
+	next_alias = (start & ~0x3fful) | 0x100;
+	if (next_alias <= end)
+		goto alias;
+	return (0);
+
+alias:
+	if (bootverbose)
+		device_printf(sc->dev,
+		    "I/O range %#lx-%#lx overlaps with an ISA alias\n", start,
+		    end);
+	return (1);
+}
+
+static void
+pcib_add_window_resources(struct pcib_window *w, struct resource **res,
+    int count)
+{
+	struct resource **newarray;
+	int error, i;
+
+	newarray = malloc(sizeof(struct resource *) * (w->count + count),
+	    M_DEVBUF, M_WAITOK);
+	if (w->res != NULL)
+		bcopy(w->res, newarray, sizeof(struct resource *) * w->count);
+	bcopy(res, newarray + w->count, sizeof(struct resource *) * count);
+	free(w->res, M_DEVBUF);
+	w->res = newarray;
+	w->count += count;
+	
+	for (i = 0; i < count; i++) {
+		error = rman_manage_region(&w->rman, rman_get_start(res[i]),
+		    rman_get_end(res[i]));
+		if (error)
+			panic("Failed to add resource to rman");
+	}
+}
+
+typedef void (nonisa_callback)(u_long start, u_long end, void *arg);
+
+static void
+pcib_walk_nonisa_ranges(u_long start, u_long end, nonisa_callback *cb,
+    void *arg)
+{
+	u_long next_end;
+
+	/*
+	 * If start is within an ISA alias range, move up to the start
+	 * of the next non-alias range.  As a special case, addresses
+	 * in the range 0x000 - 0x0ff should also be skipped since
+	 * those are used for various system I/O devices in ISA
+	 * systems.
+	 */
+	if (start <= 65535) {
+		if (start < 0x100 || (start & 0x300) != 0) {
+			start &= ~0x3ff;
+			start += 0x400;
+		}
+	}
+
+	/* ISA aliases are only in the lower 64KB of I/O space. */
+	while (start <= MIN(end, 65535)) {
+		next_end = MIN(start | 0xff, end);
+		cb(start, next_end, arg);
+		start += 0x400;
+	}
+
+	if (start <= end)
+		cb(start, end, arg);
+}
+
+static void
+count_ranges(u_long start, u_long end, void *arg)
+{
+	int *countp;
+
+	countp = arg;
+	(*countp)++;
+}
+
+struct alloc_state {
+	struct resource **res;
+	struct pcib_softc *sc;
+	int count, error;
+};
+
+static void
+alloc_ranges(u_long start, u_long end, void *arg)
+{
+	struct alloc_state *as;
+	struct pcib_window *w;
+	int rid;
+
+	as = arg;
+	if (as->error != 0)
+		return;
+
+	w = &as->sc->io;
+	rid = w->reg;
+	if (bootverbose)
+		device_printf(as->sc->dev,
+		    "allocating non-ISA range %#lx-%#lx\n", start, end);
+	as->res[as->count] = bus_alloc_resource(as->sc->dev, SYS_RES_IOPORT,
+	    &rid, start, end, end - start + 1, 0);
+	if (as->res[as->count] == NULL)
+		as->error = ENXIO;
+	else
+		as->count++;
+}
+
+static int
+pcib_alloc_nonisa_ranges(struct pcib_softc *sc, u_long start, u_long end)
+{
+	struct alloc_state as;
+	int i, new_count;
+
+	/* First, see how many ranges we need. */
+	new_count = 0;
+	pcib_walk_nonisa_ranges(start, end, count_ranges, &new_count);
+
+	/* Second, allocate the ranges. */
+	as.res = malloc(sizeof(struct resource *) * new_count, M_DEVBUF,
+	    M_WAITOK);
+	as.sc = sc;
+	as.count = 0;
+	as.error = 0;
+	pcib_walk_nonisa_ranges(start, end, alloc_ranges, &as);
+	if (as.error != 0) {
+		for (i = 0; i < as.count; i++)
+			bus_release_resource(sc->dev, SYS_RES_IOPORT,
+			    sc->io.reg, as.res[i]);
+		free(as.res, M_DEVBUF);
+		return (as.error);
+	}
+	KASSERT(as.count == new_count, ("%s: count mismatch", __func__));
+
+	/* Third, add the ranges to the window. */
+	pcib_add_window_resources(&sc->io, as.res, as.count);
+	free(as.res, M_DEVBUF);
+	return (0);
+}
+
 static void
 pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type,
     int flags, pci_addr_t max_address)
 {
+	struct resource *res;
 	char buf[64];
 	int error, rid;
 
@@ -219,9 +391,15 @@ pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 		    "initial %s window has too many bits, ignoring\n", w->name);
 		return;
 	}
-	rid = w->reg;
-	w->res = bus_alloc_resource(sc->dev, type, &rid, w->base, w->limit,
-	    w->limit - w->base + 1, flags);
+	if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE)
+		(void)pcib_alloc_nonisa_ranges(sc, w->base, w->limit);
+	else {
+		rid = w->reg;
+		res = bus_alloc_resource(sc->dev, type, &rid, w->base, w->limit,
+		    w->limit - w->base + 1, flags);
+		if (res != NULL)
+			pcib_add_window_resources(w, &res, 1);
+	}
 	if (w->res == NULL) {
 		device_printf(sc->dev,
 		    "failed to allocate initial %s window: %#jx-%#jx\n",
@@ -232,11 +410,6 @@ pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 		return;
 	}
 	pcib_activate_window(sc, type);
-
-	error = rman_manage_region(&w->rman, rman_get_start(w->res),
-	    rman_get_end(w->res));
-	if (error)
-		panic("Failed to initialize rman with resource");
 }
 
 /*
@@ -251,6 +424,19 @@ pcib_probe_windows(struct pcib_softc *sc)
 
 	dev = sc->dev;
 
+	if (pci_clear_pcib) {
+		pci_write_config(dev, PCIR_IOBASEL_1, 0xff, 1);
+		pci_write_config(dev, PCIR_IOBASEH_1, 0xffff, 2);
+		pci_write_config(dev, PCIR_IOLIMITL_1, 0, 1);
+		pci_write_config(dev, PCIR_IOLIMITH_1, 0, 2);
+		pci_write_config(dev, PCIR_MEMBASE_1, 0xffff, 2);
+		pci_write_config(dev, PCIR_MEMLIMIT_1, 0, 2);
+		pci_write_config(dev, PCIR_PMBASEL_1, 0xffff, 2);
+		pci_write_config(dev, PCIR_PMBASEH_1, 0xffffffff, 4);
+		pci_write_config(dev, PCIR_PMLIMITL_1, 0, 2);
+		pci_write_config(dev, PCIR_PMLIMITH_1, 0, 4);
+	}
+
 	/* Determine if the I/O port window is implemented. */
 	val = pci_read_config(dev, PCIR_IOBASEL_1, 1);
 	if (val == 0) {
@@ -543,6 +729,7 @@ pcib_attach_common(device_t dev)
     struct pcib_softc	*sc;
     struct sysctl_ctx_list *sctx;
     struct sysctl_oid	*soid;
+    int comma;
 
     sc = device_get_softc(dev);
     sc->dev = dev;
@@ -671,10 +858,22 @@ pcib_attach_common(device_t dev)
 	    device_printf(dev, "  prefetched decode 0x%jx-0x%jx\n",
 	      (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit);
 #endif
-	else
-	    device_printf(dev, "  no prefetched decode\n");
-	if (sc->flags & PCIB_SUBTRACTIVE)
-	    device_printf(dev, "  Subtractively decoded bridge.\n");
+	if (sc->bridgectl & (PCIB_BCR_ISA_ENABLE | PCIB_BCR_VGA_ENABLE) ||
+	    sc->flags & PCIB_SUBTRACTIVE) {
+		device_printf(dev, "  special decode    ");
+		comma = 0;
+		if (sc->bridgectl & PCIB_BCR_ISA_ENABLE) {
+			printf("ISA");
+			comma = 1;
+		}
+		if (sc->bridgectl & PCIB_BCR_VGA_ENABLE) {
+			printf("%sVGA", comma ? ", " : "");
+			comma = 1;
+		}
+		if (sc->flags & PCIB_SUBTRACTIVE)
+			printf("%ssubtractive", comma ? ", " : "");
+		printf("\n");
+	}
     }
 
     /*
@@ -821,23 +1020,197 @@ pcib_suballoc_resource(struct pcib_softc *sc, struct pcib_window *w,
 	return (res);
 }
 
+/* Allocate a fresh resource range for an unconfigured window. */
+static int
+pcib_alloc_new_window(struct pcib_softc *sc, struct pcib_window *w, int type,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct resource *res;
+	u_long base, limit, wmask;
+	int rid;
+
+	/*
+	 * If this is an I/O window on a bridge with ISA enable set
+	 * and the start address is below 64k, then try to allocate an
+	 * initial window of 0x1000 bytes long starting at address
+	 * 0xf000 and walking down.  Note that if the original request
+	 * was larger than the non-aliased range size of 0x100 our
+	 * caller would have raised the start address up to 64k
+	 * already.
+	 */
+	if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE &&
+	    start < 65536) {
+		for (base = 0xf000; (long)base >= 0; base -= 0x1000) {
+			limit = base + 0xfff;
+
+			/*
+			 * Skip ranges that wouldn't work for the
+			 * original request.  Note that the actual
+			 * window that overlaps are the non-alias
+			 * ranges within [base, limit], so this isn't
+			 * quite a simple comparison.
+			 */
+			if (start + count > limit - 0x400)
+				continue;
+			if (base == 0) {
+				/*
+				 * The first open region for the window at
+				 * 0 is 0x400-0x4ff.
+				 */
+				if (end - count + 1 < 0x400)
+					continue;
+			} else {
+				if (end - count + 1 < base)
+					continue;
+			}
+
+			if (pcib_alloc_nonisa_ranges(sc, base, limit) == 0) {
+				w->base = base;
+				w->limit = limit;
+				return (0);
+			}
+		}
+		return (ENOSPC);		
+	}
+	
+	wmask = (1ul << w->step) - 1;
+	if (RF_ALIGNMENT(flags) < w->step) {
+		flags &= ~RF_ALIGNMENT_MASK;
+		flags |= RF_ALIGNMENT_LOG2(w->step);
+	}
+	start &= ~wmask;
+	end |= wmask;
+	count = roundup2(count, 1ul << w->step);
+	rid = w->reg;
+	res = bus_alloc_resource(sc->dev, type, &rid, start, end, count,
+	    flags & ~RF_ACTIVE);
+	if (res == NULL)
+		return (ENOSPC);
+	pcib_add_window_resources(w, &res, 1);
+	pcib_activate_window(sc, type);
+	w->base = rman_get_start(res);
+	w->limit = rman_get_end(res);
+	return (0);
+}
+
+/* Try to expand an existing window to the requested base and limit. */
+static int
+pcib_expand_window(struct pcib_softc *sc, struct pcib_window *w, int type,
+    u_long base, u_long limit)
+{
+	struct resource *res;
+	int error, i, force_64k_base;
+
+	KASSERT(base <= w->base && limit >= w->limit,
+	    ("attempting to shrink window"));
+
+	/*
+	 * XXX: pcib_grow_window() doesn't try to do this anyway and
+	 * the error handling for all the edge cases would be tedious.
+	 */
+	KASSERT(limit == w->limit || base == w->base,
+	    ("attempting to grow both ends of a window"));
+
+	/*
+	 * Yet more special handling for requests to expand an I/O
+	 * window behind an ISA-enabled bridge.  Since I/O windows
+	 * have to grow in 0x1000 increments and the end of the 0xffff
+	 * range is an alias, growing a window below 64k will always
+	 * result in allocating new resources and never adjusting an
+	 * existing resource.
+	 */
+	if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE &&
+	    (limit <= 65535 || (base <= 65535 && base != w->base))) {
+		KASSERT(limit == w->limit || limit <= 65535,
+		    ("attempting to grow both ends across 64k ISA alias"));
+
+		if (base != w->base)
+			error = pcib_alloc_nonisa_ranges(sc, base, w->base - 1);
+		else
+			error = pcib_alloc_nonisa_ranges(sc, w->limit + 1,
+			    limit);
+		if (error == 0) {
+			w->base = base;
+			w->limit = limit;
+		}
+		return (error);
+	}
+
+	/*
+	 * Find the existing resource to adjust.  Usually there is only one,
+	 * but for an ISA-enabled bridge we might be growing the I/O window
+	 * above 64k and need to find the existing resource that maps all
+	 * of the area above 64k.
+	 */
+	for (i = 0; i < w->count; i++) {
+		if (rman_get_end(w->res[i]) == w->limit)
+			break;
+	}
+	KASSERT(i != w->count, ("did not find existing resource"));
+	res = w->res[i];
+
+	/*
+	 * Usually the resource we found should match the window's
+	 * existing range.  The one exception is the ISA-enabled case
+	 * mentioned above in which case the resource should start at
+	 * 64k.
+	 */
+	if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE &&
+	    w->base <= 65535) {
+		KASSERT(rman_get_start(res) == 65536,
+		    ("existing resource mismatch"));
+		force_64k_base = 1;
+	} else {
+		KASSERT(w->base == rman_get_start(res),
+		    ("existing resource mismatch"));
+		force_64k_base = 0;
+	}	
+
+	error = bus_adjust_resource(sc->dev, type, res, force_64k_base ?
+	    rman_get_start(res) : base, limit);
+	if (error)
+		return (error);
+
+	/* Add the newly allocated region to the resource manager. */
+	if (w->base != base) {
+		error = rman_manage_region(&w->rman, base, w->base - 1);
+		w->base = base;
+	} else {
+		error = rman_manage_region(&w->rman, w->limit + 1, limit);
+		w->limit = limit;
+	}
+	if (error) {
+		if (bootverbose)
+			device_printf(sc->dev,
+			    "failed to expand %s resource manager\n", w->name);
+		(void)bus_adjust_resource(sc->dev, type, res, force_64k_base ?
+		    rman_get_start(res) : w->base, w->limit);
+	}
+	return (error);
+}
+
 /*
  * Attempt to grow a window to make room for a given resource request.
- * The 'step' parameter is log_2 of the desired I/O window's alignment.
  */
 static int
 pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
     u_long start, u_long end, u_long count, u_int flags)
 {
 	u_long align, start_free, end_free, front, back, wmask;
-	int error, rid;
+	int error;
 
 	/*
 	 * Clamp the desired resource range to the maximum address
 	 * this window supports.  Reject impossible requests.
+	 *
+	 * For I/O port requests behind a bridge with the ISA enable
+	 * bit set, force large allocations to start above 64k.
 	 */
 	if (!w->valid)
 		return (EINVAL);
+	if (sc->bridgectl & PCIB_BCR_ISA_ENABLE && count > 0x100 &&
+	    start < 65536)
+		start = 65536;
 	if (end > w->rman.rm_end)
 		end = w->rman.rm_end;
 	if (start + count - 1 > end || start + count < start)
@@ -849,40 +1222,19 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 	 * aligned space for this resource.
 	 */
 	if (w->res == NULL) {
-		if (RF_ALIGNMENT(flags) < w->step) {
-			flags &= ~RF_ALIGNMENT_MASK;
-			flags |= RF_ALIGNMENT_LOG2(w->step);
-		}
-		start &= ~wmask;
-		end |= wmask;
-		count = roundup2(count, 1ul << w->step);
-		rid = w->reg;
-		w->res = bus_alloc_resource(sc->dev, type, &rid, start, end,
-		    count, flags & ~RF_ACTIVE);
-		if (w->res == NULL) {
+		error = pcib_alloc_new_window(sc, w, type, start, end, count,
+		    flags);
+		if (error) {
 			if (bootverbose)
 				device_printf(sc->dev,
 		    "failed to allocate initial %s window (%#lx-%#lx,%#lx)\n",
 				    w->name, start, end, count);
-			return (ENXIO);
+			return (error);
 		}
 		if (bootverbose)
 			device_printf(sc->dev,
-			    "allocated initial %s window of %#lx-%#lx\n",
-			    w->name, rman_get_start(w->res),
-			    rman_get_end(w->res));
-		error = rman_manage_region(&w->rman, rman_get_start(w->res),
-		    rman_get_end(w->res));
-		if (error) {
-			if (bootverbose)
-				device_printf(sc->dev,
-				    "failed to add initial %s window to rman\n",
-				    w->name);
-			bus_release_resource(sc->dev, type, w->reg, w->res);
-			w->res = NULL;
-			return (error);
-		}
-		pcib_activate_window(sc, type);
+			    "allocated initial %s window of %#jx-%#jx\n",
+			    w->name, (uintmax_t)w->base, (uintmax_t)w->limit);
 		goto updatewin;
 	}
 
@@ -896,6 +1248,11 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 	 * edge of the window, grow from the inner edge of the free
 	 * region.  Otherwise grow from the window boundary.
 	 *
+	 * Growing an I/O window below 64k for a bridge with the ISA
+	 * enable bit doesn't require any special magic as the step
+	 * size of an I/O window (1k) always includes multiple
+	 * non-alias ranges when it is grown in either direction.
+	 *
 	 * XXX: Special case: if w->res is completely empty and the
 	 * request size is larger than w->res, we should find the
 	 * optimal aligned buffer containing w->res and allocate that.
@@ -905,10 +1262,10 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 		    "attempting to grow %s window for (%#lx-%#lx,%#lx)\n",
 		    w->name, start, end, count);
 	align = 1ul << RF_ALIGNMENT(flags);
-	if (start < rman_get_start(w->res)) {
+	if (start < w->base) {
 		if (rman_first_free_region(&w->rman, &start_free, &end_free) !=
-		    0 || start_free != rman_get_start(w->res))
-			end_free = rman_get_start(w->res);
+		    0 || start_free != w->base)
+			end_free = w->base;
 		if (end_free > end)
 			end_free = end + 1;
 
@@ -929,15 +1286,15 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 				printf("\tfront candidate range: %#lx-%#lx\n",
 				    front, end_free);
 			front &= ~wmask;
-			front = rman_get_start(w->res) - front;
+			front = w->base - front;
 		} else
 			front = 0;
 	} else
 		front = 0;
-	if (end > rman_get_end(w->res)) {
+	if (end > w->limit) {
 		if (rman_last_free_region(&w->rman, &start_free, &end_free) !=
-		    0 || end_free != rman_get_end(w->res))
-			start_free = rman_get_end(w->res) + 1;
+		    0 || end_free != w->limit)
+			start_free = w->limit + 1;
 		if (start_free < start)
 			start_free = start;
 
@@ -957,7 +1314,7 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 				printf("\tback candidate range: %#lx-%#lx\n",
 				    start_free, back);
 			back |= wmask;
-			back -= rman_get_end(w->res);
+			back -= w->limit;
 		} else
 			back = 0;
 	} else
@@ -970,16 +1327,14 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 	error = ENOSPC;
 	while (front != 0 || back != 0) {
 		if (front != 0 && (front <= back || back == 0)) {
-			error = bus_adjust_resource(sc->dev, type, w->res,
-			    rman_get_start(w->res) - front,
-			    rman_get_end(w->res));
+			error = pcib_expand_window(sc, w, type, w->base - front,
+			    w->limit);
 			if (error == 0)
 				break;
 			front = 0;
 		} else {
-			error = bus_adjust_resource(sc->dev, type, w->res,
-			    rman_get_start(w->res),
-			    rman_get_end(w->res) + back);
+			error = pcib_expand_window(sc, w, type, w->base,
+			    w->limit + back);
 			if (error == 0)
 				break;
 			back = 0;
@@ -989,32 +1344,11 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 	if (error)
 		return (error);
 	if (bootverbose)
-		device_printf(sc->dev, "grew %s window to %#lx-%#lx\n",
-		    w->name, rman_get_start(w->res), rman_get_end(w->res));
-
-	/* Add the newly allocated region to the resource manager. */
-	if (w->base != rman_get_start(w->res)) {
-		KASSERT(w->limit == rman_get_end(w->res), ("both ends moved"));
-		error = rman_manage_region(&w->rman, rman_get_start(w->res),
-		    w->base - 1);
-	} else {
-		KASSERT(w->limit != rman_get_end(w->res),
-		    ("neither end moved"));
-		error = rman_manage_region(&w->rman, w->limit + 1,
-		    rman_get_end(w->res));
-	}
-	if (error) {
-		if (bootverbose)
-			device_printf(sc->dev,
-			    "failed to expand %s resource manager\n", w->name);
-		bus_adjust_resource(sc->dev, type, w->res, w->base, w->limit);
-		return (error);
-	}
+		device_printf(sc->dev, "grew %s window to %#jx-%#jx\n",
+		    w->name, (uintmax_t)w->base, (uintmax_t)w->limit);
 
 updatewin:
-	/* Save the new window. */
-	w->base = rman_get_start(w->res);
-	w->limit = rman_get_end(w->res);
+	/* Write the new window. */
 	KASSERT((w->base & wmask) == 0, ("start address is not aligned"));
 	KASSERT((w->limit & wmask) == wmask, ("end address is not aligned"));
 	pcib_write_windows(sc, w->mask);
@@ -1050,6 +1384,8 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
 
 	switch (type) {
 	case SYS_RES_IOPORT:
+		if (pcib_is_isa_range(sc, start, end, count))
+			return (NULL);
 		r = pcib_suballoc_resource(sc, &sc->io, child, type, rid, start,
 		    end, count, flags);
 		if (r != NULL || (sc->flags & PCIB_SUBTRACTIVE) != 0)
diff --git a/freebsd/sys/dev/pci/pci_private.h b/freebsd/sys/dev/pci/pci_private.h
index b8e446e..92f36d5 100644
--- a/freebsd/sys/dev/pci/pci_private.h
+++ b/freebsd/sys/dev/pci/pci_private.h
@@ -91,6 +91,8 @@ int		pci_msix_count_method(device_t dev, device_t child);
 struct resource	*pci_alloc_resource(device_t dev, device_t child, 
 		    int type, int *rid, u_long start, u_long end, u_long count,
 		    u_int flags);
+int		pci_release_resource(device_t dev, device_t child, int type,
+		    int rid, struct resource *r);
 int		pci_activate_resource(device_t dev, device_t child, int type,
 		    int rid, struct resource *r);
 int		pci_deactivate_resource(device_t dev, device_t child, int type,
diff --git a/freebsd/sys/dev/pci/pci_user.c b/freebsd/sys/dev/pci/pci_user.c
index 63d64c3..dc22106 100644
--- a/freebsd/sys/dev/pci/pci_user.c
+++ b/freebsd/sys/dev/pci/pci_user.c
@@ -409,6 +409,89 @@ pci_conf_match_old32(struct pci_match_conf_old32 *matches, int num_matches,
 #endif	/* PRE7_COMPAT */
 
 static int
+pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
+{
+	struct pci_vpd_element vpd_element, *vpd_user;
+	struct pcicfg_vpd *vpd;
+	size_t len;
+	int error, i;
+
+	vpd = pci_fetch_vpd_list(dev);
+	if (vpd->vpd_reg == 0 || vpd->vpd_ident == NULL)
+		return (ENXIO);
+
+	/*
+	 * Calculate the amount of space needed in the data buffer.  An
+	 * identifier element is always present followed by the read-only
+	 * and read-write keywords.
+	 */
+	len = sizeof(struct pci_vpd_element) + strlen(vpd->vpd_ident);
+	for (i = 0; i < vpd->vpd_rocnt; i++)
+		len += sizeof(struct pci_vpd_element) + vpd->vpd_ros[i].len;
+	for (i = 0; i < vpd->vpd_wcnt; i++)
+		len += sizeof(struct pci_vpd_element) + vpd->vpd_w[i].len;
+
+	if (lvio->plvi_len == 0) {
+		lvio->plvi_len = len;
+		return (0);
+	}
+	if (lvio->plvi_len < len) {
+		lvio->plvi_len = len;
+		return (ENOMEM);
+	}
+
+	/*
+	 * Copyout the identifier string followed by each keyword and
+	 * value.
+	 */
+	vpd_user = lvio->plvi_data;
+	vpd_element.pve_keyword[0] = '\0';
+	vpd_element.pve_keyword[1] = '\0';
+	vpd_element.pve_flags = PVE_FLAG_IDENT;
+	vpd_element.pve_datalen = strlen(vpd->vpd_ident);
+	error = copyout(&vpd_element, vpd_user, sizeof(vpd_element));
+	if (error)
+		return (error);
+	error = copyout(vpd->vpd_ident, vpd_user->pve_data,
+	    strlen(vpd->vpd_ident));
+	if (error)
+		return (error);
+	vpd_user = PVE_NEXT(vpd_user);
+	vpd_element.pve_flags = 0;
+	for (i = 0; i < vpd->vpd_rocnt; i++) {
+		vpd_element.pve_keyword[0] = vpd->vpd_ros[i].keyword[0];
+		vpd_element.pve_keyword[1] = vpd->vpd_ros[i].keyword[1];
+		vpd_element.pve_datalen = vpd->vpd_ros[i].len;
+		error = copyout(&vpd_element, vpd_user, sizeof(vpd_element));
+		if (error)
+			return (error);
+		error = copyout(vpd->vpd_ros[i].value, vpd_user->pve_data,
+		    vpd->vpd_ros[i].len);
+		if (error)
+			return (error);
+		vpd_user = PVE_NEXT(vpd_user);
+	}
+	vpd_element.pve_flags = PVE_FLAG_RW;
+	for (i = 0; i < vpd->vpd_wcnt; i++) {
+		vpd_element.pve_keyword[0] = vpd->vpd_w[i].keyword[0];
+		vpd_element.pve_keyword[1] = vpd->vpd_w[i].keyword[1];
+		vpd_element.pve_datalen = vpd->vpd_w[i].len;
+		error = copyout(&vpd_element, vpd_user, sizeof(vpd_element));
+		if (error)
+			return (error);
+		error = copyout(vpd->vpd_w[i].value, vpd_user->pve_data,
+		    vpd->vpd_w[i].len);
+		if (error)
+			return (error);
+		vpd_user = PVE_NEXT(vpd_user);
+	}
+	KASSERT((char *)vpd_user - (char *)lvio->plvi_data == len,
+	    ("length mismatch"));
+	lvio->plvi_len = len;
+	return (0);
+}
+
+static int
 pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
 {
 	device_t pcidev, brdev;
@@ -419,6 +502,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
 	struct pci_devinfo *dinfo;
 	struct pci_io *io;
 	struct pci_bar_io *bio;
+	struct pci_list_vpd_io *lvio;
 	struct pci_match_conf *pattern_buf;
 	struct pci_map *pm;
 	size_t confsz, iolen, pbufsz;
@@ -435,19 +519,29 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
 	struct pci_match_conf_old *pattern_buf_old = NULL;
 
 	io_old = NULL;
+#endif
 
-	if (!(flag & FWRITE) && cmd != PCIOCGETBAR &&
-	    cmd != PCIOCGETCONF && cmd != PCIOCGETCONF_OLD)
-		return EPERM;
-#else
-	if (!(flag & FWRITE) && cmd != PCIOCGETBAR && cmd != PCIOCGETCONF)
-		return EPERM;
+	if (!(flag & FWRITE)) {
+		switch (cmd) {
+#ifdef PRE7_COMPAT
+#ifdef COMPAT_FREEBSD32
+		case PCIOCGETCONF_OLD32:
 #endif
+		case PCIOCGETCONF_OLD:
+#endif
+		case PCIOCGETCONF:
+		case PCIOCGETBAR:
+		case PCIOCLISTVPD:
+			break;
+		default:
+			return (EPERM);
+		}
+	}
 
-	switch(cmd) {
+	switch (cmd) {
 #ifdef PRE7_COMPAT
 #ifdef COMPAT_FREEBSD32
-       case PCIOCGETCONF_OLD32:
+	case PCIOCGETCONF_OLD32:
                cio32 = (struct pci_conf_io32 *)data;
                cio = malloc(sizeof(struct pci_conf_io), M_TEMP, M_WAITOK);
                cio->pat_buf_len = cio32->pat_buf_len;
@@ -468,7 +562,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
 		cio = (struct pci_conf_io *)data;
 	}
 
-	switch(cmd) {
+	switch (cmd) {
 #ifdef PRE7_COMPAT
 #ifdef COMPAT_FREEBSD32
 	case PCIOCGETCONF_OLD32:
@@ -914,6 +1008,22 @@ getconfexit:
 		else
 			error = ENODEV;
 		break;
+	case PCIOCLISTVPD:
+		lvio = (struct pci_list_vpd_io *)data;
+
+		/*
+		 * Assume that the user-level bus number is
+		 * in fact the physical PCI bus number.
+		 */
+		pcidev = pci_find_dbsf(lvio->plvi_sel.pc_domain,
+		    lvio->plvi_sel.pc_bus, lvio->plvi_sel.pc_dev,
+		    lvio->plvi_sel.pc_func);
+		if (pcidev == NULL) {
+			error = ENODEV;
+			break;
+		}
+		error = pci_list_vpd(pcidev, lvio);
+		break;
 	default:
 		error = ENOTTY;
 		break;
diff --git a/freebsd/sys/dev/pci/pcib_private.h b/freebsd/sys/dev/pci/pcib_private.h
index 79135af..e9d4c4b 100644
--- a/freebsd/sys/dev/pci/pcib_private.h
+++ b/freebsd/sys/dev/pci/pcib_private.h
@@ -73,7 +73,8 @@ struct pcib_window {
 	pci_addr_t	base;		/* base address */
 	pci_addr_t	limit;		/* topmost address */
 	struct rman	rman;
-	struct resource *res;
+	struct resource **res;
+	int		count;		/* size of 'res' array */
 	int		reg;		/* resource id from parent */
 	int		valid;
 	int		mask;		/* WIN_* bitmask of this window */
diff --git a/freebsd/sys/dev/pci/pcireg.h b/freebsd/sys/dev/pci/pcireg.h
index ef35135..f2d1ccb 100644
--- a/freebsd/sys/dev/pci/pcireg.h
+++ b/freebsd/sys/dev/pci/pcireg.h
@@ -752,8 +752,17 @@
 #define	PCIEM_SLOT_STA_EIS		0x0080
 #define	PCIEM_SLOT_STA_DLLSC		0x0100
 #define	PCIER_ROOT_CTL		0x1c
+#define	PCIEM_ROOT_CTL_SERR_CORR	0x0001
+#define	PCIEM_ROOT_CTL_SERR_NONFATAL	0x0002
+#define	PCIEM_ROOT_CTL_SERR_FATAL	0x0004
+#define	PCIEM_ROOT_CTL_PME		0x0008
+#define	PCIEM_ROOT_CTL_CRS_VIS		0x0010
 #define	PCIER_ROOT_CAP		0x1e
+#define	PCIEM_ROOT_CAP_CRS_VIS		0x0001
 #define	PCIER_ROOT_STA		0x20
+#define	PCIEM_ROOT_STA_PME_REQID_MASK	0x0000ffff
+#define	PCIEM_ROOT_STA_PME_STATUS	0x00010000
+#define	PCIEM_ROOT_STA_PME_PEND		0x00020000
 #define	PCIER_DEVICE_CAP2	0x24
 #define	PCIER_DEVICE_CTL2	0x28
 #define	PCIEM_CTL2_COMP_TIMEOUT_VAL	0x000f
diff --git a/freebsd/sys/dev/pci/pcivar.h b/freebsd/sys/dev/pci/pcivar.h
index 84e7c87..a951ca6 100644
--- a/freebsd/sys/dev/pci/pcivar.h
+++ b/freebsd/sys/dev/pci/pcivar.h
@@ -57,6 +57,7 @@ struct pci_map {
 struct vpd_readonly {
     char	keyword[2];
     char	*value;
+    int		len;
 };
 
 struct vpd_write {
@@ -491,5 +492,13 @@ extern uint32_t	pci_generation;
 
 struct pci_map *pci_find_bar(device_t dev, int reg);
 int	pci_bar_enabled(device_t dev, struct pci_map *pm);
+struct pcicfg_vpd *pci_fetch_vpd_list(device_t dev);
+
+#define	VGA_PCI_BIOS_SHADOW_ADDR	0xC0000
+#define	VGA_PCI_BIOS_SHADOW_SIZE	131072
+
+int	vga_pci_is_boot_display(device_t dev);
+void *	vga_pci_map_bios(device_t dev, size_t *size);
+void	vga_pci_unmap_bios(device_t dev, void *bios);
 
 #endif /* _PCIVAR_H_ */
diff --git a/freebsd/sys/dev/re/if_re.c b/freebsd/sys/dev/re/if_re.c
index cde6bce..9975137 100644
--- a/freebsd/sys/dev/re/if_re.c
+++ b/freebsd/sys/dev/re/if_re.c
@@ -183,7 +183,7 @@ static const struct rl_type re_devs[] = {
 	{ RT_VENDORID, RT_DEVICEID_8101E, 0,
 	    "RealTek 810xE PCIe 10/100baseTX" },
 	{ RT_VENDORID, RT_DEVICEID_8168, 0,
-	    "RealTek 8168/8111 B/C/CP/D/DP/E/F PCIe Gigabit Ethernet" },
+	    "RealTek 8168/8111 B/C/CP/D/DP/E/F/G PCIe Gigabit Ethernet" },
 	{ RT_VENDORID, RT_DEVICEID_8169, 0,
 	    "RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" },
 	{ RT_VENDORID, RT_DEVICEID_8169SC, 0,
@@ -225,6 +225,7 @@ static const struct rl_hwrev re_hwrevs[] = {
 	{ RL_HWREV_8402, RL_8169, "8402", RL_MTU },
 	{ RL_HWREV_8105E, RL_8169, "8105E", RL_MTU },
 	{ RL_HWREV_8105E_SPIN1, RL_8169, "8105E", RL_MTU },
+	{ RL_HWREV_8106E, RL_8169, "8106E", RL_MTU },
 	{ RL_HWREV_8168B_SPIN2, RL_8169, "8168", RL_JUMBO_MTU },
 	{ RL_HWREV_8168B_SPIN3, RL_8169, "8168", RL_JUMBO_MTU },
 	{ RL_HWREV_8168C, RL_8169, "8168C/8111C", RL_JUMBO_MTU_6K },
@@ -234,8 +235,12 @@ static const struct rl_hwrev re_hwrevs[] = {
 	{ RL_HWREV_8168DP, RL_8169, "8168DP/8111DP", RL_JUMBO_MTU_9K },
 	{ RL_HWREV_8168E, RL_8169, "8168E/8111E", RL_JUMBO_MTU_9K},
 	{ RL_HWREV_8168E_VL, RL_8169, "8168E/8111E-VL", RL_JUMBO_MTU_6K},
+	{ RL_HWREV_8168EP, RL_8169, "8168EP/8111EP", RL_JUMBO_MTU_9K},
 	{ RL_HWREV_8168F, RL_8169, "8168F/8111F", RL_JUMBO_MTU_9K},
+	{ RL_HWREV_8168G, RL_8169, "8168G/8111G", RL_JUMBO_MTU_9K},
+	{ RL_HWREV_8168GU, RL_8169, "8168GU/8111GU", RL_JUMBO_MTU_9K},
 	{ RL_HWREV_8411, RL_8169, "8411", RL_JUMBO_MTU_9K},
+	{ RL_HWREV_8411B, RL_8169, "8411B", RL_JUMBO_MTU_9K},
 	{ 0, 0, NULL, 0 }
 };
 
@@ -652,6 +657,10 @@ re_set_rxmode(struct rl_softc *sc)
 	ifp = sc->rl_ifp;
 
 	rxfilt = RL_RXCFG_CONFIG | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_BROAD;
+	if ((sc->rl_flags & RL_FLAG_EARLYOFF) != 0)
+		rxfilt |= RL_RXCFG_EARLYOFF;
+	else if ((sc->rl_flags & RL_FLAG_EARLYOFFV2) != 0)
+		rxfilt |= RL_RXCFG_EARLYOFFV2;
 
 	if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
 		if (ifp->if_flags & IFF_PROMISC)
@@ -1261,7 +1270,7 @@ re_attach(device_t dev)
 		msic = 0;
 	/* Prefer MSI-X to MSI. */
 	if (msixc > 0) {
-		msixc = 1;
+		msixc = RL_MSI_MESSAGES;
 		rid = PCIR_BAR(4);
 		sc->rl_res_pba = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
 		    &rid, RF_ACTIVE);
@@ -1271,7 +1280,7 @@ re_attach(device_t dev)
 		}
 		if (sc->rl_res_pba != NULL &&
 		    pci_alloc_msix(dev, &msixc) == 0) {
-			if (msixc == 1) {
+			if (msixc == RL_MSI_MESSAGES) {
 				device_printf(dev, "Using %d MSI-X message\n",
 				    msixc);
 				sc->rl_flags |= RL_FLAG_MSIX;
@@ -1288,7 +1297,7 @@ re_attach(device_t dev)
 	}
 	/* Prefer MSI to INTx. */
 	if (msixc == 0 && msic > 0) {
-		msic = 1;
+		msic = RL_MSI_MESSAGES;
 		if (pci_alloc_msi(dev, &msic) == 0) {
 			if (msic == RL_MSI_MESSAGES) {
 				device_printf(dev, "Using %d MSI message\n",
@@ -1369,10 +1378,11 @@ re_attach(device_t dev)
 		break;
 	default:
 		device_printf(dev, "Chip rev. 0x%08x\n", hwrev & 0x7c800000);
+		sc->rl_macrev = hwrev & 0x00700000;
 		hwrev &= RL_TXCFG_HWREV;
 		break;
 	}
-	device_printf(dev, "MAC rev. 0x%08x\n", hwrev & 0x00700000);
+	device_printf(dev, "MAC rev. 0x%08x\n", sc->rl_macrev);
 	while (hw_rev->rl_desc != NULL) {
 		if (hw_rev->rl_rev == hwrev) {
 			sc->rl_type = hw_rev->rl_type;
@@ -1410,6 +1420,7 @@ re_attach(device_t dev)
 	case RL_HWREV_8401E:
 	case RL_HWREV_8105E:
 	case RL_HWREV_8105E_SPIN1:
+	case RL_HWREV_8106E:
 		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM |
 		    RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT |
 		    RL_FLAG_FASTETHER | RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD;
@@ -1431,7 +1442,7 @@ re_attach(device_t dev)
 		sc->rl_flags |= RL_FLAG_MACSLEEP;
 		/* FALLTHROUGH */
 	case RL_HWREV_8168C:
-		if ((hwrev & 0x00700000) == 0x00200000)
+		if (sc->rl_macrev == 0x00200000)
 			sc->rl_flags |= RL_FLAG_MACSLEEP;
 		/* FALLTHROUGH */
 	case RL_HWREV_8168CP:
@@ -1458,12 +1469,35 @@ re_attach(device_t dev)
 		break;
 	case RL_HWREV_8168E_VL:
 	case RL_HWREV_8168F:
+		sc->rl_flags |= RL_FLAG_EARLYOFF;
+		/* FALLTHROUGH */
 	case RL_HWREV_8411:
 		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
 		    RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
 		    RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 |
 		    RL_FLAG_CMDSTOP_WAIT_TXQ | RL_FLAG_WOL_MANLINK;
 		break;
+	case RL_HWREV_8168EP:
+	case RL_HWREV_8168G:
+	case RL_HWREV_8411B:
+		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
+		    RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
+		    RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 |
+		    RL_FLAG_CMDSTOP_WAIT_TXQ | RL_FLAG_WOL_MANLINK |
+		    RL_FLAG_EARLYOFFV2 | RL_FLAG_RXDV_GATED;
+		break;
+	case RL_HWREV_8168GU:
+		if (pci_get_device(dev) == RT_DEVICEID_8101E) {
+			/* RTL8106EUS */
+			sc->rl_flags |= RL_FLAG_FASTETHER;
+		} else
+			sc->rl_flags |= RL_FLAG_JUMBOV2 | RL_FLAG_WOL_MANLINK;
+
+		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
+		    RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
+		    RL_FLAG_AUTOPAD | RL_FLAG_CMDSTOP_WAIT_TXQ |
+		    RL_FLAG_EARLYOFFV2 | RL_FLAG_RXDV_GATED;
+		break;
 	case RL_HWREV_8169_8110SB:
 	case RL_HWREV_8169_8110SBL:
 	case RL_HWREV_8169_8110SC:
@@ -1586,16 +1620,18 @@ re_attach(device_t dev)
 	ifp->if_start = re_start;
 	/*
 	 * RTL8168/8111C generates wrong IP checksummed frame if the
-	 * packet has IP options so disable TX IP checksum offloading.
+	 * packet has IP options so disable TX checksum offloading.
 	 */
 	if (sc->rl_hwrev->rl_rev == RL_HWREV_8168C ||
 	    sc->rl_hwrev->rl_rev == RL_HWREV_8168C_SPIN2 ||
-	    sc->rl_hwrev->rl_rev == RL_HWREV_8168CP)
-		ifp->if_hwassist = CSUM_TCP | CSUM_UDP;
-	else
+	    sc->rl_hwrev->rl_rev == RL_HWREV_8168CP) {
+		ifp->if_hwassist = 0;
+		ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TSO4;
+	} else {
 		ifp->if_hwassist = CSUM_IP | CSUM_TCP | CSUM_UDP;
+		ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4;
+	}
 	ifp->if_hwassist |= CSUM_TSO;
-	ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4;
 	ifp->if_capenable = ifp->if_capabilities;
 	ifp->if_init = re_init;
 	IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN);
@@ -2114,8 +2150,7 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
 
 	ifp = sc->rl_ifp;
 #ifdef DEV_NETMAP
-	if (netmap_rx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT),
-	    &rx_npkts))
+	if (netmap_rx_irq(ifp, 0, &rx_npkts))
 		return 0;
 #endif /* DEV_NETMAP */
 	if (ifp->if_mtu > RL_MTU && (sc->rl_flags & RL_FLAG_JUMBOV2) != 0)
@@ -2360,7 +2395,7 @@ re_txeof(struct rl_softc *sc)
 
 	ifp = sc->rl_ifp;
 #ifdef DEV_NETMAP
-	if (netmap_tx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
+	if (netmap_tx_irq(ifp, 0))
 		return;
 #endif /* DEV_NETMAP */
 	/* Invalidate the TX descriptor list */
@@ -3151,6 +3186,10 @@ re_init_locked(struct rl_softc *sc)
 	CSR_WRITE_4(sc, RL_TXLIST_ADDR_LO,
 	    RL_ADDR_LO(sc->rl_ldata.rl_tx_list_addr));
 
+	if ((sc->rl_flags & RL_FLAG_RXDV_GATED) != 0)
+		CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) &
+		    ~0x00080000);
+
 	/*
 	 * Enable transmit and receive.
 	 */
@@ -3328,13 +3367,14 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 	struct rl_softc		*sc = ifp->if_softc;
 	struct ifreq		*ifr = (struct ifreq *) data;
 	struct mii_data		*mii;
-	uint32_t		rev;
 	int			error = 0;
 
 	switch (command) {
 	case SIOCSIFMTU:
 		if (ifr->ifr_mtu < ETHERMIN ||
-		    ifr->ifr_mtu > sc->rl_hwrev->rl_max_mtu) {
+		    ifr->ifr_mtu > sc->rl_hwrev->rl_max_mtu ||
+		    ((sc->rl_flags & RL_FLAG_FASTETHER) != 0 &&
+		    ifr->ifr_mtu > RL_MTU)) {
 			error = EINVAL;
 			break;
 		}
@@ -3415,15 +3455,9 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 		if ((mask & IFCAP_TXCSUM) != 0 &&
 		    (ifp->if_capabilities & IFCAP_TXCSUM) != 0) {
 			ifp->if_capenable ^= IFCAP_TXCSUM;
-			if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) {
-				rev = sc->rl_hwrev->rl_rev;
-				if (rev == RL_HWREV_8168C ||
-				    rev == RL_HWREV_8168C_SPIN2 ||
-				    rev == RL_HWREV_8168CP)
-					ifp->if_hwassist |= CSUM_TCP | CSUM_UDP;
-				else
-					ifp->if_hwassist |= RE_CSUM_FEATURES;
-			} else
+			if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
+				ifp->if_hwassist |= RE_CSUM_FEATURES;
+			else
 				ifp->if_hwassist &= ~RE_CSUM_FEATURES;
 			reinit = 1;
 		}
diff --git a/freebsd/sys/dev/usb/controller/ehci.c b/freebsd/sys/dev/usb/controller/ehci.c
index 456aff6..528e4a0 100644
--- a/freebsd/sys/dev/usb/controller/ehci.c
+++ b/freebsd/sys/dev/usb/controller/ehci.c
@@ -258,7 +258,7 @@ ehci_init_sub(struct ehci_softc *sc)
 		DPRINTF("HCC uses 64-bit structures\n");
 
 		/* MUST clear segment register if 64 bit capable */
-		EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
+		EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
 	}
 
 	usbd_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
@@ -1197,9 +1197,16 @@ ehci_non_isoc_done_sub(struct usb_xfer *xfer)
 		    (status & EHCI_QTD_PINGSTATE) ? "[PING]" : "");
 	}
 #endif
-
-	return ((status & EHCI_QTD_HALTED) ?
-	    USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
+	if (status & EHCI_QTD_HALTED) {
+		if ((xfer->xroot->udev->parent_hs_hub != NULL) ||
+		    (xfer->xroot->udev->address != 0)) {
+			/* try to separate I/O errors from STALL */
+			if (EHCI_QTD_GET_CERR(status) == 0)
+				return (USB_ERR_IOERROR);
+		}
+		return (USB_ERR_STALLED);
+	}
+	return (USB_ERR_NORMAL_COMPLETION);
 }
 
 static void
@@ -1653,12 +1660,17 @@ restart:
 			}
 			td->len = 0;
 
+			/* properly reset reserved fields */
 			td->qtd_buffer[0] = 0;
-			td->qtd_buffer_hi[0] = 0;
-
 			td->qtd_buffer[1] = 0;
+			td->qtd_buffer[2] = 0;
+			td->qtd_buffer[3] = 0;
+			td->qtd_buffer[4] = 0;
+			td->qtd_buffer_hi[0] = 0;
 			td->qtd_buffer_hi[1] = 0;
-
+			td->qtd_buffer_hi[2] = 0;
+			td->qtd_buffer_hi[3] = 0;
+			td->qtd_buffer_hi[4] = 0;
 		} else {
 
 			uint8_t x;
@@ -1713,6 +1725,12 @@ restart:
 			    htohc32(temp->sc,
 			    buf_res.physaddr & (~0xFFF));
 			td->qtd_buffer_hi[x] = 0;
+
+			/* properly reset reserved fields */
+			while (++x < EHCI_QTD_NBUFFERS) {
+				td->qtd_buffer[x] = 0;
+				td->qtd_buffer_hi[x] = 0;
+			}
 		}
 
 		if (td_next) {
@@ -2000,6 +2018,18 @@ ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last)
 	qh->qh_qtd.qtd_altnext =
 	    htohc32(temp.sc, EHCI_LINK_TERMINATE);
 
+	/* properly reset reserved fields */
+	qh->qh_qtd.qtd_buffer[0] = 0;
+	qh->qh_qtd.qtd_buffer[1] = 0;
+	qh->qh_qtd.qtd_buffer[2] = 0;
+	qh->qh_qtd.qtd_buffer[3] = 0;
+	qh->qh_qtd.qtd_buffer[4] = 0;
+	qh->qh_qtd.qtd_buffer_hi[0] = 0;
+	qh->qh_qtd.qtd_buffer_hi[1] = 0;
+	qh->qh_qtd.qtd_buffer_hi[2] = 0;
+	qh->qh_qtd.qtd_buffer_hi[3] = 0;
+	qh->qh_qtd.qtd_buffer_hi[4] = 0;
+
 	usb_pc_cpu_flush(qh->page_cache);
 
 	if (xfer->xroot->udev->flags.self_suspended == 0) {
@@ -2230,10 +2260,26 @@ ehci_device_bulk_enter(struct usb_xfer *xfer)
 }
 
 static void
+ehci_doorbell_async(struct ehci_softc *sc)
+{
+	uint32_t temp;
+
+	/*
+	 * XXX Performance quirk: Some Host Controllers have a too low
+	 * interrupt rate. Issue an IAAD to stimulate the Host
+	 * Controller after queueing the BULK transfer.
+	 *
+	 * XXX Force the host controller to refresh any QH caches.
+	 */
+	temp = EOREAD4(sc, EHCI_USBCMD);
+	if (!(temp & EHCI_CMD_IAAD))
+		EOWRITE4(sc, EHCI_USBCMD, temp | EHCI_CMD_IAAD);
+}
+
+static void
 ehci_device_bulk_start(struct usb_xfer *xfer)
 {
 	ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-	uint32_t temp;
 
 	/* setup TD's and QH */
 	ehci_setup_standard_chain(xfer, &sc->sc_async_p_last);
@@ -2248,13 +2294,7 @@ ehci_device_bulk_start(struct usb_xfer *xfer)
 	if (sc->sc_flags & EHCI_SCFLG_IAADBUG)
 		return;
 
-	/* XXX Performance quirk: Some Host Controllers have a too low
-	 * interrupt rate. Issue an IAAD to stimulate the Host
-	 * Controller after queueing the BULK transfer.
-	 */
-	temp = EOREAD4(sc, EHCI_USBCMD);
-	if (!(temp & EHCI_CMD_IAAD))
-		EOWRITE4(sc, EHCI_USBCMD, temp | EHCI_CMD_IAAD);
+	ehci_doorbell_async(sc);
 }
 
 struct usb_pipe_methods ehci_device_bulk_methods =
@@ -3707,10 +3747,6 @@ ehci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
 	    edesc->bEndpointAddress, udev->flags.usb_mode,
 	    sc->sc_addr);
 
-	if (udev->flags.usb_mode != USB_MODE_HOST) {
-		/* not supported */
-		return;
-	}
 	if (udev->device_index != sc->sc_addr) {
 
 		if ((udev->speed != USB_SPEED_HIGH) &&
@@ -3754,7 +3790,7 @@ ehci_get_dma_delay(struct usb_device *udev, uint32_t *pus)
 	 * Wait until the hardware has finished any possible use of
 	 * the transfer descriptor(s) and QH
 	 */
-	*pus = (188);			/* microseconds */
+	*pus = (1125);			/* microseconds */
 }
 
 static void
@@ -3875,6 +3911,41 @@ ehci_set_hw_power(struct usb_bus *bus)
 	return;
 }
 
+static void
+ehci_start_dma_delay_second(struct usb_xfer *xfer)
+{
+	struct ehci_softc *sc = EHCI_BUS2SC(xfer->xroot->bus);
+
+	DPRINTF("\n");
+
+	/* trigger doorbell */
+	ehci_doorbell_async(sc);
+
+	/* give the doorbell 4ms */
+	usbd_transfer_timeout_ms(xfer,
+	    (void (*)(void *))&usb_dma_delay_done_cb, 4);
+}
+
+/*
+ * Ring the doorbell twice before freeing any DMA descriptors. Some host
+ * controllers apparently cache the QH descriptors and need a message
+ * that the cache needs to be discarded.
+ */
+static void
+ehci_start_dma_delay(struct usb_xfer *xfer)
+{
+	struct ehci_softc *sc = EHCI_BUS2SC(xfer->xroot->bus);
+
+	DPRINTF("\n");
+
+	/* trigger doorbell */
+	ehci_doorbell_async(sc);
+
+	/* give the doorbell 4ms */
+	usbd_transfer_timeout_ms(xfer,
+	    (void (*)(void *))&ehci_start_dma_delay_second, 4);
+}
+
 struct usb_bus_methods ehci_bus_methods =
 {
 	.endpoint_init = ehci_ep_init,
@@ -3887,4 +3958,5 @@ struct usb_bus_methods ehci_bus_methods =
 	.set_hw_power_sleep = ehci_set_hw_power_sleep,
 	.roothub_exec = ehci_roothub_exec,
 	.xfer_poll = ehci_do_poll,
+	.start_dma_delay = ehci_start_dma_delay,
 };
diff --git a/freebsd/sys/dev/usb/controller/ohci.c b/freebsd/sys/dev/usb/controller/ohci.c
index 42129a8..05c5e19 100644
--- a/freebsd/sys/dev/usb/controller/ohci.c
+++ b/freebsd/sys/dev/usb/controller/ohci.c
@@ -2316,6 +2316,7 @@ ohci_roothub_exec(struct usb_device *udev,
 		}
 		v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
 		DPRINTFN(9, "port status=0x%04x\n", v);
+		v &= ~UPS_PORT_MODE_DEVICE;	/* force host mode */
 		USETW(sc->sc_hub_desc.ps.wPortStatus, v);
 		USETW(sc->sc_hub_desc.ps.wPortChange, v >> 16);
 		len = sizeof(sc->sc_hub_desc.ps);
@@ -2552,10 +2553,6 @@ ohci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
 	    edesc->bEndpointAddress, udev->flags.usb_mode,
 	    sc->sc_addr);
 
-	if (udev->flags.usb_mode != USB_MODE_HOST) {
-		/* not supported */
-		return;
-	}
 	if (udev->device_index != sc->sc_addr) {
 		switch (edesc->bmAttributes & UE_XFERTYPE) {
 		case UE_CONTROL:
diff --git a/freebsd/sys/dev/usb/controller/usb_controller.c b/freebsd/sys/dev/usb/controller/usb_controller.c
index 37f7936..c0fda65 100644
--- a/freebsd/sys/dev/usb/controller/usb_controller.c
+++ b/freebsd/sys/dev/usb/controller/usb_controller.c
@@ -288,6 +288,28 @@ usb_resume(device_t dev)
 }
 
 /*------------------------------------------------------------------------*
+ *	usb_bus_reset_async_locked
+ *------------------------------------------------------------------------*/
+void
+usb_bus_reset_async_locked(struct usb_bus *bus)
+{
+	USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
+
+	DPRINTF("\n");
+
+	if (bus->reset_msg[0].hdr.pm_qentry.tqe_prev != NULL ||
+	    bus->reset_msg[1].hdr.pm_qentry.tqe_prev != NULL) {
+		DPRINTF("Reset already pending\n");
+		return;
+	}
+
+	device_printf(bus->parent, "Resetting controller\n");
+
+	usb_proc_msignal(&bus->explore_proc,
+	    &bus->reset_msg[0], &bus->reset_msg[1]);
+}
+
+/*------------------------------------------------------------------------*
  *	usb_shutdown
  *------------------------------------------------------------------------*/
 static int
@@ -338,7 +360,13 @@ usb_bus_explore(struct usb_proc_msg *pm)
 	if (bus->no_explore != 0)
 		return;
 
-	if (udev && udev->hub) {
+	if (udev != NULL) {
+		USB_BUS_UNLOCK(bus);
+		uhub_explore_handle_re_enumerate(udev);
+		USB_BUS_LOCK(bus);
+	}
+
+	if (udev != NULL && udev->hub != NULL) {
 
 		if (bus->do_probe) {
 			bus->do_probe = 0;
@@ -411,7 +439,7 @@ usb_bus_detach(struct usb_proc_msg *pm)
 /*------------------------------------------------------------------------*
  *	usb_bus_suspend
  *
- * This function is used to suspend the USB contoller.
+ * This function is used to suspend the USB controller.
  *------------------------------------------------------------------------*/
 static void
 usb_bus_suspend(struct usb_proc_msg *pm)
@@ -421,6 +449,8 @@ usb_bus_suspend(struct usb_proc_msg *pm)
 	usb_error_t err;
 	uint8_t do_unlock;
 
+	DPRINTF("\n");
+
 	bus = ((struct usb_bus_msg *)pm)->bus;
 	udev = bus->devices[USB_ROOT_HUB_ADDR];
 
@@ -466,7 +496,7 @@ usb_bus_suspend(struct usb_proc_msg *pm)
 /*------------------------------------------------------------------------*
  *	usb_bus_resume
  *
- * This function is used to resume the USB contoller.
+ * This function is used to resume the USB controller.
  *------------------------------------------------------------------------*/
 static void
 usb_bus_resume(struct usb_proc_msg *pm)
@@ -476,6 +506,8 @@ usb_bus_resume(struct usb_proc_msg *pm)
 	usb_error_t err;
 	uint8_t do_unlock;
 
+	DPRINTF("\n");
+
 	bus = ((struct usb_bus_msg *)pm)->bus;
 	udev = bus->devices[USB_ROOT_HUB_ADDR];
 
@@ -525,9 +557,31 @@ usb_bus_resume(struct usb_proc_msg *pm)
 }
 
 /*------------------------------------------------------------------------*
+ *	usb_bus_reset
+ *
+ * This function is used to reset the USB controller.
+ *------------------------------------------------------------------------*/
+static void
+usb_bus_reset(struct usb_proc_msg *pm)
+{
+	struct usb_bus *bus;
+
+	DPRINTF("\n");
+
+	bus = ((struct usb_bus_msg *)pm)->bus;
+
+	if (bus->bdev == NULL || bus->no_explore != 0)
+		return;
+
+	/* a suspend and resume will reset the USB controller */
+	usb_bus_suspend(pm);
+	usb_bus_resume(pm);
+}
+
+/*------------------------------------------------------------------------*
  *	usb_bus_shutdown
  *
- * This function is used to shutdown the USB contoller.
+ * This function is used to shutdown the USB controller.
  *------------------------------------------------------------------------*/
 static void
 usb_bus_shutdown(struct usb_proc_msg *pm)
@@ -740,6 +794,11 @@ usb_attach_sub(device_t dev, struct usb_bus *bus)
 	bus->resume_msg[1].hdr.pm_callback = &usb_bus_resume;
 	bus->resume_msg[1].bus = bus;
 
+	bus->reset_msg[0].hdr.pm_callback = &usb_bus_reset;
+	bus->reset_msg[0].bus = bus;
+	bus->reset_msg[1].hdr.pm_callback = &usb_bus_reset;
+	bus->reset_msg[1].bus = bus;
+
 	bus->shutdown_msg[0].hdr.pm_callback = &usb_bus_shutdown;
 	bus->shutdown_msg[0].bus = bus;
 	bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown;
diff --git a/freebsd/sys/dev/usb/controller/xhcireg.h b/freebsd/sys/dev/usb/controller/xhcireg.h
index 85d989a..bd1d635 100644
--- a/freebsd/sys/dev/usb/controller/xhcireg.h
+++ b/freebsd/sys/dev/usb/controller/xhcireg.h
@@ -166,7 +166,8 @@
 #define	XHCI_IMOD_IVAL_SET(x)	(((x) & 0xFFFF) << 0)	/* 250ns unit */
 #define	XHCI_IMOD_ICNT_GET(x)	(((x) >> 16) & 0xFFFF)	/* 250ns unit */
 #define	XHCI_IMOD_ICNT_SET(x)	(((x) & 0xFFFF) << 16)	/* 250ns unit */
-#define	XHCI_IMOD_DEFAULT	0x000003E8U	/* 8000 IRQ/second */
+#define	XHCI_IMOD_DEFAULT	0x000001F4U	/* 8000 IRQs/second */
+#define	XHCI_IMOD_DEFAULT_LP 	0x000003F8U	/* 4000 IRQs/second - LynxPoint */
 #define	XHCI_ERSTSZ(n)		(0x0028 + (0x20 * (n)))	/* XHCI event ring segment table size */
 #define	XHCI_ERSTS_GET(x)	((x) & 0xFFFF)
 #define	XHCI_ERSTS_SET(x)	((x) & 0xFFFF)
diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.c b/freebsd/sys/dev/usb/quirk/usb_quirk.c
index 9042c16..2f7ea79 100644
--- a/freebsd/sys/dev/usb/quirk/usb_quirk.c
+++ b/freebsd/sys/dev/usb/quirk/usb_quirk.c
@@ -95,6 +95,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	USB_QUIRK(TELEX, MIC1, 0x009, 0x009, UQ_AU_NO_FRAC),
 	USB_QUIRK(SILICONPORTALS, YAPPHONE, 0x100, 0x100, UQ_AU_INP_ASYNC),
 	USB_QUIRK(LOGITECH, UN53B, 0x0000, 0xffff, UQ_NO_STRINGS),
+	USB_QUIRK(REALTEK, RTL8196EU, 0x0000, 0xffff, UQ_CFG_INDEX_1),
 	USB_QUIRK(ELSA, MODEM1, 0x0000, 0xffff, UQ_CFG_INDEX_1),
 	USB_QUIRK(PLANEX2, MZKUE150N, 0x0000, 0xffff, UQ_CFG_INDEX_1),
 	/* Quirks for printer devices */
@@ -114,6 +115,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	USB_QUIRK(ITUNERNET, USBLCD2X20, 0x0000, 0xffff, UQ_HID_IGNORE),
 	USB_QUIRK(ITUNERNET, USBLCD4X20, 0x0000, 0xffff, UQ_HID_IGNORE),
 	USB_QUIRK(LIEBERT, POWERSURE_PXT, 0x0000, 0xffff, UQ_HID_IGNORE),
+	USB_QUIRK(LIEBERT2, PSI1000, 0x0000, 0xffff, UQ_HID_IGNORE),
 	USB_QUIRK(MGE, UPS1, 0x0000, 0xffff, UQ_HID_IGNORE),
 	USB_QUIRK(MGE, UPS2, 0x0000, 0xffff, UQ_HID_IGNORE),
 	USB_QUIRK(APPLE, IPHONE, 0x0000, 0xffff, UQ_HID_IGNORE),
@@ -165,6 +167,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
 	USB_QUIRK(ASAHIOPTICAL, OPTIO330, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(ATP, EUSB, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 	USB_QUIRK(BELKIN, USB2SCSI, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 	    UQ_MSC_FORCE_PROTO_SCSI),
 	USB_QUIRK(CASIO, QV_DIGICAM, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
@@ -235,6 +238,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	USB_QUIRK(JMICRON, JM20337, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 	    UQ_MSC_FORCE_PROTO_SCSI,
 	    UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(KINGSTON, HYPERX3_0, 0x0000, 0xffff, UQ_MSC_NO_INQUIRY),
 	USB_QUIRK(KYOCERA, FINECAM_L3, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
 	USB_QUIRK(KYOCERA, FINECAM_S3X, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
@@ -287,6 +291,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE),
 	USB_QUIRK(NETCHIP, CLIK_40, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_ATAPI,
 	    UQ_MSC_NO_INQUIRY),
+	USB_QUIRK(NETCHIP, POCKETBOOK, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 	USB_QUIRK(NIKON, D300, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 	    UQ_MSC_FORCE_PROTO_SCSI),
 	USB_QUIRK(OLYMPUS, C1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
@@ -333,6 +338,9 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	USB_QUIRK(SANDISK, SDDR12, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1,
 	    UQ_MSC_NO_GETMAXLUN),
+	USB_QUIRK(SANDISK, SDCZ2_128, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
+	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE,
+	    UQ_MSC_NO_SYNC_CACHE),
 	USB_QUIRK(SANDISK, SDCZ2_256, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE),
 	USB_QUIRK(SANDISK, SDCZ4_128, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
@@ -398,6 +406,8 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	USB_QUIRK(STMICRO, ST72682, 0x0000, 0xffff, UQ_MSC_NO_PREVENT_ALLOW),
 	USB_QUIRK(SUPERTOP, IDE, 0x0000, 0xffff, UQ_MSC_IGNORE_RESIDUE,
 	    UQ_MSC_NO_SYNC_CACHE),
+	USB_QUIRK(SUPERTOP, FLASHDRIVE, 0x0000, 0xffff, UQ_MSC_NO_TEST_UNIT_READY,
+	    UQ_MSC_NO_SYNC_CACHE),
 	USB_QUIRK(TAUGA, CAMERAMATE, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
 	USB_QUIRK(TEAC, FD05PUB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
 	    UQ_MSC_FORCE_PROTO_UFI),
@@ -427,6 +437,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY_EVPD,
 	    UQ_MSC_NO_SYNC_CACHE),
 	USB_QUIRK(WESTERN, MYPASSWORD, 0x0000, 0xffff, UQ_MSC_FORCE_SHORT_INQ),
+	USB_QUIRK(WESTERN, MYPASSPORT, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 	USB_QUIRK(WINMAXGROUP, FLASH64MC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
 	USB_QUIRK(YANO, FW800HD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
diff --git a/freebsd/sys/dev/usb/storage/umass.c b/freebsd/sys/dev/usb/storage/umass.c
index 76a1fcb..39d3269 100644
--- a/freebsd/sys/dev/usb/storage/umass.c
+++ b/freebsd/sys/dev/usb/storage/umass.c
@@ -1326,10 +1326,12 @@ umass_t_bbb_command_callback(struct usb_xfer *xfer, usb_error_t error)
 			}
 			sc->cbw.bCDBLength = sc->sc_transfer.cmd_len;
 
+			/* copy SCSI command data */
 			memcpy(sc->cbw.CBWCDB, sc->sc_transfer.cmd_data,
 			    sc->sc_transfer.cmd_len);
 
-			memset(sc->sc_transfer.cmd_data +
+			/* clear remaining command area */
+			memset(sc->cbw.CBWCDB +
 			    sc->sc_transfer.cmd_len, 0,
 			    sizeof(sc->cbw.CBWCDB) -
 			    sc->sc_transfer.cmd_len);
diff --git a/freebsd/sys/dev/usb/usb.h b/freebsd/sys/dev/usb/usb.h
index 9492d49..bb5a60c 100644
--- a/freebsd/sys/dev/usb/usb.h
+++ b/freebsd/sys/dev/usb/usb.h
@@ -493,8 +493,11 @@ typedef struct usb_interface_assoc_descriptor usb_interface_assoc_descriptor_t;
 #define	UICLASS_WIRELESS	0xe0
 #define	UISUBCLASS_RF			0x01
 #define	UIPROTO_BLUETOOTH		0x01
+#define	UIPROTO_RNDIS			0x03
 
 #define	UICLASS_IAD		0xEF	/* Interface Association Descriptor */
+#define	UISUBCLASS_SYNC			0x01
+#define	UIPROTO_ACTIVESYNC		0x01
 
 #define	UICLASS_APPL_SPEC	0xfe
 #define	UISUBCLASS_FIRMWARE_DOWNLOAD	1
diff --git a/freebsd/sys/dev/usb/usb_bus.h b/freebsd/sys/dev/usb/usb_bus.h
index 459219b..702f623 100644
--- a/freebsd/sys/dev/usb/usb_bus.h
+++ b/freebsd/sys/dev/usb/usb_bus.h
@@ -73,6 +73,7 @@ struct usb_bus {
 	struct usb_bus_msg attach_msg[2];
 	struct usb_bus_msg suspend_msg[2];
 	struct usb_bus_msg resume_msg[2];
+	struct usb_bus_msg reset_msg[2];
 	struct usb_bus_msg shutdown_msg[2];
 	/*
 	 * This mutex protects the USB hardware:
diff --git a/freebsd/sys/dev/usb/usb_busdma.c b/freebsd/sys/dev/usb/usb_busdma.c
index 80cd8c3..7d98155 100644
--- a/freebsd/sys/dev/usb/usb_busdma.c
+++ b/freebsd/sys/dev/usb/usb_busdma.c
@@ -213,9 +213,7 @@ usbd_m_copy_in(struct usb_page_cache *cache, usb_frlength_t dst_offset,
     struct mbuf *m, usb_size_t src_offset, usb_frlength_t src_len)
 {
 	struct usb_m_copy_in_arg arg = {cache, dst_offset};
-	int error;
-
-	error = m_apply(m, src_offset, src_len, &usbd_m_copy_in_cb, &arg);
+	(void) m_apply(m, src_offset, src_len, &usbd_m_copy_in_cb, &arg);
 }
 #endif
 
@@ -360,8 +358,7 @@ usb_dma_tag_create(struct usb_dma_tag *udt,
 	if (bus_dma_tag_create
 	    ( /* parent    */ udt->tag_parent->tag,
 	     /* alignment */ align,
-	     /* boundary  */ (align == 1) ?
-	    USB_PAGE_SIZE : 0,
+	     /* boundary  */ 0,
 	     /* lowaddr   */ (2ULL << (udt->tag_parent->dma_bits - 1)) - 1,
 	     /* highaddr  */ BUS_SPACE_MAXADDR,
 	     /* filter    */ NULL,
@@ -420,6 +417,7 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs,
 	struct usb_page_cache *pc;
 	struct usb_page *pg;
 	usb_size_t rem;
+	bus_size_t off;
 	uint8_t owned;
 
 	pc = arg;
@@ -435,12 +433,13 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs,
 	if (error) {
 		goto done;
 	}
+
+	off = 0;
 	pg = pc->page_start;
 	pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1);
 	rem = segs->ds_addr & (USB_PAGE_SIZE - 1);
 	pc->page_offset_buf = rem;
 	pc->page_offset_end += rem;
-	nseg--;
 #ifdef USB_DEBUG
 	if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) {
 		/*
@@ -451,11 +450,19 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs,
 		goto done;
 	}
 #endif
-	while (nseg > 0) {
-		nseg--;
-		segs++;
+	while (pc->ismultiseg) {
+		off += USB_PAGE_SIZE;
+		if (off >= (segs->ds_len + rem)) {
+			/* page crossing */
+			nseg--;
+			segs++;
+			off = 0;
+			rem = 0;
+			if (nseg == 0)
+				break;
+		}
 		pg++;
-		pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1);
+		pg->physaddr = (segs->ds_addr + off) & ~(USB_PAGE_SIZE - 1);
 	}
 
 done:
diff --git a/freebsd/sys/dev/usb/usb_controller.h b/freebsd/sys/dev/usb/usb_controller.h
index ad87191..f23ade2 100644
--- a/freebsd/sys/dev/usb/usb_controller.h
+++ b/freebsd/sys/dev/usb/usb_controller.h
@@ -186,6 +186,7 @@ void	usb_bus_mem_flush_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb);
 uint8_t	usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat, usb_bus_mem_cb_t *cb);
 void	usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb);
 uint16_t usb_isoc_time_expand(struct usb_bus *bus, uint16_t isoc_time_curr);
+void	usb_bus_reset_async_locked(struct usb_bus *bus);
 #if USB_HAVE_TT_SUPPORT
 uint8_t	usbd_fs_isoc_schedule_alloc_slot(struct usb_xfer *isoc_xfer, uint16_t isoc_time);
 #endif
diff --git a/freebsd/sys/dev/usb/usb_core.h b/freebsd/sys/dev/usb/usb_core.h
index 3dfd0d1..48e5ee8 100644
--- a/freebsd/sys/dev/usb/usb_core.h
+++ b/freebsd/sys/dev/usb/usb_core.h
@@ -113,6 +113,8 @@ struct usb_xfer_flags_int {
 	uint8_t	can_cancel_immed:1;	/* set if USB transfer can be
 					 * cancelled immediately */
 	uint8_t	doing_callback:1;	/* set if executing the callback */
+	uint8_t maxp_was_clamped:1;	/* set if the max packet size 
+					 * was outside its allowed range */
 };
 
 /*
diff --git a/freebsd/sys/dev/usb/usb_dev.c b/freebsd/sys/dev/usb/usb_dev.c
index 7697b64..3ff064e 100644
--- a/freebsd/sys/dev/usb/usb_dev.c
+++ b/freebsd/sys/dev/usb/usb_dev.c
@@ -107,7 +107,7 @@ static void	usb_dev_uninit(void *);
 static int	usb_fifo_uiomove(struct usb_fifo *, void *, int,
 		    struct uio *);
 static void	usb_fifo_check_methods(struct usb_fifo_methods *);
-static struct	usb_fifo *usb_fifo_alloc(void);
+static struct	usb_fifo *usb_fifo_alloc(struct mtx *);
 static struct	usb_endpoint *usb_dev_get_ep(struct usb_device *, uint8_t,
 		    uint8_t);
 static void	usb_loc_fill(struct usb_fs_privdata *,
@@ -122,6 +122,7 @@ static d_ioctl_t usb_ioctl;
 static d_read_t usb_read;
 static d_write_t usb_write;
 static d_poll_t usb_poll;
+static d_kqfilter_t usb_kqfilter;
 
 static d_ioctl_t usb_static_ioctl;
 
@@ -139,7 +140,8 @@ struct cdevsw usb_devsw = {
 	.d_flags = D_TRACKCLOSE,
 	.d_read = usb_read,
 	.d_write = usb_write,
-	.d_poll = usb_poll
+	.d_poll = usb_poll,
+	.d_kqfilter = usb_kqfilter,
 };
 
 static struct cdev* usb_dev = NULL;
@@ -205,12 +207,18 @@ usb_ref_device(struct usb_cdev_privdata *cpd,
 		DPRINTFN(2, "no device at %u\n", cpd->dev_index);
 		goto error;
 	}
-	if (cpd->udev->refcount == USB_DEV_REF_MAX) {
-		DPRINTFN(2, "no dev ref\n");
+	if (cpd->udev->state == USB_STATE_DETACHED &&
+	    (need_uref != 2)) {
+		DPRINTFN(2, "device is detached\n");
 		goto error;
 	}
 	if (need_uref) {
 		DPRINTFN(2, "ref udev - needed\n");
+
+		if (cpd->udev->refcount == USB_DEV_REF_MAX) {
+			DPRINTFN(2, "no dev ref\n");
+			goto error;
+		}
 		cpd->udev->refcount++;
 
 		mtx_unlock(&usb_ref_lock);
@@ -284,9 +292,8 @@ error:
 		usbd_enum_unlock(cpd->udev);
 
 	if (crd->is_uref) {
-		if (--(cpd->udev->refcount) == 0) {
-			cv_signal(&cpd->udev->ref_cv);
-		}
+		cpd->udev->refcount--;
+		cv_broadcast(&cpd->udev->ref_cv);
 	}
 	mtx_unlock(&usb_ref_lock);
 	DPRINTFN(2, "fail\n");
@@ -352,24 +359,25 @@ usb_unref_device(struct usb_cdev_privdata *cpd,
 		crd->is_write = 0;
 	}
 	if (crd->is_uref) {
-		if (--(cpd->udev->refcount) == 0) {
-			cv_signal(&cpd->udev->ref_cv);
-		}
 		crd->is_uref = 0;
+		cpd->udev->refcount--;
+		cv_broadcast(&cpd->udev->ref_cv);
 	}
 	mtx_unlock(&usb_ref_lock);
 }
 
 static struct usb_fifo *
-usb_fifo_alloc(void)
+usb_fifo_alloc(struct mtx *mtx)
 {
 	struct usb_fifo *f;
 
 	f = malloc(sizeof(*f), M_USBDEV, M_WAITOK | M_ZERO);
-	if (f) {
+	if (f != NULL) {
 		cv_init(&f->cv_io, "FIFO-IO");
 		cv_init(&f->cv_drain, "FIFO-DRAIN");
+		f->priv_mtx = mtx;
 		f->refcount = 1;
+		knlist_init_mtx(&f->selinfo.si_note, mtx);
 	}
 	return (f);
 }
@@ -493,7 +501,7 @@ usb_fifo_create(struct usb_cdev_privdata *cpd,
 			DPRINTFN(5, "dev_get_endpoint returned NULL\n");
 			return (EINVAL);
 		}
-		f = usb_fifo_alloc();
+		f = usb_fifo_alloc(&udev->device_mtx);
 		if (f == NULL) {
 			DPRINTFN(5, "could not alloc tx fifo\n");
 			return (ENOMEM);
@@ -501,7 +509,6 @@ usb_fifo_create(struct usb_cdev_privdata *cpd,
 		/* update some fields */
 		f->fifo_index = n + USB_FIFO_TX;
 		f->dev_ep_index = e;
-		f->priv_mtx = &udev->device_mtx;
 		f->priv_sc0 = ep;
 		f->methods = &usb_ugen_methods;
 		f->iface_index = ep->iface_index;
@@ -520,7 +527,7 @@ usb_fifo_create(struct usb_cdev_privdata *cpd,
 			DPRINTFN(5, "dev_get_endpoint returned NULL\n");
 			return (EINVAL);
 		}
-		f = usb_fifo_alloc();
+		f = usb_fifo_alloc(&udev->device_mtx);
 		if (f == NULL) {
 			DPRINTFN(5, "could not alloc rx fifo\n");
 			return (ENOMEM);
@@ -528,7 +535,6 @@ usb_fifo_create(struct usb_cdev_privdata *cpd,
 		/* update some fields */
 		f->fifo_index = n + USB_FIFO_RX;
 		f->dev_ep_index = e;
-		f->priv_mtx = &udev->device_mtx;
 		f->priv_sc0 = ep;
 		f->methods = &usb_ugen_methods;
 		f->iface_index = ep->iface_index;
@@ -595,6 +601,13 @@ usb_fifo_free(struct usb_fifo *f)
 		mtx_unlock(f->priv_mtx);
 		mtx_lock(&usb_ref_lock);
 
+		/*
+		 * Check if the "f->refcount" variable reached zero
+		 * during the unlocked time before entering wait:
+		 */
+		if (f->refcount == 0)
+			break;
+
 		/* wait for sync */
 		cv_wait(&f->cv_drain, &usb_ref_lock);
 	}
@@ -606,6 +619,10 @@ usb_fifo_free(struct usb_fifo *f)
 	cv_destroy(&f->cv_io);
 	cv_destroy(&f->cv_drain);
 
+	knlist_clear(&f->selinfo.si_note, 0);
+	seldrain(&f->selinfo);
+	knlist_destroy(&f->selinfo.si_note);
+
 	free(f, M_USBDEV);
 }
 
@@ -760,7 +777,12 @@ usb_fifo_close(struct usb_fifo *f, int fflags)
 	mtx_lock(f->priv_mtx);
 
 	/* clear current cdev private data pointer */
+	mtx_lock(&usb_ref_lock);
 	f->curr_cpd = NULL;
+	mtx_unlock(&usb_ref_lock);
+
+	/* check if we are watched by kevent */
+	KNOTE_LOCKED(&f->selinfo.si_note, 0);
 
 	/* check if we are selected */
 	if (f->flag_isselect) {
@@ -913,23 +935,12 @@ usb_close(void *arg)
 
 	DPRINTFN(2, "cpd=%p\n", cpd);
 
-	err = usb_ref_device(cpd, &refs, 0);
-	if (err)
+	err = usb_ref_device(cpd, &refs,
+	    2 /* uref and allow detached state */);
+	if (err) {
+		DPRINTFN(2, "Cannot grab USB reference when "
+		    "closing USB file handle\n");
 		goto done;
-
-	/*
-	 * If this function is not called directly from the root HUB
-	 * thread, there is usually a need to lock the enumeration
-	 * lock. Check this.
-	 */
-	if (!usbd_enum_is_locked(cpd->udev)) {
-
-		DPRINTFN(2, "Locking enumeration\n");
-
-		/* reference device */
-		err = usb_usb_ref_device(cpd, &refs);
-		if (err)
-			goto done;
 	}
 	if (cpd->fflags & FREAD) {
 		usb_fifo_close(refs.rxfifo, cpd->fflags);
@@ -1097,15 +1108,20 @@ usb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread*
 
 	/* Wait for re-enumeration, if any */
 
-	while (f->udev->re_enumerate_wait != 0) {
+	while (f->udev->re_enumerate_wait != USB_RE_ENUM_DONE) {
 
 		usb_unref_device(cpd, &refs);
 
 		usb_pause_mtx(NULL, hz / 128);
 
-		if (usb_ref_device(cpd, &refs, 1 /* need uref */)) {
-			err = ENXIO;
-			goto done;
+		while (usb_ref_device(cpd, &refs, 1 /* need uref */)) {
+			if (usb_ref_device(cpd, &refs, 0)) {
+				/* device no longer exits */
+				err = ENXIO;
+				goto done;
+			}
+			usb_unref_device(cpd, &refs);
+			usb_pause_mtx(NULL, hz / 128);
 		}
 	}
 
@@ -1114,6 +1130,162 @@ done:
 	return (err);
 }
 
+static void
+usb_filter_detach(struct knote *kn)
+{
+	struct usb_fifo *f = kn->kn_hook;
+	knlist_remove(&f->selinfo.si_note, kn, 0);
+}
+
+static int
+usb_filter_write(struct knote *kn, long hint)
+{
+	struct usb_cdev_privdata* cpd;
+	struct usb_fifo *f;
+	struct usb_mbuf *m;
+
+	DPRINTFN(2, "\n");
+
+	f = kn->kn_hook;
+
+	mtx_assert(f->priv_mtx, MA_OWNED);
+
+	cpd = f->curr_cpd;
+	if (cpd == NULL) {
+		m = (void *)1;
+	} else if (f->fs_ep_max == 0) {
+		if (f->flag_iserror) {
+			/* we got an error */
+			m = (void *)1;
+		} else {
+			if (f->queue_data == NULL) {
+				/*
+				 * start write transfer, if not
+				 * already started
+				 */
+				(f->methods->f_start_write) (f);
+			}
+			/* check if any packets are available */
+			USB_IF_POLL(&f->free_q, m);
+		}
+	} else {
+		if (f->flag_iscomplete) {
+			m = (void *)1;
+		} else {
+			m = NULL;
+		}
+	}
+	return (m ? 1 : 0);
+}
+
+static int
+usb_filter_read(struct knote *kn, long hint)
+{
+	struct usb_cdev_privdata* cpd;
+	struct usb_fifo *f;
+	struct usb_mbuf *m;
+
+	DPRINTFN(2, "\n");
+
+	f = kn->kn_hook;
+
+	mtx_assert(f->priv_mtx, MA_OWNED);
+
+	cpd = f->curr_cpd;
+	if (cpd == NULL) {
+		m = (void *)1;
+	} else if (f->fs_ep_max == 0) {
+		if (f->flag_iserror) {
+			/* we have an error */
+			m = (void *)1;
+		} else {
+			if (f->queue_data == NULL) {
+				/*
+				 * start read transfer, if not
+				 * already started
+				 */
+				(f->methods->f_start_read) (f);
+			}
+			/* check if any packets are available */
+			USB_IF_POLL(&f->used_q, m);
+
+			/* start reading data, if any */
+			if (m == NULL)
+				(f->methods->f_start_read) (f);
+		}
+	} else {
+		if (f->flag_iscomplete) {
+			m = (void *)1;
+		} else {
+			m = NULL;
+		}
+	}
+	return (m ? 1 : 0);
+}
+
+static struct filterops usb_filtops_write = {
+	.f_isfd = 1,
+	.f_detach = usb_filter_detach,
+	.f_event = usb_filter_write,
+};
+
+static struct filterops usb_filtops_read = {
+	.f_isfd = 1,
+	.f_detach = usb_filter_detach,
+	.f_event = usb_filter_read,
+};
+
+
+/* ARGSUSED */
+static int
+usb_kqfilter(struct cdev* dev, struct knote *kn)
+{
+	struct usb_cdev_refdata refs;
+	struct usb_cdev_privdata* cpd;
+	struct usb_fifo *f;
+	int fflags;
+	int err = EINVAL;
+
+	DPRINTFN(2, "\n");
+
+	if (devfs_get_cdevpriv((void **)&cpd) != 0 ||
+	    usb_ref_device(cpd, &refs, 0) != 0)
+		return (ENXIO);
+
+	fflags = cpd->fflags;
+
+	/* Figure out who needs service */
+	switch (kn->kn_filter) {
+	case EVFILT_WRITE:
+		if (fflags & FWRITE) {
+			f = refs.txfifo;
+			kn->kn_fop = &usb_filtops_write;
+			err = 0;
+		}
+		break;
+	case EVFILT_READ:
+		if (fflags & FREAD) {
+			f = refs.rxfifo;
+			kn->kn_fop = &usb_filtops_read;
+			err = 0;
+		}
+		break;
+	default:
+		err = EOPNOTSUPP;
+		break;
+	}
+
+	if (err == 0) {
+		kn->kn_hook = f;
+		mtx_lock(f->priv_mtx);
+		knlist_add(&f->selinfo.si_note, kn, 1);
+		mtx_unlock(f->priv_mtx);
+	}
+
+	usb_unref_device(cpd, &refs);
+	return (err);
+}
+
 /* ARGSUSED */
 static int
 usb_poll(struct cdev* dev, int events, struct thread* td)
@@ -1181,7 +1353,7 @@ usb_poll(struct cdev* dev, int events, struct thread* td)
 
 		if (!refs.is_usbfs) {
 			if (f->flag_iserror) {
-				/* we have and error */
+				/* we have an error */
 				m = (void *)1;
 			} else {
 				if (f->queue_data == NULL) {
@@ -1578,6 +1750,8 @@ usb_fifo_wakeup(struct usb_fifo *f)
 {
 	usb_fifo_signal(f);
 
+	KNOTE_LOCKED(&f->selinfo.si_note, 0);
+
 	if (f->flag_isselect) {
 		selwakeup(&f->selinfo);
 		f->flag_isselect = 0;
@@ -1693,8 +1867,8 @@ usb_fifo_attach(struct usb_device *udev, void *priv_sc,
 		break;
 	}
 
-	f_tx = usb_fifo_alloc();
-	f_rx = usb_fifo_alloc();
+	f_tx = usb_fifo_alloc(priv_mtx);
+	f_rx = usb_fifo_alloc(priv_mtx);
 
 	if ((f_tx == NULL) || (f_rx == NULL)) {
 		usb_fifo_free(f_tx);
@@ -1705,7 +1879,6 @@ usb_fifo_attach(struct usb_device *udev, void *priv_sc,
 
 	f_tx->fifo_index = n + USB_FIFO_TX;
 	f_tx->dev_ep_index = -1;
-	f_tx->priv_mtx = priv_mtx;
 	f_tx->priv_sc0 = priv_sc;
 	f_tx->methods = pm;
 	f_tx->iface_index = iface_index;
@@ -1713,7 +1886,6 @@ usb_fifo_attach(struct usb_device *udev, void *priv_sc,
 
 	f_rx->fifo_index = n + USB_FIFO_RX;
 	f_rx->dev_ep_index = -1;
-	f_rx->priv_mtx = priv_mtx;
 	f_rx->priv_sc0 = priv_sc;
 	f_rx->methods = pm;
 	f_rx->iface_index = iface_index;
diff --git a/freebsd/sys/dev/usb/usb_device.c b/freebsd/sys/dev/usb/usb_device.c
index 78ae3d8..e18c32d 100644
--- a/freebsd/sys/dev/usb/usb_device.c
+++ b/freebsd/sys/dev/usb/usb_device.c
@@ -96,7 +96,7 @@ static void	usb_init_attach_arg(struct usb_device *,
 		    struct usb_attach_arg *);
 static void	usb_suspend_resume_sub(struct usb_device *, device_t,
 		    uint8_t);
-static void	usbd_clear_stall_proc(struct usb_proc_msg *_pm);
+static usb_proc_callback_t usbd_clear_stall_proc;
 static usb_error_t usb_config_parse(struct usb_device *, uint8_t, uint8_t);
 static void	usbd_set_device_strings(struct usb_device *);
 #if USB_HAVE_DEVCTL
@@ -437,6 +437,65 @@ usb_endpoint_foreach(struct usb_device *udev, struct usb_endpoint *ep)
 }
 
 /*------------------------------------------------------------------------*
+ *	usb_wait_pending_ref_locked
+ *
+ * This function will wait for any USB references to go away before
+ * returning and disable further USB device refcounting on the
+ * specified USB device. This function is used when detaching a USB
+ * device.
+ *------------------------------------------------------------------------*/
+static void
+usb_wait_pending_ref_locked(struct usb_device *udev)
+{
+#if USB_HAVE_UGEN
+	const uint16_t refcount =
+	    usb_proc_is_called_from(
+	    &udev->bus->explore_proc) ? 1 : 2;
+
+	DPRINTF("Refcount = %d\n", (int)refcount); 
+
+	while (1) {
+		/* wait for any pending references to go away */
+		mtx_lock(&usb_ref_lock);
+		if (udev->refcount == refcount) {
+			/* prevent further refs being taken */
+			udev->refcount = USB_DEV_REF_MAX;
+			mtx_unlock(&usb_ref_lock);
+			break;
+		}
+		usbd_enum_unlock(udev);
+		cv_wait(&udev->ref_cv, &usb_ref_lock);
+		mtx_unlock(&usb_ref_lock);
+		(void) usbd_enum_lock(udev);
+	}
+#endif
+}
+
+/*------------------------------------------------------------------------*
+ *	usb_ref_restore_locked
+ *
+ * This function will restore the reference count value after a call
+ * to "usb_wait_pending_ref_locked()".
+ *------------------------------------------------------------------------*/
+static void
+usb_ref_restore_locked(struct usb_device *udev)
+{
+#if USB_HAVE_UGEN
+	const uint16_t refcount =
+	    usb_proc_is_called_from(
+	    &udev->bus->explore_proc) ? 1 : 2;
+
+	DPRINTF("Refcount = %d\n", (int)refcount); 
+
+	/* restore reference count and wakeup waiters, if any */
+	mtx_lock(&usb_ref_lock);
+	udev->refcount = refcount;
+	cv_broadcast(&udev->ref_cv);
+	mtx_unlock(&usb_ref_lock);
+#endif
+}
+
+/*------------------------------------------------------------------------*
  *	usb_unconfigure
  *
  * This function will free all USB interfaces and USB endpoints belonging
@@ -1097,6 +1156,9 @@ usb_detach_device(struct usb_device *udev, uint8_t iface_index,
 
 	sx_assert(&udev->enum_sx, SA_LOCKED);
 
+	/* wait for pending refs to go away */
+	usb_wait_pending_ref_locked(udev);
+
 	/*
 	 * First detach the child to give the child's detach routine a
 	 * chance to detach the sub-devices in the correct order.
@@ -1123,6 +1185,8 @@ usb_detach_device(struct usb_device *udev, uint8_t iface_index,
 		usb_detach_device_sub(udev, &iface->subdev,
 		    &iface->pnpinfo, flag);
 	}
+
+	usb_ref_restore_locked(udev);
 }
 
 /*------------------------------------------------------------------------*
@@ -1450,7 +1514,7 @@ usb_suspend_resume(struct usb_device *udev, uint8_t do_suspend)
 static void
 usbd_clear_stall_proc(struct usb_proc_msg *_pm)
 {
-	struct usb_clear_stall_msg *pm = (void *)_pm;
+	struct usb_udev_msg *pm = (void *)_pm;
 	struct usb_device *udev = pm->udev;
 
 	/* Change lock */
@@ -1679,10 +1743,14 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
 	err = usbd_setup_device_desc(udev, NULL);
 
 	if (err != 0) {
-		/* XXX try to re-enumerate the device */
+		/* try to enumerate two more times */
 		err = usbd_req_re_enumerate(udev, NULL);
-		if (err)
-			goto done;
+		if (err != 0) {
+			err = usbd_req_re_enumerate(udev, NULL);
+			if (err != 0) {
+				goto done;
+			}
+		}
 	}
 
 	/*
@@ -2038,6 +2106,8 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
 	DPRINTFN(4, "udev=%p port=%d\n", udev, udev->port_no);
 
 	bus = udev->bus;
+
+	/* set DETACHED state to prevent any further references */
 	usb_set_device_state(udev, USB_STATE_DETACHED);
 
 #if USB_HAVE_DEVCTL
@@ -2053,23 +2123,6 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
 		usb_free_symlink(udev->ugen_symlink);
 		udev->ugen_symlink = NULL;
 	}
-#endif
-	/*
-	 * Unregister our device first which will prevent any further
-	 * references:
-	 */
-	usb_bus_port_set_device(bus, udev->parent_hub ?
-	    udev->parent_hub->hub->ports + udev->port_index : NULL,
-	    NULL, USB_ROOT_HUB_ADDR);
-
-#if USB_HAVE_UGEN
-	/* wait for all pending references to go away: */
-	mtx_lock(&usb_ref_lock);
-	udev->refcount--;
-	while (udev->refcount != 0) {
-		cv_wait(&udev->ref_cv, &usb_ref_lock);
-	}
-	mtx_unlock(&usb_ref_lock);
 
 	usb_destroy_dev(udev->ctrl_dev);
 #endif
@@ -2082,6 +2135,11 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
 	/* the following will get the device unconfigured in software */
 	usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_EP0);
 
+	/* final device unregister after all character devices are closed */
+	usb_bus_port_set_device(bus, udev->parent_hub ?
+	    udev->parent_hub->hub->ports + udev->port_index : NULL,
+	    NULL, USB_ROOT_HUB_ADDR);
+
 	/* unsetup any leftover default USB transfers */
 	usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
 
@@ -2582,8 +2640,14 @@ usb_fifo_free_wrap(struct usb_device *udev,
 			/* no need to free this FIFO */
 			continue;
 		}
+		/* wait for pending refs to go away */
+		usb_wait_pending_ref_locked(udev);
+
 		/* free this FIFO */
 		usb_fifo_free(f);
+
+		/* restore refcount */
+		usb_ref_restore_locked(udev);
 	}
 }
 #endif
@@ -2615,8 +2679,14 @@ usb_set_device_state(struct usb_device *udev, enum usb_dev_state state)
 
 	DPRINTF("udev %p state %s -> %s\n", udev,
 	    usb_statestr(udev->state), usb_statestr(state));
-	udev->state = state;
 
+#if USB_HAVE_UGEN
+	mtx_lock(&usb_ref_lock);
+#endif
+	udev->state = state;
+#if USB_HAVE_UGEN
+	mtx_unlock(&usb_ref_lock);
+#endif
 	if (udev->bus->methods->device_state_change != NULL)
 		(udev->bus->methods->device_state_change) (udev);
 }
diff --git a/freebsd/sys/dev/usb/usb_device.h b/freebsd/sys/dev/usb/usb_device.h
index 8e13e3d..361f5c3 100644
--- a/freebsd/sys/dev/usb/usb_device.h
+++ b/freebsd/sys/dev/usb/usb_device.h
@@ -53,7 +53,7 @@ struct usb_symlink;		/* UGEN */
 #define	USB_UNCFG_FLAG_NONE 0x00
 #define	USB_UNCFG_FLAG_FREE_EP0	0x02		/* endpoint zero is freed */
 
-struct usb_clear_stall_msg {
+struct usb_udev_msg {
 	struct usb_proc_msg hdr;
 	struct usb_device *udev;
 };
@@ -179,8 +179,8 @@ union usb_device_scratch {
  * these structures for every USB device.
  */
 struct usb_device {
-	struct usb_clear_stall_msg cs_msg[2];	/* generic clear stall
-						 * messages */
+	/* generic clear stall message */
+	struct usb_udev_msg cs_msg[2];
 	struct sx enum_sx;
 	struct sx sr_sx;
 	struct mtx device_mtx;
@@ -220,6 +220,7 @@ struct usb_device {
 	uint8_t	address;		/* device addess */
 	uint8_t	device_index;		/* device index in "bus->devices" */
 	uint8_t	controller_slot_id;	/* controller specific value */
+	uint8_t next_config_index;	/* used by USB_RE_ENUM_SET_CONFIG */
 	uint8_t	curr_config_index;	/* current configuration index */
 	uint8_t	curr_config_no;		/* current configuration number */
 	uint8_t	depth;			/* distance from root HUB */
@@ -230,6 +231,10 @@ struct usb_device {
 	uint8_t	driver_added_refcount;	/* our driver added generation count */
 	uint8_t	power_mode;		/* see USB_POWER_XXX */
 	uint8_t re_enumerate_wait;	/* set if re-enum. is in progress */
+#define	USB_RE_ENUM_DONE	0
+#define	USB_RE_ENUM_START	1
+#define	USB_RE_ENUM_PWR_OFF	2
+#define	USB_RE_ENUM_SET_CONFIG	3
 	uint8_t ifaces_max;		/* number of interfaces present */
 	uint8_t endpoints_max;		/* number of endpoints present */
 
@@ -301,4 +306,10 @@ void	usbd_sr_lock(struct usb_device *);
 void	usbd_sr_unlock(struct usb_device *);
 uint8_t usbd_enum_is_locked(struct usb_device *);
 
+#if USB_HAVE_TT_SUPPORT
+void	uhub_tt_buffer_reset_async_locked(struct usb_device *, struct usb_endpoint *);
+#endif
+
+uint8_t uhub_count_active_host_ports(struct usb_device *, enum usb_dev_speed);
+
 #endif					/* _USB_DEVICE_H_ */
diff --git a/freebsd/sys/dev/usb/usb_freebsd.h b/freebsd/sys/dev/usb/usb_freebsd.h
index 06369a2..4cd1758 100644
--- a/freebsd/sys/dev/usb/usb_freebsd.h
+++ b/freebsd/sys/dev/usb/usb_freebsd.h
@@ -45,6 +45,9 @@
 #define	USB_HAVE_PF 1
 #endif /* __rtems__ */
 
+/* define zero ticks callout value */
+#define	USB_CALLOUT_ZERO_TICKS 1
+
 #define	USB_TD_GET_PROC(td) (td)->td_proc
 #define	USB_PROC_GET_GID(td) (td)->p_pgid
 
diff --git a/freebsd/sys/dev/usb/usb_generic.c b/freebsd/sys/dev/usb/usb_generic.c
index a0b7f00..e1fc141 100644
--- a/freebsd/sys/dev/usb/usb_generic.c
+++ b/freebsd/sys/dev/usb/usb_generic.c
@@ -612,24 +612,17 @@ ugen_set_config(struct usb_fifo *f, uint8_t index)
 		/* not possible in device side mode */
 		return (ENOTTY);
 	}
-	if (f->udev->curr_config_index == index) {
-		/* no change needed */
-		return (0);
-	}
+
 	/* make sure all FIFO's are gone */
 	/* else there can be a deadlock */
 	if (ugen_fs_uninit(f)) {
 		/* ignore any errors */
 		DPRINTFN(6, "no FIFOs\n");
 	}
-	/* change setting - will free generic FIFOs, if any */
-	if (usbd_set_config_index(f->udev, index)) {
-		return (EIO);
-	}
-	/* probe and attach */
-	if (usb_probe_and_attach(f->udev, USB_IFACE_INDEX_ANY)) {
+
+	if (usbd_start_set_config(f->udev, index) != 0)
 		return (EIO);
-	}
+
 	return (0);
 }
 
@@ -963,11 +956,6 @@ ugen_re_enumerate(struct usb_fifo *f)
 		DPRINTFN(6, "device mode\n");
 		return (ENOTTY);
 	}
-	if (udev->parent_hub == NULL) {
-		/* the root HUB cannot be re-enumerated */
-		DPRINTFN(6, "cannot reset root HUB\n");
-		return (EINVAL);
-	}
 	/* make sure all FIFO's are gone */
 	/* else there can be a deadlock */
 	if (ugen_fs_uninit(f)) {
@@ -1751,16 +1739,11 @@ ugen_set_power_mode(struct usb_fifo *f, int mode)
 
 	switch (mode) {
 	case USB_POWER_MODE_OFF:
-		/* get the device unconfigured */
-		err = ugen_set_config(f, USB_UNCONFIG_INDEX);
-		if (err) {
-			DPRINTFN(0, "Could not unconfigure "
-			    "device (ignored)\n");
+		if (udev->flags.usb_mode == USB_MODE_HOST &&
+		    udev->re_enumerate_wait == USB_RE_ENUM_DONE) {
+			udev->re_enumerate_wait = USB_RE_ENUM_PWR_OFF;
 		}
-
-		/* clear port enable */
-		err = usbd_req_clear_port_feature(udev->parent_hub,
-		    NULL, udev->port_no, UHF_PORT_ENABLE);
+		/* set power mode will wake up the explore thread */
 		break;
 
 	case USB_POWER_MODE_ON:
@@ -1808,9 +1791,9 @@ ugen_set_power_mode(struct usb_fifo *f, int mode)
 
 	/* if we are powered off we need to re-enumerate first */
 	if (old_mode == USB_POWER_MODE_OFF) {
-		if (udev->flags.usb_mode == USB_MODE_HOST) {
-			if (udev->re_enumerate_wait == 0)
-				udev->re_enumerate_wait = 1;
+		if (udev->flags.usb_mode == USB_MODE_HOST &&
+		    udev->re_enumerate_wait == USB_RE_ENUM_DONE) {
+			udev->re_enumerate_wait = USB_RE_ENUM_START;
 		}
 		/* set power mode will wake up the explore thread */
 	}
@@ -1833,6 +1816,46 @@ ugen_get_power_mode(struct usb_fifo *f)
 }
 
 static int
+ugen_get_port_path(struct usb_fifo *f, struct usb_device_port_path *dpp)
+{
+	struct usb_device *udev = f->udev;
+	struct usb_device *next;
+	unsigned int nlevel = 0;
+
+	if (udev == NULL)
+		goto error;
+
+	dpp->udp_bus = device_get_unit(udev->bus->bdev);
+	dpp->udp_index = udev->device_index;
+
+	/* count port levels */
+	next = udev;
+	while (next->parent_hub != NULL) {
+		nlevel++;
+		next = next->parent_hub;
+	}
+
+	/* check if too many levels */
+	if (nlevel > USB_DEVICE_PORT_PATH_MAX)
+		goto error;
+
+	/* store port index array */
+	next = udev;
+	while (next->parent_hub != NULL) {
+		nlevel--;
+
+		dpp->udp_port_no[nlevel] = next->port_no;
+		dpp->udp_port_level = nlevel;
+
+		next = next->parent_hub;
+	}
+	return (0);	/* success */
+
+error:
+	return (EINVAL);	/* failure */
+}
+
+static int
 ugen_get_power_usage(struct usb_fifo *f)
 {
 	struct usb_device *udev = f->udev;
@@ -2033,6 +2056,7 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
 		struct usb_device_stats *stat;
 		struct usb_fs_init *pinit;
 		struct usb_fs_uninit *puninit;
+		struct usb_device_port_path *dpp;
 		uint32_t *ptime;
 		void   *addr;
 		int    *pint;
@@ -2205,6 +2229,10 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
 		*u.pint = ugen_get_power_mode(f);
 		break;
 
+	case USB_GET_DEV_PORT_PATH:
+		error = ugen_get_port_path(f, u.dpp);
+		break;
+
 	case USB_GET_POWER_USAGE:
 		*u.pint = ugen_get_power_usage(f);
 		break;
diff --git a/freebsd/sys/dev/usb/usb_hub.c b/freebsd/sys/dev/usb/usb_hub.c
index 2dee678..9b3bd07 100644
--- a/freebsd/sys/dev/usb/usb_hub.c
+++ b/freebsd/sys/dev/usb/usb_hub.c
@@ -52,7 +52,6 @@
 #include <sys/priv.h>
 
 #include <dev/usb/usb.h>
-#include <dev/usb/usb_ioctl.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
 
@@ -73,7 +72,13 @@
 #include <dev/usb/usb_bus.h>
 
 #define	UHUB_INTR_INTERVAL 250		/* ms */
-#define	UHUB_N_TRANSFER 1
+enum {
+	UHUB_INTR_TRANSFER,
+#if USB_HAVE_TT_SUPPORT
+	UHUB_RESET_TT_TRANSFER,
+#endif
+	UHUB_N_TRANSFER,
+};
 
 #ifdef USB_DEBUG
 static int uhub_debug = 0;
@@ -126,6 +131,9 @@ static bus_child_location_str_t uhub_child_location_string;
 static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string;
 
 static usb_callback_t uhub_intr_callback;
+#if USB_HAVE_TT_SUPPORT
+static usb_callback_t uhub_reset_tt_callback;
+#endif
 
 static void usb_dev_resume_peer(struct usb_device *udev);
 static void usb_dev_suspend_peer(struct usb_device *udev);
@@ -133,7 +141,7 @@ static uint8_t usb_peer_should_wakeup(struct usb_device *udev);
 
 static const struct usb_config uhub_config[UHUB_N_TRANSFER] = {
 
-	[0] = {
+	[UHUB_INTR_TRANSFER] = {
 		.type = UE_INTERRUPT,
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_ANY,
@@ -143,6 +151,17 @@ static const struct usb_config uhub_config[UHUB_N_TRANSFER] = {
 		.callback = &uhub_intr_callback,
 		.interval = UHUB_INTR_INTERVAL,
 	},
+#if USB_HAVE_TT_SUPPORT
+	[UHUB_RESET_TT_TRANSFER] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.bufsize = sizeof(struct usb_device_request),
+		.callback = &uhub_reset_tt_callback,
+		.timeout = 1000,	/* 1 second */
+		.usb_mode = USB_MODE_HOST,
+	},
+#endif
 };
 
 /*
@@ -212,6 +231,279 @@ uhub_intr_callback(struct usb_xfer *xfer, usb_error_t error)
 }
 
 /*------------------------------------------------------------------------*
+ *      uhub_reset_tt_proc
+ *
+ * This function starts the TT reset USB request
+ *------------------------------------------------------------------------*/
+#if USB_HAVE_TT_SUPPORT
+static void
+uhub_reset_tt_proc(struct usb_proc_msg *_pm)
+{
+	struct usb_udev_msg *pm = (void *)_pm;
+	struct usb_device *udev = pm->udev;
+	struct usb_hub *hub;
+	struct uhub_softc *sc;
+
+	hub = udev->hub;
+	if (hub == NULL)
+		return;
+	sc = hub->hubsoftc;
+	if (sc == NULL)
+		return;
+
+	/* Change lock */
+	USB_BUS_UNLOCK(udev->bus);
+	mtx_lock(&sc->sc_mtx);
+	/* Start transfer */
+	usbd_transfer_start(sc->sc_xfer[UHUB_RESET_TT_TRANSFER]);
+	/* Change lock */
+	mtx_unlock(&sc->sc_mtx);
+	USB_BUS_LOCK(udev->bus);
+}
+#endif
+
+/*------------------------------------------------------------------------*
+ *      uhub_tt_buffer_reset_async_locked
+ *
+ * This function queues a TT reset for the given USB device and endpoint.
+ *------------------------------------------------------------------------*/
+#if USB_HAVE_TT_SUPPORT
+void
+uhub_tt_buffer_reset_async_locked(struct usb_device *child, struct usb_endpoint *ep)
+{
+	struct usb_device_request req;
+	struct usb_device *udev;
+	struct usb_hub *hub;
+	struct usb_port *up;
+	uint16_t wValue;
+	uint8_t port;
+
+	if (child == NULL || ep == NULL)
+		return;
+
+	udev = child->parent_hs_hub;
+	port = child->hs_port_no;
+
+	if (udev == NULL)
+		return;
+
+	hub = udev->hub;
+	if ((hub == NULL) ||
+	    (udev->speed != USB_SPEED_HIGH) ||
+	    (child->speed != USB_SPEED_LOW &&
+	     child->speed != USB_SPEED_FULL) ||
+	    (child->flags.usb_mode != USB_MODE_HOST) ||
+	    (port == 0) || (ep->edesc == NULL)) {
+		/* not applicable */
+		return;
+	}
+
+	USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
+
+	up = hub->ports + port - 1;
+
+	if (udev->ddesc.bDeviceClass == UDCLASS_HUB &&
+	    udev->ddesc.bDeviceProtocol == UDPROTO_HSHUBSTT)
+		port = 1;
+
+	/* if we already received a clear buffer request, reset the whole TT */
+	if (up->req_reset_tt.bRequest != 0) {
+		req.bmRequestType = UT_WRITE_CLASS_OTHER;
+		req.bRequest = UR_RESET_TT;
+		USETW(req.wValue, 0);
+		req.wIndex[0] = port;
+		req.wIndex[1] = 0;
+		USETW(req.wLength, 0);
+	} else {
+		wValue = (ep->edesc->bEndpointAddress & 0xF) |
+		      ((child->address & 0x7F) << 4) |
+		      ((ep->edesc->bEndpointAddress & 0x80) << 8) |
+		      ((ep->edesc->bmAttributes & 3) << 12);
+
+		req.bmRequestType = UT_WRITE_CLASS_OTHER;
+		req.bRequest = UR_CLEAR_TT_BUFFER;
+		USETW(req.wValue, wValue);
+		req.wIndex[0] = port;
+		req.wIndex[1] = 0;
+		USETW(req.wLength, 0);
+	}
+	up->req_reset_tt = req;
+	/* get reset transfer started */
+	usb_proc_msignal(&udev->bus->non_giant_callback_proc,
+	    &hub->tt_msg[0], &hub->tt_msg[1]);
+}
+#endif
+
+#if USB_HAVE_TT_SUPPORT
+static void
+uhub_reset_tt_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct uhub_softc *sc;
+	struct usb_device *udev;
+	struct usb_port *up;
+	uint8_t x;
+
+	DPRINTF("TT buffer reset\n");
+
+	sc = usbd_xfer_softc(xfer);
+	udev = sc->sc_udev;
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+	case USB_ST_SETUP:
+tr_setup:
+		USB_BUS_LOCK(udev->bus);
+		/* find first port which needs a TT reset */
+		for (x = 0; x != udev->hub->nports; x++) {
+			up = udev->hub->ports + x;
+
+			if (up->req_reset_tt.bRequest == 0)
+				continue;
+
+			/* copy in the transfer */
+			usbd_copy_in(xfer->frbuffers, 0, &up->req_reset_tt,
+			    sizeof(up->req_reset_tt));
+			/* reset buffer */
+			memset(&up->req_reset_tt, 0, sizeof(up->req_reset_tt));
+
+			/* set length */
+			usbd_xfer_set_frame_len(xfer, 0, sizeof(up->req_reset_tt));
+			xfer->nframes = 1;
+			USB_BUS_UNLOCK(udev->bus);
+
+			usbd_transfer_submit(xfer);
+			return;
+		}
+		USB_BUS_UNLOCK(udev->bus);
+		break;
+
+	default:
+		if (error == USB_ERR_CANCELLED)
+			break;
+
+		DPRINTF("TT buffer reset failed (%s)\n", usbd_errstr(error));
+		goto tr_setup;
+	}
+}
+#endif
+
+/*------------------------------------------------------------------------*
+ *      uhub_count_active_host_ports
+ *
+ * This function counts the number of active ports at the given speed.
+ *------------------------------------------------------------------------*/
+uint8_t
+uhub_count_active_host_ports(struct usb_device *udev, enum usb_dev_speed speed)
+{
+	struct uhub_softc *sc;
+	struct usb_device *child;
+	struct usb_hub *hub;
+	struct usb_port *up;
+	uint8_t retval = 0;
+	uint8_t x;
+
+	if (udev == NULL)
+		goto done;
+	hub = udev->hub;
+	if (hub == NULL)
+		goto done;
+	sc = hub->hubsoftc;
+	if (sc == NULL)
+		goto done;
+
+	for (x = 0; x != hub->nports; x++) {
+		up = hub->ports + x;
+		child = usb_bus_port_get_device(udev->bus, up);
+		if (child != NULL &&
+		    child->flags.usb_mode == USB_MODE_HOST &&
+		    child->speed == speed)
+			retval++;
+	}
+done:
+	return (retval);
+}
+
+void
+uhub_explore_handle_re_enumerate(struct usb_device *child)
+{
+	uint8_t do_unlock;
+	usb_error_t err;
+
+	/* check if device should be re-enumerated */
+	if (child->flags.usb_mode != USB_MODE_HOST)
+		return;
+
+	do_unlock = usbd_enum_lock(child);
+	switch (child->re_enumerate_wait) {
+	case USB_RE_ENUM_START:
+		err = usbd_set_config_index(child,
+		    USB_UNCONFIG_INDEX);
+		if (err != 0) {
+			DPRINTF("Unconfigure failed: %s: Ignored.\n",
+			    usbd_errstr(err));
+		}
+		if (child->parent_hub == NULL) {
+			/* the root HUB cannot be re-enumerated */
+			DPRINTFN(6, "cannot reset root HUB\n");
+			err = 0;
+		} else {
+			err = usbd_req_re_enumerate(child, NULL);
+		}
+		if (err == 0)
+			err = usbd_set_config_index(child, 0);
+		if (err == 0) {
+			err = usb_probe_and_attach(child,
+			    USB_IFACE_INDEX_ANY);
+		}
+		child->re_enumerate_wait = USB_RE_ENUM_DONE;
+		break;
+
+	case USB_RE_ENUM_PWR_OFF:
+		/* get the device unconfigured */
+		err = usbd_set_config_index(child,
+		    USB_UNCONFIG_INDEX);
+		if (err) {
+			DPRINTFN(0, "Could not unconfigure "
+			    "device (ignored)\n");
+		}
+		if (child->parent_hub == NULL) {
+			/* the root HUB cannot be re-enumerated */
+			DPRINTFN(6, "cannot set port feature\n");
+			err = 0;
+		} else {
+			/* clear port enable */
+			err = usbd_req_clear_port_feature(child->parent_hub,
+			    NULL, child->port_no, UHF_PORT_ENABLE);
+			if (err) {
+				DPRINTFN(0, "Could not disable port "
+				    "(ignored)\n");
+			}
+		}
+		child->re_enumerate_wait = USB_RE_ENUM_DONE;
+		break;
+
+	case USB_RE_ENUM_SET_CONFIG:
+		err = usbd_set_config_index(child,
+		    child->next_config_index);
+		if (err != 0) {
+			DPRINTF("Configure failed: %s: Ignored.\n",
+			    usbd_errstr(err));
+		} else {
+			err = usb_probe_and_attach(child,
+			    USB_IFACE_INDEX_ANY);
+		}
+		child->re_enumerate_wait = USB_RE_ENUM_DONE;
+		break;
+
+	default:
+		child->re_enumerate_wait = USB_RE_ENUM_DONE;
+		break;
+	}
+	if (do_unlock)
+		usbd_enum_unlock(child);
+}
+
+/*------------------------------------------------------------------------*
  *	uhub_explore_sub - subroutine
  *
  * Return values:
@@ -239,33 +531,7 @@ uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up)
 		goto done;
 	}
 
-	/* check if device should be re-enumerated */
-
-	if (child->flags.usb_mode == USB_MODE_HOST) {
-		uint8_t do_unlock;
-		
-		do_unlock = usbd_enum_lock(child);
-		if (child->re_enumerate_wait) {
-			err = usbd_set_config_index(child,
-			    USB_UNCONFIG_INDEX);
-			if (err != 0) {
-				DPRINTF("Unconfigure failed: "
-				    "%s: Ignored.\n",
-				    usbd_errstr(err));
-			}
-			err = usbd_req_re_enumerate(child, NULL);
-			if (err == 0)
-				err = usbd_set_config_index(child, 0);
-			if (err == 0) {
-				err = usb_probe_and_attach(child,
-				    USB_IFACE_INDEX_ANY);
-			}
-			child->re_enumerate_wait = 0;
-			err = 0;
-		}
-		if (do_unlock)
-			usbd_enum_unlock(child);
-	}
+	uhub_explore_handle_re_enumerate(child);
 
 	/* check if probe and attach should be done */
 
@@ -522,7 +788,10 @@ repeat:
 	 *
 	 * NOTE: This part is currently FreeBSD specific.
 	 */
-	if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)
+	if (udev->parent_hub != NULL) {
+		/* inherit mode from the parent HUB */
+		mode = udev->parent_hub->flags.usb_mode;
+	} else if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)
 		mode = USB_MODE_DEVICE;
 	else
 		mode = USB_MODE_HOST;
@@ -1079,7 +1348,12 @@ uhub_attach(device_t dev)
 	hub->explore = &uhub_explore;
 	hub->nports = nports;
 	hub->hubudev = udev;
-
+#if USB_HAVE_TT_SUPPORT
+	hub->tt_msg[0].hdr.pm_callback = &uhub_reset_tt_proc;
+	hub->tt_msg[0].udev = udev;
+	hub->tt_msg[1].hdr.pm_callback = &uhub_reset_tt_proc;
+	hub->tt_msg[1].udev = udev;
+#endif
 	/* if self powered hub, give ports maximum current */
 	if (udev->flags.self_powered) {
 		hub->portpower = USB_MAX_POWER;
@@ -1181,11 +1455,9 @@ uhub_attach(device_t dev)
 
 	/* Start the interrupt endpoint, if any */
 
-	if (sc->sc_xfer[0] != NULL) {
-		mtx_lock(&sc->sc_mtx);
-		usbd_transfer_start(sc->sc_xfer[0]);
-		mtx_unlock(&sc->sc_mtx);
-	}
+	mtx_lock(&sc->sc_mtx);
+	usbd_transfer_start(sc->sc_xfer[UHUB_INTR_TRANSFER]);
+	mtx_unlock(&sc->sc_mtx);
 
 	/* Enable automatic power save on all USB HUBs */
 
@@ -1215,6 +1487,7 @@ uhub_detach(device_t dev)
 {
 	struct uhub_softc *sc = device_get_softc(dev);
 	struct usb_hub *hub = sc->sc_udev->hub;
+	struct usb_bus *bus = sc->sc_udev->bus;
 	struct usb_device *child;
 	uint8_t x;
 
@@ -1227,7 +1500,7 @@ uhub_detach(device_t dev)
 	/* Detach all ports */
 	for (x = 0; x != hub->nports; x++) {
 
-		child = usb_bus_port_get_device(sc->sc_udev->bus, hub->ports + x);
+		child = usb_bus_port_get_device(bus, hub->ports + x);
 
 		if (child == NULL) {
 			continue;
@@ -1239,6 +1512,13 @@ uhub_detach(device_t dev)
 		usb_free_device(child, 0);
 	}
 
+#if USB_HAVE_TT_SUPPORT
+	/* Make sure our TT messages are not queued anywhere */
+	USB_BUS_LOCK(bus);
+	usb_proc_mwait(&bus->non_giant_callback_proc,
+	    &hub->tt_msg[0], &hub->tt_msg[1]);
+	USB_BUS_UNLOCK(bus);
+#endif
 	free(hub, M_USBDEV);
 	sc->sc_udev->hub = NULL;
 
@@ -2070,9 +2350,10 @@ usbd_transfer_power_ref(struct usb_xfer *xfer, int val)
 static uint8_t
 usb_peer_should_wakeup(struct usb_device *udev)
 {
-	return ((udev->power_mode == USB_POWER_MODE_ON) ||
+	return (((udev->power_mode == USB_POWER_MODE_ON) &&
+	    (udev->flags.usb_mode == USB_MODE_HOST)) ||
 	    (udev->driver_added_refcount != udev->bus->driver_added_refcount) ||
-	    (udev->re_enumerate_wait != 0) ||
+	    (udev->re_enumerate_wait != USB_RE_ENUM_DONE) ||
 	    (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0) ||
 	    (udev->pwr_save.write_refs != 0) ||
 	    ((udev->pwr_save.read_refs != 0) &&
@@ -2488,6 +2769,8 @@ usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode)
 
 #if USB_HAVE_POWERD
 	usb_bus_power_update(udev->bus);
+#else
+	usb_needs_explore(udev->bus, 0 /* no probe */ );
 #endif
 }
 
@@ -2526,8 +2809,36 @@ usbd_filter_power_mode(struct usb_device *udev, uint8_t power_mode)
 void
 usbd_start_re_enumerate(struct usb_device *udev)
 {
-	if (udev->re_enumerate_wait == 0) {
-		udev->re_enumerate_wait = 1;
+	if (udev->re_enumerate_wait == USB_RE_ENUM_DONE) {
+		udev->re_enumerate_wait = USB_RE_ENUM_START;
 		usb_needs_explore(udev->bus, 0);
 	}
 }
+
+/*-----------------------------------------------------------------------*
+ *	usbd_start_set_config
+ *
+ * This function starts setting a USB configuration. This function
+ * does not need to be called BUS-locked. This function does not wait
+ * until the set USB configuratino is completed.
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_start_set_config(struct usb_device *udev, uint8_t index)
+{
+	if (udev->re_enumerate_wait == USB_RE_ENUM_DONE) {
+		if (udev->curr_config_index == index) {
+			/* no change needed */
+			return (0);
+		}
+		udev->next_config_index = index;
+		udev->re_enumerate_wait = USB_RE_ENUM_SET_CONFIG;
+		usb_needs_explore(udev->bus, 0);
+		return (0);
+	} else if (udev->re_enumerate_wait == USB_RE_ENUM_SET_CONFIG) {
+		if (udev->next_config_index == index) {
+			/* no change needed */
+			return (0);
+		}
+	}
+	return (USB_ERR_PENDING_REQUESTS);
+}
diff --git a/freebsd/sys/dev/usb/usb_hub.h b/freebsd/sys/dev/usb/usb_hub.h
index 23a1fa4..557a056 100644
--- a/freebsd/sys/dev/usb/usb_hub.h
+++ b/freebsd/sys/dev/usb/usb_hub.h
@@ -35,6 +35,9 @@ struct usb_port {
 #define	USB_RESTART_MAX 5
 	uint8_t	device_index;		/* zero means not valid */
 	enum usb_hc_mode usb_mode;	/* host or device mode */
+#if USB_HAVE_TT_SUPPORT
+	struct usb_device_request req_reset_tt __aligned(4);
+#endif
 };
 
 /*
@@ -44,6 +47,9 @@ struct usb_hub {
 	struct usb_device *hubudev;	/* the HUB device */
 	usb_error_t (*explore) (struct usb_device *hub);
 	void   *hubsoftc;
+#if USB_HAVE_TT_SUPPORT
+	struct usb_udev_msg tt_msg[2];
+#endif
 	usb_size_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];
 	uint16_t portpower;		/* mA per USB port */
 	uint8_t	isoc_last_time;
@@ -65,5 +71,6 @@ void	usb_bus_power_update(struct usb_bus *bus);
 void	usb_bus_powerd(struct usb_bus *bus);
 void	uhub_root_intr(struct usb_bus *, const uint8_t *, uint8_t);
 usb_error_t uhub_query_info(struct usb_device *, uint8_t *, uint8_t *);
+void	uhub_explore_handle_re_enumerate(struct usb_device *);
 
 #endif					/* _USB_HUB_H_ */
diff --git a/freebsd/sys/dev/usb/usb_ioctl.h b/freebsd/sys/dev/usb/usb_ioctl.h
index 9e66bd5..d5be169 100644
--- a/freebsd/sys/dev/usb/usb_ioctl.h
+++ b/freebsd/sys/dev/usb/usb_ioctl.h
@@ -30,6 +30,7 @@
 #define	_USB_IOCTL_H_
 
 #include <sys/ioccom.h>
+#include <sys/cdefs.h>
 
 /* Building "kdump" depends on these includes */
 
@@ -41,6 +42,16 @@
 #define	USB_GENERIC_NAME "ugen"
 #define	USB_TEMPLATE_SYSCTL "hw.usb.template"	/* integer type */
 
+/*
+ * Align IOCTL structures to hide differences when running 32-bit
+ * programs under 64-bit kernels:
+ */
+#ifdef COMPAT_32BIT
+#define	USB_IOCTL_STRUCT_ALIGN(n) __aligned(n)
+#else
+#define	USB_IOCTL_STRUCT_ALIGN(n)
+#endif
+
 /* Definition of valid template sysctl values */
 
 enum {
@@ -62,7 +73,7 @@ struct usb_read_dir {
 #endif
 	uint32_t urd_startentry;
 	uint32_t urd_maxlen;
-};
+} USB_IOCTL_STRUCT_ALIGN(8);
 
 struct usb_ctl_request {
 #ifdef COMPAT_32BIT
@@ -74,12 +85,12 @@ struct usb_ctl_request {
 	uint16_t ucr_actlen;		/* actual length transferred */
 	uint8_t	ucr_addr;		/* zero - currently not used */
 	struct usb_device_request ucr_request;
-};
+} USB_IOCTL_STRUCT_ALIGN(8);
 
 struct usb_alt_interface {
 	uint8_t	uai_interface_index;
 	uint8_t	uai_alt_index;
-};
+} USB_IOCTL_STRUCT_ALIGN(1);
 
 struct usb_gen_descriptor {
 #ifdef COMPAT_32BIT
@@ -98,7 +109,7 @@ struct usb_gen_descriptor {
 	uint8_t	ugd_endpt_index;
 	uint8_t	ugd_report_type;
 	uint8_t	reserved[8];
-};
+} USB_IOCTL_STRUCT_ALIGN(8);
 
 struct usb_device_info {
 	uint16_t udi_productNo;
@@ -127,24 +138,33 @@ struct usb_device_info {
 	char	udi_vendor[128];
 	char	udi_serial[64];
 	char	udi_release[8];
-};
+} USB_IOCTL_STRUCT_ALIGN(2);
+
+#define	USB_DEVICE_PORT_PATH_MAX 32
+
+struct usb_device_port_path {
+	uint8_t udp_bus;		/* which bus we are on */
+	uint8_t udp_index;		/* which device index */
+	uint8_t udp_port_level;		/* how many levels: 0, 1, 2 ... */
+	uint8_t udp_port_no[USB_DEVICE_PORT_PATH_MAX];
+} USB_IOCTL_STRUCT_ALIGN(1);
 
 struct usb_device_stats {
 	uint32_t uds_requests_ok[4];	/* Indexed by transfer type UE_XXX */
 	uint32_t uds_requests_fail[4];	/* Indexed by transfer type UE_XXX */
-};
+} USB_IOCTL_STRUCT_ALIGN(4);
 
 struct usb_fs_start {
 	uint8_t	ep_index;
-};
+} USB_IOCTL_STRUCT_ALIGN(1);
 
 struct usb_fs_stop {
 	uint8_t	ep_index;
-};
+} USB_IOCTL_STRUCT_ALIGN(1);
 
 struct usb_fs_complete {
 	uint8_t	ep_index;
-};
+} USB_IOCTL_STRUCT_ALIGN(1);
 
 /* This structure is used for all endpoint types */
 struct usb_fs_endpoint {
@@ -177,7 +197,7 @@ struct usb_fs_endpoint {
 	/* timeout value for no timeout */
 #define	USB_FS_TIMEOUT_NONE 0
 	int	status;			/* see USB_ERR_XXX */
-};
+} USB_IOCTL_STRUCT_ALIGN(8);
 
 struct usb_fs_init {
 	/* userland pointer to endpoints structure */
@@ -188,11 +208,11 @@ struct usb_fs_init {
 #endif
 	/* maximum number of endpoints */
 	uint8_t	ep_index_max;
-};
+} USB_IOCTL_STRUCT_ALIGN(8);
 
 struct usb_fs_uninit {
 	uint8_t	dummy;			/* zero */
-};
+} USB_IOCTL_STRUCT_ALIGN(1);
 
 struct usb_fs_open {
 #define	USB_FS_MAX_BUFSIZE (1 << 18)
@@ -204,15 +224,20 @@ struct usb_fs_open {
 	uint8_t	dev_index;		/* currently unused */
 	uint8_t	ep_index;
 	uint8_t	ep_no;			/* bEndpointNumber */
-};
+} USB_IOCTL_STRUCT_ALIGN(4);
+
+struct usb_fs_open_stream {
+	struct usb_fs_open fs_open;
+	uint16_t stream_id;		/* stream ID */
+} USB_IOCTL_STRUCT_ALIGN(4);
 
 struct usb_fs_close {
 	uint8_t	ep_index;
-};
+} USB_IOCTL_STRUCT_ALIGN(1);
 
 struct usb_fs_clear_stall_sync {
 	uint8_t	ep_index;
-};
+} USB_IOCTL_STRUCT_ALIGN(1);
 
 struct usb_gen_quirk {
 	uint16_t index;			/* Quirk Index */
@@ -222,11 +247,11 @@ struct usb_gen_quirk {
 	uint16_t bcdDeviceHigh;		/* High Device Revision */
 	uint16_t reserved[2];
 	/*
-	 * String version of quirk including terminating zero. See UQ_XXX in
-	 * "usb_quirk.h".
+	 * String version of quirk including terminating zero. See
+	 * UQ_XXX in "usb_quirk.h".
 	 */
 	char	quirkname[64 - 14];
-};
+} USB_IOCTL_STRUCT_ALIGN(2);
 
 /* USB controller */
 #define	USB_REQUEST		_IOWR('U', 1, struct usb_ctl_request)
@@ -270,7 +295,8 @@ struct usb_gen_quirk {
 #define	USB_IFACE_DRIVER_DETACH	_IOW ('U', 125, int)
 #define	USB_GET_PLUGTIME	_IOR ('U', 126, uint32_t)
 #define	USB_READ_DIR		_IOW ('U', 127, struct usb_read_dir)
-/* 128 - 134 unused */
+/* 128 - 133 unused */
+#define	USB_GET_DEV_PORT_PATH	_IOR ('U', 134, struct usb_device_port_path)
 #define	USB_GET_POWER_USAGE	_IOR ('U', 135, int)
 #define	USB_SET_TX_FORCE_SHORT	_IOW ('U', 136, int)
 #define	USB_SET_TX_TIMEOUT	_IOW ('U', 137, int)
diff --git a/freebsd/sys/dev/usb/usb_msctest.c b/freebsd/sys/dev/usb/usb_msctest.c
index fcb9f02..4d28346 100644
--- a/freebsd/sys/dev/usb/usb_msctest.c
+++ b/freebsd/sys/dev/usb/usb_msctest.c
@@ -85,7 +85,7 @@ enum {
 	DIR_NONE,
 };
 
-#define	SCSI_MAX_LEN	0x100
+#define	SCSI_MAX_LEN	MAX(0x100, BULK_SIZE)
 #define	SCSI_INQ_LEN	0x24
 #define	SCSI_SENSE_LEN	0xFF
 
@@ -141,8 +141,8 @@ struct bbb_csw {
 struct bbb_transfer {
 	struct mtx mtx;
 	struct cv cv;
-	struct bbb_cbw cbw;
-	struct bbb_csw csw;
+	struct bbb_cbw *cbw;
+	struct bbb_csw *csw;
 
 	struct usb_xfer *xfer[ST_MAX];
 
@@ -152,6 +152,7 @@ struct bbb_transfer {
 	usb_size_t data_rem;		/* bytes */
 	usb_timeout_t data_timeout;	/* ms */
 	usb_frlength_t actlen;		/* bytes */
+	usb_frlength_t buffer_size;    	/* bytes */
 
 	uint8_t	cmd_len;		/* bytes */
 	uint8_t	dir;
@@ -160,7 +161,7 @@ struct bbb_transfer {
 	uint8_t	status_try;
 	int	error;
 
-	uint8_t	buffer[SCSI_MAX_LEN] __aligned(4);
+	uint8_t	*buffer;
 };
 
 static usb_callback_t bbb_command_callback;
@@ -186,7 +187,6 @@ static const struct usb_config bbb_config[ST_MAX] = {
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_OUT,
 		.bufsize = sizeof(struct bbb_cbw),
-		.flags = {.ext_buffer = 1,},
 		.callback = &bbb_command_callback,
 		.timeout = 4 * USB_MS_HZ,	/* 4 seconds */
 	},
@@ -195,8 +195,8 @@ static const struct usb_config bbb_config[ST_MAX] = {
 		.type = UE_BULK,
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_IN,
-		.bufsize = BULK_SIZE,
-		.flags = {.ext_buffer = 1,.proxy_buffer = 1,.short_xfer_ok = 1,},
+		.bufsize = SCSI_MAX_LEN,
+		.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
 		.callback = &bbb_data_read_callback,
 		.timeout = 4 * USB_MS_HZ,	/* 4 seconds */
 	},
@@ -214,7 +214,7 @@ static const struct usb_config bbb_config[ST_MAX] = {
 		.type = UE_BULK,
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_OUT,
-		.bufsize = BULK_SIZE,
+		.bufsize = SCSI_MAX_LEN,
 		.flags = {.ext_buffer = 1,.proxy_buffer = 1,},
 		.callback = &bbb_data_write_callback,
 		.timeout = 4 * USB_MS_HZ,	/* 4 seconds */
@@ -234,7 +234,7 @@ static const struct usb_config bbb_config[ST_MAX] = {
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_IN,
 		.bufsize = sizeof(struct bbb_csw),
-		.flags = {.ext_buffer = 1,.short_xfer_ok = 1,},
+		.flags = {.short_xfer_ok = 1,},
 		.callback = &bbb_status_callback,
 		.timeout = 1 * USB_MS_HZ,	/* 1 second  */
 	},
@@ -243,7 +243,6 @@ static const struct usb_config bbb_config[ST_MAX] = {
 static void
 bbb_done(struct bbb_transfer *sc, int error)
 {
-
 	sc->error = error;
 	sc->state = ST_COMMAND;
 	sc->status_try = 1;
@@ -292,18 +291,19 @@ bbb_command_callback(struct usb_xfer *xfer, usb_error_t error)
 
 	case USB_ST_SETUP:
 		sc->status_try = 0;
-		tag = UGETDW(sc->cbw.dCBWTag) + 1;
-		USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE);
-		USETDW(sc->cbw.dCBWTag, tag);
-		USETDW(sc->cbw.dCBWDataTransferLength, (uint32_t)sc->data_len);
-		sc->cbw.bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT);
-		sc->cbw.bCBWLUN = sc->lun;
-		sc->cbw.bCDBLength = sc->cmd_len;
-		if (sc->cbw.bCDBLength > sizeof(sc->cbw.CBWCDB)) {
-			sc->cbw.bCDBLength = sizeof(sc->cbw.CBWCDB);
+		tag = UGETDW(sc->cbw->dCBWTag) + 1;
+		USETDW(sc->cbw->dCBWSignature, CBWSIGNATURE);
+		USETDW(sc->cbw->dCBWTag, tag);
+		USETDW(sc->cbw->dCBWDataTransferLength, (uint32_t)sc->data_len);
+		sc->cbw->bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT);
+		sc->cbw->bCBWLUN = sc->lun;
+		sc->cbw->bCDBLength = sc->cmd_len;
+		if (sc->cbw->bCDBLength > sizeof(sc->cbw->CBWCDB)) {
+			sc->cbw->bCDBLength = sizeof(sc->cbw->CBWCDB);
 			DPRINTFN(0, "Truncating long command\n");
 		}
-		usbd_xfer_set_frame_data(xfer, 0, &sc->cbw, sizeof(sc->cbw));
+		usbd_xfer_set_frame_len(xfer, 0,
+		    sizeof(struct bbb_cbw));
 		usbd_transfer_submit(xfer);
 		break;
 
@@ -390,7 +390,7 @@ bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error)
 
 		if (sc->data_rem == 0) {
 			bbb_transfer_start(sc, ST_STATUS);
-			return;
+			break;
 		}
 		if (max_bulk > sc->data_rem) {
 			max_bulk = sc->data_rem;
@@ -398,7 +398,7 @@ bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error)
 		usbd_xfer_set_timeout(xfer, sc->data_timeout);
 		usbd_xfer_set_frame_data(xfer, 0, sc->data_ptr, max_bulk);
 		usbd_transfer_submit(xfer);
-		return;
+		break;
 
 	default:			/* Error */
 		if (error == USB_ERR_CANCELLED) {
@@ -406,8 +406,7 @@ bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error)
 		} else {
 			bbb_transfer_start(sc, ST_DATA_WR_CS);
 		}
-		return;
-
+		break;
 	}
 }
 
@@ -432,9 +431,9 @@ bbb_status_callback(struct usb_xfer *xfer, usb_error_t error)
 
 		/* very simple status check */
 
-		if (actlen < (int)sizeof(sc->csw)) {
+		if (actlen < (int)sizeof(struct bbb_csw)) {
 			bbb_done(sc, USB_ERR_SHORT_XFER);
-		} else if (sc->csw.bCSWStatus == CSWSTATUS_GOOD) {
+		} else if (sc->csw->bCSWStatus == CSWSTATUS_GOOD) {
 			bbb_done(sc, 0);	/* success */
 		} else {
 			bbb_done(sc, ERR_CSW_FAILED);	/* error */
@@ -442,7 +441,8 @@ bbb_status_callback(struct usb_xfer *xfer, usb_error_t error)
 		break;
 
 	case USB_ST_SETUP:
-		usbd_xfer_set_frame_data(xfer, 0, &sc->csw, sizeof(sc->csw));
+		usbd_xfer_set_frame_len(xfer, 0,
+		    sizeof(struct bbb_csw));
 		usbd_transfer_submit(xfer);
 		break;
 
@@ -480,9 +480,9 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
 	sc->data_timeout = (data_timeout + USB_MS_HZ);
 	sc->actlen = 0;
 	sc->cmd_len = cmd_len;
-	memset(&sc->cbw.CBWCDB, 0, sizeof(sc->cbw.CBWCDB));
-	memcpy(&sc->cbw.CBWCDB, cmd_ptr, cmd_len);
-	DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw.CBWCDB, ":");
+	memset(&sc->cbw->CBWCDB, 0, sizeof(sc->cbw->CBWCDB));
+	memcpy(&sc->cbw->CBWCDB, cmd_ptr, cmd_len);
+	DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw->CBWCDB, ":");
 
 	mtx_lock(&sc->mtx);
 	usbd_transfer_start(sc->xfer[sc->state]);
@@ -551,6 +551,16 @@ bbb_attach(struct usb_device *udev, uint8_t iface_index)
 		bbb_detach(sc);
 		return (NULL);
 	}
+	/* store pointer to DMA buffers */
+	sc->buffer = usbd_xfer_get_frame_buffer(
+	    sc->xfer[ST_DATA_RD], 0);
+	sc->buffer_size =
+	    usbd_xfer_max_len(sc->xfer[ST_DATA_RD]);
+	sc->cbw = usbd_xfer_get_frame_buffer(
+	    sc->xfer[ST_COMMAND], 0);
+	sc->csw = usbd_xfer_get_frame_buffer(
+	    sc->xfer[ST_STATUS], 0);
+
 	return (sc);
 }
 
@@ -826,8 +836,8 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
 		 * TCTMobile needs DIR_IN flag. To get it, we
 		 * supply a dummy data with the command.
 		 */
-		err = bbb_command_start(sc, DIR_IN, 0, &sc->buffer,
-		    sizeof(sc->buffer), &scsi_tct_eject,
+		err = bbb_command_start(sc, DIR_IN, 0, sc->buffer,
+		    sc->buffer_size, &scsi_tct_eject,
 		    sizeof(scsi_tct_eject), USB_MS_HZ);
 		break;
 	default:
diff --git a/freebsd/sys/dev/usb/usb_process.c b/freebsd/sys/dev/usb/usb_process.c
index 59b2656..d36df36 100644
--- a/freebsd/sys/dev/usb/usb_process.c
+++ b/freebsd/sys/dev/usb/usb_process.c
@@ -503,3 +503,15 @@ usb_proc_rewakeup(struct usb_process *up)
 		cv_signal(&up->up_cv);
 	}
 }
+
+/*------------------------------------------------------------------------*
+ *	usb_proc_is_called_from
+ *
+ * This function will return non-zero if called from inside the USB
+ * process passed as first argument. Else this function returns zero.
+ *------------------------------------------------------------------------*/
+int
+usb_proc_is_called_from(struct usb_process *up)
+{
+	return (up->up_curtd == curthread);
+}
diff --git a/freebsd/sys/dev/usb/usb_process.h b/freebsd/sys/dev/usb/usb_process.h
index 9b1a853..06feee8 100644
--- a/freebsd/sys/dev/usb/usb_process.h
+++ b/freebsd/sys/dev/usb/usb_process.h
@@ -79,6 +79,7 @@ void	usb_proc_mwait(struct usb_process *up, void *pm0, void *pm1);
 void	usb_proc_free(struct usb_process *up);
 void   *usb_proc_msignal(struct usb_process *up, void *pm0, void *pm1);
 void	usb_proc_rewakeup(struct usb_process *up);
+int	usb_proc_is_called_from(struct usb_process *up);
 
 void	usb_proc_explore_mwait(struct usb_device *, void *, void *);
 void   *usb_proc_explore_msignal(struct usb_device *, void *, void *);
diff --git a/freebsd/sys/dev/usb/usb_request.c b/freebsd/sys/dev/usb/usb_request.c
index 167a722..e9137bd 100644
--- a/freebsd/sys/dev/usb/usb_request.c
+++ b/freebsd/sys/dev/usb/usb_request.c
@@ -50,7 +50,6 @@
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_ioctl.h>
 #include <dev/usb/usbhid.h>
 
 #define	USB_DEBUG_VAR usb_debug
@@ -74,6 +73,11 @@ static int usb_no_cs_fail;
 SYSCTL_INT(_hw_usb, OID_AUTO, no_cs_fail, CTLFLAG_RW,
     &usb_no_cs_fail, 0, "USB clear stall failures are ignored, if set");
 
+static int usb_full_ddesc;
+
+SYSCTL_INT(_hw_usb, OID_AUTO, full_ddesc, CTLFLAG_RW,
+    &usb_full_ddesc, 0, "USB always read complete device descriptor, if set");
+
 #ifdef USB_DEBUG
 #ifdef USB_REQ_DEBUG
 /* The following structures are used in connection to fault injection. */
@@ -712,6 +716,17 @@ done:
 	if ((mtx != NULL) && (mtx != &Giant))
 		mtx_lock(mtx);
 
+	switch (err) {
+	case USB_ERR_NORMAL_COMPLETION:
+	case USB_ERR_SHORT_XFER:
+	case USB_ERR_STALLED:
+	case USB_ERR_CANCELLED:
+		break;
+	default:
+		DPRINTF("I/O error - waiting a bit for TT cleanup\n");
+		usb_pause_mtx(mtx, hz / 16);
+		break;
+	}
 	return ((usb_error_t)err);
 }
 
@@ -999,7 +1014,7 @@ usbd_req_get_desc(struct usb_device *udev,
 		USETW(req.wLength, min_len);
 
 		err = usbd_do_request_flags(udev, mtx, &req,
-		    desc, 0, NULL, 1000);
+		    desc, 0, NULL, 500 /* ms */);
 
 		if (err) {
 			if (!retries) {
@@ -1884,32 +1899,41 @@ usbd_setup_device_desc(struct usb_device *udev, struct mtx *mtx)
 	 */
 	switch (udev->speed) {
 	case USB_SPEED_FULL:
-	case USB_SPEED_LOW:
+		if (usb_full_ddesc != 0) {
+			/* get full device descriptor */
+			err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc);
+			if (err == 0)
+				break;
+		}
+
+		/* get partial device descriptor, some devices crash on this */
 		err = usbd_req_get_desc(udev, mtx, NULL, &udev->ddesc,
 		    USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0);
-		if (err != 0) {
-			DPRINTFN(0, "getting device descriptor "
-			    "at addr %d failed, %s\n", udev->address,
-			    usbd_errstr(err));
-			return (err);
-		}
+		if (err != 0)
+			break;
+
+		/* get the full device descriptor */
+		err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc);
 		break;
+
 	default:
 		DPRINTF("Minimum MaxPacketSize is large enough "
-		    "to hold the complete device descriptor\n");
-		break;
-	}
-
-	/* get the full device descriptor */
-	err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc);
+		    "to hold the complete device descriptor or "
+		    "only once MaxPacketSize choice\n");
 
-	/* try one more time, if error */
-	if (err)
+		/* get the full device descriptor */
 		err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc);
 
-	if (err) {
-		DPRINTF("addr=%d, getting full desc failed\n",
-		    udev->address);
+		/* try one more time, if error */
+		if (err != 0)
+			err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc);
+		break;
+	}
+
+	if (err != 0) {
+		DPRINTFN(0, "getting device descriptor "
+		    "at addr %d failed, %s\n", udev->address,
+		    usbd_errstr(err));
 		return (err);
 	}
 
@@ -1954,6 +1978,7 @@ usbd_req_re_enumerate(struct usb_device *udev, struct mtx *mtx)
 		return (USB_ERR_INVAL);
 	}
 retry:
+#if USB_HAVE_TT_SUPPORT
 	/*
 	 * Try to reset the High Speed parent HUB of a LOW- or FULL-
 	 * speed device, if any.
@@ -1961,15 +1986,24 @@ retry:
 	if (udev->parent_hs_hub != NULL &&
 	    udev->speed != USB_SPEED_HIGH) {
 		DPRINTF("Trying to reset parent High Speed TT.\n");
-		err = usbd_req_reset_tt(udev->parent_hs_hub, NULL,
-		    udev->hs_port_no);
+		if (udev->parent_hs_hub == parent_hub &&
+		    (uhub_count_active_host_ports(parent_hub, USB_SPEED_LOW) +
+		     uhub_count_active_host_ports(parent_hub, USB_SPEED_FULL)) == 1) {
+			/* we can reset the whole TT */
+			err = usbd_req_reset_tt(parent_hub, NULL,
+			    udev->hs_port_no);
+		} else {
+			/* only reset a particular device and endpoint */
+			err = usbd_req_clear_tt_buffer(udev->parent_hs_hub, NULL,
+			    udev->hs_port_no, old_addr, UE_CONTROL, 0);
+		}
 		if (err) {
 			DPRINTF("Resetting parent High "
 			    "Speed TT failed (%s).\n",
 			    usbd_errstr(err));
 		}
 	}
-
+#endif
 	/* Try to warm reset first */
 	if (parent_hub->speed == USB_SPEED_SUPER)
 		usbd_req_warm_reset_port(parent_hub, mtx, udev->port_no);
diff --git a/freebsd/sys/dev/usb/usb_transfer.c b/freebsd/sys/dev/usb/usb_transfer.c
index b252818..205a72f 100644
--- a/freebsd/sys/dev/usb/usb_transfer.c
+++ b/freebsd/sys/dev/usb/usb_transfer.c
@@ -334,6 +334,7 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm)
 	usb_frcount_t n_frlengths;
 	usb_frcount_t n_frbuffers;
 	usb_frcount_t x;
+	uint16_t maxp_old;
 	uint8_t type;
 	uint8_t zmps;
 
@@ -419,6 +420,11 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm)
 	if (xfer->max_packet_count > parm->hc_max_packet_count) {
 		xfer->max_packet_count = parm->hc_max_packet_count;
 	}
+
+	/* store max packet size value before filtering */
+
+	maxp_old = xfer->max_packet_size;
+
 	/* filter "wMaxPacketSize" according to HC capabilities */
 
 	if ((xfer->max_packet_size > parm->hc_max_packet_size) ||
@@ -451,6 +457,13 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm)
 		}
 	}
 
+	/*
+	 * Check if the max packet size was outside its allowed range
+	 * and clamped to a valid value:
+	 */
+	if (maxp_old != xfer->max_packet_size)
+		xfer->flags_int.maxp_was_clamped = 1;
+	
 	/* compute "max_frame_size" */
 
 	usbd_update_max_frame_size(xfer);
@@ -2396,7 +2409,9 @@ usbd_transfer_enqueue(struct usb_xfer_queue *pq, struct usb_xfer *xfer)
 void
 usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error)
 {
-	USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
+	struct usb_xfer_root *info = xfer->xroot;
+
+	USB_BUS_LOCK_ASSERT(info->bus, MA_OWNED);
 
 	DPRINTF("err=%s\n", usbd_errstr(error));
 
@@ -2410,10 +2425,10 @@ usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error)
 		xfer->flags_int.control_act = 0;
 		return;
 	}
-	/* only set transfer error if not already set */
-	if (!xfer->error) {
+	/* only set transfer error, if not already set */
+	if (xfer->error == USB_ERR_NORMAL_COMPLETION)
 		xfer->error = error;
-	}
+
 	/* stop any callouts */
 	usb_callout_stop(&xfer->timeout_handle);
 
@@ -2425,14 +2440,14 @@ usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error)
 	usbd_transfer_dequeue(xfer);
 
 #if USB_HAVE_BUSDMA
-	if (mtx_owned(xfer->xroot->xfer_mtx)) {
+	if (mtx_owned(info->xfer_mtx)) {
 		struct usb_xfer_queue *pq;
 
 		/*
 		 * If the private USB lock is not locked, then we assume
 		 * that the BUS-DMA load stage has been passed:
 		 */
-		pq = &xfer->xroot->dma_q;
+		pq = &info->dma_q;
 
 		if (pq->curr == xfer) {
 			/* start the next BUS-DMA load, if any */
@@ -2442,10 +2457,10 @@ usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error)
 #endif
 	/* keep some statistics */
 	if (xfer->error) {
-		xfer->xroot->bus->stats_err.uds_requests
+		info->bus->stats_err.uds_requests
 		    [xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE]++;
 	} else {
-		xfer->xroot->bus->stats_ok.uds_requests
+		info->bus->stats_ok.uds_requests
 		    [xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE]++;
 	}
 
@@ -2685,7 +2700,7 @@ usbd_transfer_timeout_ms(struct usb_xfer *xfer,
 
 	/* defer delay */
 	usb_callout_reset(&xfer->timeout_handle,
-	    USB_MS_TO_TICKS(ms), cb, xfer);
+	    USB_MS_TO_TICKS(ms) + USB_CALLOUT_ZERO_TICKS, cb, xfer);
 }
 
 /*------------------------------------------------------------------------*
@@ -2811,6 +2826,22 @@ usbd_callback_wrapper_sub(struct usb_xfer *xfer)
 		/* end of control transfer, if any */
 		xfer->flags_int.control_act = 0;
 
+#if USB_HAVE_TT_SUPPORT
+		switch (xfer->error) {
+		case USB_ERR_NORMAL_COMPLETION:
+		case USB_ERR_SHORT_XFER:
+		case USB_ERR_STALLED:
+		case USB_ERR_CANCELLED:
+			/* nothing to do */
+			break;
+		default:
+			/* try to reset the TT, if any */
+			USB_BUS_LOCK(bus);
+			uhub_tt_buffer_reset_async_locked(xfer->xroot->udev, xfer->endpoint);
+			USB_BUS_UNLOCK(bus);
+			break;
+		}
+#endif
 		/* check if we should block the execution queue */
 		if ((xfer->error != USB_ERR_CANCELLED) &&
 		    (xfer->flags.pipe_bof)) {
@@ -3377,3 +3408,13 @@ usbd_xfer_get_timestamp(struct usb_xfer *xfer)
 {
 	return (xfer->isoc_time_complete);
 }
+
+/*
+ * The following function returns non-zero if the max packet size
+ * field was clamped to a valid value. Else it returns zero.
+ */
+uint8_t
+usbd_xfer_maxp_was_clamped(struct usb_xfer *xfer)
+{
+	return (xfer->flags_int.maxp_was_clamped);
+}
diff --git a/freebsd/sys/dev/usb/usbdi.h b/freebsd/sys/dev/usb/usbdi.h
index 245777f..6ec26a4 100644
--- a/freebsd/sys/dev/usb/usbdi.h
+++ b/freebsd/sys/dev/usb/usbdi.h
@@ -558,6 +558,7 @@ int	usbd_xfer_is_stalled(struct usb_xfer *xfer);
 void	usbd_xfer_set_flag(struct usb_xfer *xfer, int flag);
 void	usbd_xfer_clr_flag(struct usb_xfer *xfer, int flag);
 uint16_t usbd_xfer_get_timestamp(struct usb_xfer *xfer);
+uint8_t usbd_xfer_maxp_was_clamped(struct usb_xfer *xfer);
 
 void	usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset,
 	    const void *ptr, usb_frlength_t len);
@@ -574,6 +575,8 @@ void	usbd_m_copy_in(struct usb_page_cache *cache, usb_frlength_t dst_offset,
 void	usbd_frame_zero(struct usb_page_cache *cache, usb_frlength_t offset,
 	    usb_frlength_t len);
 void	usbd_start_re_enumerate(struct usb_device *udev);
+usb_error_t
+	usbd_start_set_config(struct usb_device *, uint8_t);
 
 int	usb_fifo_attach(struct usb_device *udev, void *priv_sc,
 	    struct mtx *priv_mtx, struct usb_fifo_methods *pm,
diff --git a/freebsd/sys/i386/include/machine/specialreg.h b/freebsd/sys/i386/include/machine/specialreg.h
index 3ca5e7a..be36a91 100644
--- a/freebsd/sys/i386/include/machine/specialreg.h
+++ b/freebsd/sys/i386/include/machine/specialreg.h
@@ -180,9 +180,15 @@
 #define	AMDID2_WDT	0x00002000
 #define	AMDID2_LWP	0x00008000
 #define	AMDID2_FMA4	0x00010000
+#define	AMDID2_TCE	0x00020000
 #define	AMDID2_NODE_ID	0x00080000
 #define	AMDID2_TBM	0x00200000
 #define	AMDID2_TOPOLOGY	0x00400000
+#define	AMDID2_PCXC	0x00800000
+#define	AMDID2_PNXC	0x01000000
+#define	AMDID2_DBE	0x04000000
+#define	AMDID2_PTSC	0x08000000
+#define	AMDID2_PTSCEL2I	0x10000000
 
 /*
  * CPUID instruction 1 eax info
diff --git a/freebsd/sys/kern/init_main.c b/freebsd/sys/kern/init_main.c
index 88f5f68..f8d04f2 100644
--- a/freebsd/sys/kern/init_main.c
+++ b/freebsd/sys/kern/init_main.c
@@ -250,9 +250,6 @@ restart:
 	/*
 	 * Traverse the (now) ordered list of system initialization tasks.
 	 * Perform each task, and continue on to the next task.
-	 *
-	 * The last item on the list is expected to be the scheduler,
-	 * which will not return.
 	 */
 	for (sipp = sysinit; sipp < sysinit_end; sipp++) {
 
@@ -312,8 +309,14 @@ restart:
 #endif /* __rtems__ */
 	}
 
+	mtx_assert(&Giant, MA_OWNED | MA_NOTRECURSED);
+	mtx_unlock(&Giant);
+
 #ifndef __rtems__
-	panic("Shouldn't get here!");
+	/*
+	 * Now hand over this thread to swapper.
+	 */
+	swapper();
 	/* NOTREACHED*/
 #endif /* __rtems__ */
 }
@@ -358,7 +361,7 @@ static char wit_warn[] =
      "WARNING: WITNESS option enabled, expect reduced performance.\n";
 SYSINIT(witwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 1,
    print_caddr_t, wit_warn);
-SYSINIT(witwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 1,
+SYSINIT(witwarn2, SI_SUB_LAST, SI_ORDER_THIRD + 1,
    print_caddr_t, wit_warn);
 #endif
 
@@ -367,7 +370,7 @@ static char diag_warn[] =
      "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n";
 SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 2,
     print_caddr_t, diag_warn);
-SYSINIT(diagwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 2,
+SYSINIT(diagwarn2, SI_SUB_LAST, SI_ORDER_THIRD + 2,
     print_caddr_t, diag_warn);
 #endif
 
@@ -494,6 +497,7 @@ proc0_init(void *dummy __unused)
 
 	p->p_sysent = &null_sysvec;
 	p->p_flag = P_SYSTEM | P_INMEM;
+	p->p_flag2 = 0;
 	p->p_state = PRS_NORMAL;
 	knlist_init_mtx(&p->p_klist, &p->p_mtx);
 	STAILQ_INIT(&p->p_ktr);
diff --git a/freebsd/sys/kern/kern_event.c b/freebsd/sys/kern/kern_event.c
index 69c4724..89cd176 100644
--- a/freebsd/sys/kern/kern_event.c
+++ b/freebsd/sys/kern/kern_event.c
@@ -464,8 +464,11 @@ filt_proc(struct knote *kn, long hint)
 		if (!(kn->kn_status & KN_DETACHED))
 			knlist_remove_inevent(&p->p_klist, kn);
 		kn->kn_flags |= (EV_EOF | EV_ONESHOT);
-		kn->kn_data = p->p_xstat;
 		kn->kn_ptr.p_proc = NULL;
+		if (kn->kn_fflags & NOTE_EXIT)
+			kn->kn_data = p->p_xstat;
+		if (kn->kn_fflags == 0)
+			kn->kn_flags |= EV_DROP;
 		return (1);
 	}
 
@@ -497,7 +500,7 @@ knote_fork(struct knlist *list, int pid)
 			continue;
 		kq = kn->kn_kq;
 		KQ_LOCK(kq);
-		if ((kn->kn_status & KN_INFLUX) == KN_INFLUX) {
+		if ((kn->kn_status & (KN_INFLUX | KN_SCAN)) == KN_INFLUX) {
 			KQ_UNLOCK(kq);
 			continue;
 		}
@@ -507,7 +510,7 @@ knote_fork(struct knlist *list, int pid)
 		 */
 		if ((kn->kn_sfflags & NOTE_TRACK) == 0) {
 			kn->kn_status |= KN_HASKQLOCK;
-			if (kn->kn_fop->f_event(kn, NOTE_FORK | pid))
+			if (kn->kn_fop->f_event(kn, NOTE_FORK))
 				KNOTE_ACTIVATE(kn, 1);
 			kn->kn_status &= ~KN_HASKQLOCK;
 			KQ_UNLOCK(kq);
@@ -535,10 +538,10 @@ knote_fork(struct knlist *list, int pid)
 		kev.data = kn->kn_id;		/* parent */
 		kev.udata = kn->kn_kevent.udata;/* preserve udata */
 		error = kqueue_register(kq, &kev, NULL, 0);
-		if (kn->kn_fop->f_event(kn, NOTE_FORK | pid))
-			KNOTE_ACTIVATE(kn, 0);
 		if (error)
 			kn->kn_fflags |= NOTE_TRACKERR;
+		if (kn->kn_fop->f_event(kn, NOTE_FORK))
+			KNOTE_ACTIVATE(kn, 0);
 		KQ_LOCK(kq);
 		kn->kn_status &= ~KN_INFLUX;
 		KQ_UNLOCK_FLUX(kq);
@@ -753,11 +756,11 @@ sys_kqueue(struct thread *td, struct kqueue_args *uap)
 
 #ifndef __rtems__
 	FILEDESC_XLOCK(fdp);
-	SLIST_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list);
+	TAILQ_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list);
 	FILEDESC_XUNLOCK(fdp);
 #else /* __rtems__ */
 	rtems_libio_lock();
-	SLIST_INSERT_HEAD(&fd_kqlist, kq, kq_list);
+	TAILQ_INSERT_HEAD(&fd_kqlist, kq, kq_list);
 	rtems_libio_unlock();
 #endif /* __rtems__ */
 
@@ -1076,12 +1079,13 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa
 	struct file *fp;
 	struct knote *kn, *tkn;
 	int error, filt, event;
-	int haskqglobal;
+	int haskqglobal, filedesc_unlock;
 
 	fp = NULL;
 	kn = NULL;
 	error = 0;
 	haskqglobal = 0;
+	filedesc_unlock = 0;
 
 	filt = kev->filter;
 	fops = kqueue_fo_find(filt);
@@ -1125,6 +1129,13 @@ findkn:
 				goto done;
 			}
 
+			/*
+			 * Pre-lock the filedesc before the global
+			 * lock mutex, see the comment in
+			 * kqueue_close().
+			 */
+			FILEDESC_XLOCK(td->td_proc->p_fd);
+			filedesc_unlock = 1;
 			KQ_GLOBAL_LOCK(&kq_global, haskqglobal);
 		}
 
@@ -1154,6 +1165,10 @@ findkn:
 	/* knote is in the process of changing, wait for it to stablize. */
 	if (kn != NULL && (kn->kn_status & KN_INFLUX) == KN_INFLUX) {
 		KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal);
+		if (filedesc_unlock) {
+			FILEDESC_XUNLOCK(td->td_proc->p_fd);
+			filedesc_unlock = 0;
+		}
 		kq->kq_state |= KQ_FLUXWAIT;
 		msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqflxwt", 0);
 		if (fp != NULL) {
@@ -1229,7 +1244,7 @@ findkn:
 	 * but doing so will not reset any filter which has already been
 	 * triggered.
 	 */
-	kn->kn_status |= KN_INFLUX;
+	kn->kn_status |= KN_INFLUX | KN_SCAN;
 	KQ_UNLOCK(kq);
 	KN_LIST_LOCK(kn);
 	kn->kn_kevent.udata = kev->udata;
@@ -1252,7 +1267,7 @@ done_ev_add:
 	KQ_LOCK(kq);
 	if (event)
 		KNOTE_ACTIVATE(kn, 1);
-	kn->kn_status &= ~KN_INFLUX;
+	kn->kn_status &= ~(KN_INFLUX | KN_SCAN);
 	KN_LIST_UNLOCK(kn);
 
 	if ((kev->flags & EV_DISABLE) &&
@@ -1270,6 +1285,8 @@ done_ev_add:
 
 done:
 	KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal);
+	if (filedesc_unlock)
+		FILEDESC_XUNLOCK(td->td_proc->p_fd);
 	if (fp != NULL)
 		fdrop(fp, td);
 	if (tkn != NULL)
@@ -1541,7 +1558,21 @@ start:
 		KASSERT((kn->kn_status & KN_INFLUX) == 0,
 		    ("KN_INFLUX set when not suppose to be"));
 
-		if ((kn->kn_flags & EV_ONESHOT) == EV_ONESHOT) {
+		if ((kn->kn_flags & EV_DROP) == EV_DROP) {
+			kn->kn_status &= ~KN_QUEUED;
+			kn->kn_status |= KN_INFLUX;
+			kq->kq_count--;
+			KQ_UNLOCK(kq);
+			/*
+			 * We don't need to lock the list since we've marked
+			 * it _INFLUX.
+			 */
+			if (!(kn->kn_status & KN_DETACHED))
+				kn->kn_fop->f_detach(kn);
+			knote_drop(kn, td);
+			KQ_LOCK(kq);
+			continue;
+		} else if ((kn->kn_flags & EV_ONESHOT) == EV_ONESHOT) {
 			kn->kn_status &= ~KN_QUEUED;
 			kn->kn_status |= KN_INFLUX;
 			kq->kq_count--;
@@ -1557,7 +1588,7 @@ start:
 			KQ_LOCK(kq);
 			kn = NULL;
 		} else {
-			kn->kn_status |= KN_INFLUX;
+			kn->kn_status |= KN_INFLUX | KN_SCAN;
 			KQ_UNLOCK(kq);
 			if ((kn->kn_status & KN_KQUEUE) == KN_KQUEUE)
 				KQ_GLOBAL_LOCK(&kq_global, haskqglobal);
@@ -1566,7 +1597,8 @@ start:
 				KQ_LOCK(kq);
 				KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal);
 				kn->kn_status &=
-				    ~(KN_QUEUED | KN_ACTIVE | KN_INFLUX);
+				    ~(KN_QUEUED | KN_ACTIVE | KN_INFLUX |
+				    KN_SCAN);
 				kq->kq_count--;
 				KN_LIST_UNLOCK(kn);
 				influx = 1;
@@ -1596,7 +1628,7 @@ start:
 			} else
 				TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
 			
-			kn->kn_status &= ~(KN_INFLUX);
+			kn->kn_status &= ~(KN_INFLUX | KN_SCAN);
 			KN_LIST_UNLOCK(kn);
 			influx = 1;
 		}
@@ -1788,6 +1820,7 @@ kqueue_close(struct file *fp, struct thread *td)
 	struct knote *kn;
 	int i;
 	int error;
+	int filedesc_unlock;
 
 #ifdef __rtems__
 	/* FIXME: Move this to the RTEMS close() function */
@@ -1797,6 +1830,7 @@ kqueue_close(struct file *fp, struct thread *td)
 	if ((error = kqueue_acquire(fp, &kq)))
 		return error;
 
+	filedesc_unlock = 0;
 	KQ_LOCK(kq);
 
 	KASSERT((kq->kq_state & KQ_CLOSING) != KQ_CLOSING,
@@ -1863,12 +1897,24 @@ kqueue_close(struct file *fp, struct thread *td)
 	KQ_UNLOCK(kq);
 
 #ifndef __rtems__
-	FILEDESC_XLOCK(fdp);
-	SLIST_REMOVE(&fdp->fd_kqlist, kq, kqueue, kq_list);
-	FILEDESC_XUNLOCK(fdp);
+	/*
+	 * We could be called due to the knote_drop() doing fdrop(),
+	 * called from kqueue_register().  In this case the global
+	 * lock is owned, and filedesc sx is locked before, to not
+	 * take the sleepable lock after non-sleepable.
+	 */
+	if (!sx_xlocked(FILEDESC_LOCK(fdp))) {
+		FILEDESC_XLOCK(fdp);
+		filedesc_unlock = 1;
+	} else
+		filedesc_unlock = 0;
+	TAILQ_REMOVE(&fdp->fd_kqlist, kq, kq_list);
+	if (filedesc_unlock)
+		FILEDESC_XUNLOCK(fdp);
 #else /* __rtems__ */
+	(void)filedesc_unlock;
 	rtems_libio_lock();
-	SLIST_REMOVE(&fd_kqlist, kq, kqueue, kq_list);
+	TAILQ_REMOVE(&fd_kqlist, kq, kq_list);
 	rtems_libio_unlock();
 #endif /* __rtems__ */
 
@@ -1966,28 +2012,33 @@ knote(struct knlist *list, long hint, int lockflags)
 	 */
 	SLIST_FOREACH(kn, &list->kl_list, kn_selnext) {
 		kq = kn->kn_kq;
-		if ((kn->kn_status & KN_INFLUX) != KN_INFLUX) {
+		KQ_LOCK(kq);
+		if ((kn->kn_status & (KN_INFLUX | KN_SCAN)) == KN_INFLUX) {
+			/*
+			 * Do not process the influx notes, except for
+			 * the influx coming from the kq unlock in the
+			 * kqueue_scan().  In the later case, we do
+			 * not interfere with the scan, since the code
+			 * fragment in kqueue_scan() locks the knlist,
+			 * and cannot proceed until we finished.
+			 */
+			KQ_UNLOCK(kq);
+		} else if ((lockflags & KNF_NOKQLOCK) != 0) {
+			kn->kn_status |= KN_INFLUX;
+			KQ_UNLOCK(kq);
+			error = kn->kn_fop->f_event(kn, hint);
 			KQ_LOCK(kq);
-			if ((kn->kn_status & KN_INFLUX) == KN_INFLUX) {
-				KQ_UNLOCK(kq);
-			} else if ((lockflags & KNF_NOKQLOCK) != 0) {
-				kn->kn_status |= KN_INFLUX;
-				KQ_UNLOCK(kq);
-				error = kn->kn_fop->f_event(kn, hint);
-				KQ_LOCK(kq);
-				kn->kn_status &= ~KN_INFLUX;
-				if (error)
-					KNOTE_ACTIVATE(kn, 1);
-				KQ_UNLOCK_FLUX(kq);
-			} else {
-				kn->kn_status |= KN_HASKQLOCK;
-				if (kn->kn_fop->f_event(kn, hint))
-					KNOTE_ACTIVATE(kn, 1);
-				kn->kn_status &= ~KN_HASKQLOCK;
-				KQ_UNLOCK(kq);
-			}
+			kn->kn_status &= ~KN_INFLUX;
+			if (error)
+				KNOTE_ACTIVATE(kn, 1);
+			KQ_UNLOCK_FLUX(kq);
+		} else {
+			kn->kn_status |= KN_HASKQLOCK;
+			if (kn->kn_fop->f_event(kn, hint))
+				KNOTE_ACTIVATE(kn, 1);
+			kn->kn_status &= ~KN_HASKQLOCK;
+			KQ_UNLOCK(kq);
 		}
-		kq = NULL;
 	}
 	if ((lockflags & KNF_LISTLOCKED) == 0)
 		list->kl_unlock(list->kl_lockarg); 
@@ -2231,11 +2282,11 @@ knote_fdclose(struct thread *td, int fd)
 	 * since filedesc is locked.
 	 */
 #ifndef __rtems__
-	SLIST_FOREACH(kq, &fdp->fd_kqlist, kq_list) {
+	TAILQ_FOREACH(kq, &fdp->fd_kqlist, kq_list) {
 #else /* __rtems__ */
 	/* FIXME: Use separate lock? */
 	rtems_libio_lock();
-	SLIST_FOREACH(kq, &fd_kqlist, kq_list) {
+	TAILQ_FOREACH(kq, &fd_kqlist, kq_list) {
 #endif /* __rtems__ */
 		KQ_LOCK(kq);
 
diff --git a/freebsd/sys/kern/kern_linker.c b/freebsd/sys/kern/kern_linker.c
index b1b46d7..39664a8 100644
--- a/freebsd/sys/kern/kern_linker.c
+++ b/freebsd/sys/kern/kern_linker.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/module.h>
 #include <sys/mount.h>
 #include <sys/linker.h>
+#include <sys/eventhandler.h>
 #include <sys/fcntl.h>
 #include <sys/jail.h>
 #include <sys/libkern.h>
@@ -71,17 +72,6 @@ SYSCTL_INT(_debug, OID_AUTO, kld_debug, CTLFLAG_RW,
         &kld_debug, 0, "Set various levels of KLD debug");
 #endif
 
-#define	KLD_LOCK()		sx_xlock(&kld_sx)
-#define	KLD_UNLOCK()		sx_xunlock(&kld_sx)
-#define	KLD_DOWNGRADE()		sx_downgrade(&kld_sx)
-#define	KLD_LOCK_READ()		sx_slock(&kld_sx)
-#define	KLD_UNLOCK_READ()	sx_sunlock(&kld_sx)
-#define	KLD_LOCKED()		sx_xlocked(&kld_sx)
-#define	KLD_LOCK_ASSERT() do {						\
-	if (!cold)							\
-		sx_assert(&kld_sx, SX_XLOCKED);				\
-} while (0)
-
 /*
  * static char *linker_search_path(const char *name, struct mod_depend
  * *verinfo);
@@ -123,7 +113,8 @@ static int linker_no_more_classes = 0;
 #define	LINKER_GET_NEXT_FILE_ID(a) do {					\
 	linker_file_t lftmp;						\
 									\
-	KLD_LOCK_ASSERT();						\
+	if (!cold)							\
+		sx_assert(&kld_sx, SA_XLOCKED);				\
 retry:									\
 	TAILQ_FOREACH(lftmp, &linker_files, link) {			\
 		if (next_file_id == lftmp->id) {			\
@@ -210,6 +201,8 @@ linker_file_sysinit(linker_file_t lf)
 	KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n",
 	    lf->filename));
 
+	sx_assert(&kld_sx, SA_XLOCKED);
+
 	if (linker_file_lookup_set(lf, "sysinit_set", &start, &stop, NULL) != 0)
 		return;
 	/*
@@ -235,6 +228,7 @@ linker_file_sysinit(linker_file_t lf)
 	 * Traverse the (now) ordered list of system initialization tasks.
 	 * Perform each task, and continue on to the next task.
 	 */
+	sx_xunlock(&kld_sx);
 	mtx_lock(&Giant);
 	for (sipp = start; sipp < stop; sipp++) {
 		if ((*sipp)->subsystem == SI_SUB_DUMMY)
@@ -244,6 +238,7 @@ linker_file_sysinit(linker_file_t lf)
 		(*((*sipp)->func)) ((*sipp)->udata);
 	}
 	mtx_unlock(&Giant);
+	sx_xlock(&kld_sx);
 }
 
 static void
@@ -254,6 +249,8 @@ linker_file_sysuninit(linker_file_t lf)
 	KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n",
 	    lf->filename));
 
+	sx_assert(&kld_sx, SA_XLOCKED);
+
 	if (linker_file_lookup_set(lf, "sysuninit_set", &start, &stop,
 	    NULL) != 0)
 		return;
@@ -281,6 +278,7 @@ linker_file_sysuninit(linker_file_t lf)
 	 * Traverse the (now) ordered list of system initialization tasks.
 	 * Perform each task, and continue on to the next task.
 	 */
+	sx_xunlock(&kld_sx);
 	mtx_lock(&Giant);
 	for (sipp = start; sipp < stop; sipp++) {
 		if ((*sipp)->subsystem == SI_SUB_DUMMY)
@@ -290,6 +288,7 @@ linker_file_sysuninit(linker_file_t lf)
 		(*((*sipp)->func)) ((*sipp)->udata);
 	}
 	mtx_unlock(&Giant);
+	sx_xlock(&kld_sx);
 }
 
 static void
@@ -301,13 +300,17 @@ linker_file_register_sysctls(linker_file_t lf)
 	    ("linker_file_register_sysctls: registering SYSCTLs for %s\n",
 	    lf->filename));
 
+	sx_assert(&kld_sx, SA_XLOCKED);
+
 	if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
 		return;
 
+	sx_xunlock(&kld_sx);
 	sysctl_lock();
 	for (oidp = start; oidp < stop; oidp++)
 		sysctl_register_oid(*oidp);
 	sysctl_unlock();
+	sx_xlock(&kld_sx);
 }
 
 static void
@@ -318,13 +321,17 @@ linker_file_unregister_sysctls(linker_file_t lf)
 	KLD_DPF(FILE, ("linker_file_unregister_sysctls: registering SYSCTLs"
 	    " for %s\n", lf->filename));
 
+	sx_assert(&kld_sx, SA_XLOCKED);
+
 	if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
 		return;
 
+	sx_xunlock(&kld_sx);
 	sysctl_lock();
 	for (oidp = start; oidp < stop; oidp++)
 		sysctl_unregister_oid(*oidp);
 	sysctl_unlock();
+	sx_xlock(&kld_sx);
 }
 #endif /* __rtems__ */
 
@@ -339,6 +346,8 @@ linker_file_register_modules(linker_file_t lf)
 	    " in %s\n", lf->filename));
 
 #ifndef __rtems__
+	sx_assert(&kld_sx, SA_XLOCKED);
+
 	if (linker_file_lookup_set(lf, "modmetadata_set", &start,
 	    &stop, NULL) != 0) {
 		/*
@@ -379,7 +388,9 @@ linker_init_kernel_modules(void)
 {
 
 #ifndef __rtems__
+	sx_xlock(&kld_sx);
 	linker_file_register_modules(linker_kernel_file);
+	sx_xunlock(&kld_sx);
 #else /* __rtems__ */
 	linker_file_register_modules(NULL);
 #endif /* __rtems__ */
@@ -400,7 +411,7 @@ linker_load_file(const char *filename, linker_file_t *result)
 	if (prison0.pr_securelevel > 0)
 		return (EPERM);
 
-	KLD_LOCK_ASSERT();
+	sx_assert(&kld_sx, SA_XLOCKED);
 	lf = linker_find_file_by_name(filename);
 	if (lf) {
 		KLD_DPF(FILE, ("linker_load_file: file %s is already loaded,"
@@ -434,10 +445,8 @@ linker_load_file(const char *filename, linker_file_t *result)
 				return (error);
 			}
 			modules = !TAILQ_EMPTY(&lf->modules);
-			KLD_UNLOCK();
 			linker_file_register_sysctls(lf);
 			linker_file_sysinit(lf);
-			KLD_LOCK();
 			lf->flags |= LINKER_FILE_LINKED;
 
 			/*
@@ -449,6 +458,7 @@ linker_load_file(const char *filename, linker_file_t *result)
 				linker_file_unload(lf, LINKER_UNLOAD_FORCE);
 				return (ENOEXEC);
 			}
+			EVENTHANDLER_INVOKE(kld_load, lf);
 			*result = lf;
 			return (0);
 		}
@@ -488,16 +498,16 @@ linker_reference_module(const char *modname, struct mod_depend *verinfo,
 	modlist_t mod;
 	int error;
 
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	if ((mod = modlist_lookup2(modname, verinfo)) != NULL) {
 		*result = mod->container;
 		(*result)->refs++;
-		KLD_UNLOCK();
+		sx_xunlock(&kld_sx);
 		return (0);
 	}
 
 	error = linker_load_module(NULL, modname, NULL, verinfo, result);
-	KLD_UNLOCK();
+	sx_xunlock(&kld_sx);
 	return (error);
 }
 
@@ -508,13 +518,13 @@ linker_release_module(const char *modname, struct mod_depend *verinfo,
 	modlist_t mod;
 	int error;
 
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	if (lf == NULL) {
 		KASSERT(modname != NULL,
 		    ("linker_release_module: no file or name"));
 		mod = modlist_lookup2(modname, verinfo);
 		if (mod == NULL) {
-			KLD_UNLOCK();
+			sx_xunlock(&kld_sx);
 			return (ESRCH);
 		}
 		lf = mod->container;
@@ -522,7 +532,7 @@ linker_release_module(const char *modname, struct mod_depend *verinfo,
 		KASSERT(modname == NULL && verinfo == NULL,
 		    ("linker_release_module: both file and name"));
 	error =	linker_file_unload(lf, LINKER_UNLOAD_NORMAL);
-	KLD_UNLOCK();
+	sx_xunlock(&kld_sx);
 	return (error);
 }
 
@@ -535,7 +545,7 @@ linker_find_file_by_name(const char *filename)
 	koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK);
 	sprintf(koname, "%s.ko", filename);
 
-	KLD_LOCK_ASSERT();
+	sx_assert(&kld_sx, SA_XLOCKED);
 	TAILQ_FOREACH(lf, &linker_files, link) {
 		if (strcmp(lf->filename, koname) == 0)
 			break;
@@ -551,7 +561,7 @@ linker_find_file_by_id(int fileid)
 {
 	linker_file_t lf;
 
-	KLD_LOCK_ASSERT();
+	sx_assert(&kld_sx, SA_XLOCKED);
 	TAILQ_FOREACH(lf, &linker_files, link)
 		if (lf->id == fileid && lf->flags & LINKER_FILE_LINKED)
 			break;
@@ -564,13 +574,13 @@ linker_file_foreach(linker_predicate_t *predicate, void *context)
 	linker_file_t lf;
 	int retval = 0;
 
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	TAILQ_FOREACH(lf, &linker_files, link) {
 		retval = predicate(lf, context);
 		if (retval != 0)
 			break;
 	}
-	KLD_UNLOCK();
+	sx_xunlock(&kld_sx);
 	return (retval);
 }
 
@@ -580,7 +590,8 @@ linker_make_file(const char *pathname, linker_class_t lc)
 	linker_file_t lf;
 	const char *filename;
 
-	KLD_LOCK_ASSERT();
+	if (!cold)
+		sx_assert(&kld_sx, SA_XLOCKED);
 	filename = linker_basename(pathname);
 
 	KLD_DPF(FILE, ("linker_make_file: new file, filename='%s' for pathname='%s'\n", filename, pathname));
@@ -596,8 +607,6 @@ linker_make_file(const char *pathname, linker_class_t lc)
 	lf->ndeps = 0;
 	lf->deps = NULL;
 	lf->loadcnt = ++loadcnt;
-	lf->sdt_probes = NULL;
-	lf->sdt_nprobes = 0;
 	STAILQ_INIT(&lf->common);
 	TAILQ_INIT(&lf->modules);
 	TAILQ_INSERT_TAIL(&linker_files, lf, link);
@@ -616,7 +625,7 @@ linker_file_unload(linker_file_t file, int flags)
 	if (prison0.pr_securelevel > 0)
 		return (EPERM);
 
-	KLD_LOCK_ASSERT();
+	sx_assert(&kld_sx, SA_XLOCKED);
 	KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs));
 
 	/* Easy case of just dropping a reference. */
@@ -625,6 +634,12 @@ linker_file_unload(linker_file_t file, int flags)
 		return (0);
 	}
 
+	/* Give eventhandlers a chance to prevent the unload. */
+	error = 0;
+	EVENTHANDLER_INVOKE(kld_unload_try, file, &error);
+	if (error != 0)
+		return (EBUSY);
+
 	KLD_DPF(FILE, ("linker_file_unload: file is unloading,"
 	    " informing modules\n"));
 
@@ -689,10 +704,8 @@ linker_file_unload(linker_file_t file, int flags)
 	 */
 	if (file->flags & LINKER_FILE_LINKED) {
 		file->flags &= ~LINKER_FILE_LINKED;
-		KLD_UNLOCK();
 		linker_file_sysuninit(file);
 		linker_file_unregister_sysctls(file);
-		KLD_LOCK();
 	}
 	TAILQ_REMOVE(&linker_files, file, link);
 
@@ -708,6 +721,10 @@ linker_file_unload(linker_file_t file, int flags)
 	}
 
 	LINKER_UNLOAD(file);
+
+	EVENTHANDLER_INVOKE(kld_unload, file->filename, file->address,
+	    file->size);
+
 	if (file->filename) {
 		free(file->filename, M_LINKER);
 		file->filename = NULL;
@@ -731,18 +748,9 @@ linker_file_add_dependency(linker_file_t file, linker_file_t dep)
 {
 	linker_file_t *newdeps;
 
-	KLD_LOCK_ASSERT();
-	newdeps = malloc((file->ndeps + 1) * sizeof(linker_file_t *),
+	sx_assert(&kld_sx, SA_XLOCKED);
+	file->deps = realloc(file->deps, (file->ndeps + 1) * sizeof(*newdeps),
 	    M_LINKER, M_WAITOK | M_ZERO);
-	if (newdeps == NULL)
-		return (ENOMEM);
-
-	if (file->deps) {
-		bcopy(file->deps, newdeps,
-		    file->ndeps * sizeof(linker_file_t *));
-		free(file->deps, M_LINKER);
-	}
-	file->deps = newdeps;
 	file->deps[file->ndeps] = dep;
 	file->ndeps++;
 	KLD_DPF(FILE, ("linker_file_add_dependency:"
@@ -761,15 +769,9 @@ int
 linker_file_lookup_set(linker_file_t file, const char *name,
     void *firstp, void *lastp, int *countp)
 {
-	int error, locked;
 
-	locked = KLD_LOCKED();
-	if (!locked)
-		KLD_LOCK();
-	error = LINKER_LOOKUP_SET(file, name, firstp, lastp, countp);
-	if (!locked)
-		KLD_UNLOCK();
-	return (error);
+	sx_assert(&kld_sx, SA_LOCKED);
+	return (LINKER_LOOKUP_SET(file, name, firstp, lastp, countp));
 }
 
 /*
@@ -788,12 +790,12 @@ linker_file_lookup_symbol(linker_file_t file, const char *name, int deps)
 	caddr_t sym;
 	int locked;
 
-	locked = KLD_LOCKED();
+	locked = sx_xlocked(&kld_sx);
 	if (!locked)
-		KLD_LOCK();
+		sx_xlock(&kld_sx);
 	sym = linker_file_lookup_symbol_internal(file, name, deps);
 	if (!locked)
-		KLD_UNLOCK();
+		sx_xunlock(&kld_sx);
 	return (sym);
 }
 
@@ -807,7 +809,7 @@ linker_file_lookup_symbol_internal(linker_file_t file, const char *name,
 	size_t common_size = 0;
 	int i;
 
-	KLD_LOCK_ASSERT();
+	sx_assert(&kld_sx, SA_XLOCKED);
 	KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%p, name=%s, deps=%d\n",
 	    file, name, deps));
 
@@ -1007,9 +1009,9 @@ linker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
 {
 	int error;
 
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	error = linker_debug_search_symbol_name(value, buf, buflen, offset);
-	KLD_UNLOCK();
+	sx_xunlock(&kld_sx);
 	return (error);
 }
 
@@ -1019,9 +1021,6 @@ linker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
 int
 kern_kldload(struct thread *td, const char *file, int *fileid)
 {
-#ifdef HWPMC_HOOKS
-	struct pmckern_map_in pkm;
-#endif
 	const char *kldname, *modname;
 	linker_file_t lf;
 	int error;
@@ -1051,24 +1050,16 @@ kern_kldload(struct thread *td, const char *file, int *fileid)
 		modname = file;
 	}
 
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	error = linker_load_module(kldname, modname, NULL, NULL, &lf);
 	if (error) {
-		KLD_UNLOCK();
+		sx_xunlock(&kld_sx);
 		goto done;
 	}
 	lf->userrefs++;
 	if (fileid != NULL)
 		*fileid = lf->id;
-#ifdef HWPMC_HOOKS
-	KLD_DOWNGRADE();
-	pkm.pm_file = lf->filename;
-	pkm.pm_address = (uintptr_t) lf->address;
-	PMC_CALL_HOOK(td, PMC_FN_KLD_LOAD, (void *) &pkm);
-	KLD_UNLOCK_READ();
-#else
-	KLD_UNLOCK();
-#endif
+	sx_xunlock(&kld_sx);
 
 done:
 	CURVNET_RESTORE();
@@ -1097,9 +1088,6 @@ sys_kldload(struct thread *td, struct kldload_args *uap)
 int
 kern_kldunload(struct thread *td, int fileid, int flags)
 {
-#ifdef HWPMC_HOOKS
-	struct pmckern_map_out pkm;
-#endif
 	linker_file_t lf;
 	int error = 0;
 
@@ -1110,17 +1098,12 @@ kern_kldunload(struct thread *td, int fileid, int flags)
 		return (error);
 
 	CURVNET_SET(TD_TO_VNET(td));
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	lf = linker_find_file_by_id(fileid);
 	if (lf) {
 		KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs));
 
-		/* Check if there are DTrace probes enabled on this file. */
-		if (lf->nenabled > 0) {
-			printf("kldunload: attempt to unload file that has"
-			    " DTrace probes enabled\n");
-			error = EBUSY;
-		} else if (lf->userrefs == 0) {
+		if (lf->userrefs == 0) {
 			/*
 			 * XXX: maybe LINKER_UNLOAD_FORCE should override ?
 			 */
@@ -1128,11 +1111,6 @@ kern_kldunload(struct thread *td, int fileid, int flags)
 			    " loaded by the kernel\n");
 			error = EBUSY;
 		} else {
-#ifdef HWPMC_HOOKS
-			/* Save data needed by hwpmc(4) before unloading. */
-			pkm.pm_address = (uintptr_t) lf->address;
-			pkm.pm_size = lf->size;
-#endif
 			lf->userrefs--;
 			error = linker_file_unload(lf, flags);
 			if (error)
@@ -1140,17 +1118,8 @@ kern_kldunload(struct thread *td, int fileid, int flags)
 		}
 	} else
 		error = ENOENT;
+	sx_xunlock(&kld_sx);
 
-#ifdef HWPMC_HOOKS
-	if (error == 0) {
-		KLD_DOWNGRADE();
-		PMC_CALL_HOOK(td, PMC_FN_KLD_UNLOAD, (void *) &pkm);
-		KLD_UNLOCK_READ();
-	} else
-		KLD_UNLOCK();
-#else
-	KLD_UNLOCK();
-#endif
 	CURVNET_RESTORE();
 	return (error);
 }
@@ -1193,13 +1162,13 @@ sys_kldfind(struct thread *td, struct kldfind_args *uap)
 		goto out;
 
 	filename = linker_basename(pathname);
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	lf = linker_find_file_by_name(filename);
 	if (lf)
 		td->td_retval[0] = lf->id;
 	else
 		error = ENOENT;
-	KLD_UNLOCK();
+	sx_xunlock(&kld_sx);
 out:
 	free(pathname, M_TEMP);
 	return (error);
@@ -1217,7 +1186,7 @@ sys_kldnext(struct thread *td, struct kldnext_args *uap)
 		return (error);
 #endif
 
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	if (uap->fileid == 0)
 		lf = TAILQ_FIRST(&linker_files);
 	else {
@@ -1238,7 +1207,7 @@ sys_kldnext(struct thread *td, struct kldnext_args *uap)
 	else
 		td->td_retval[0] = 0;
 out:
-	KLD_UNLOCK();
+	sx_xunlock(&kld_sx);
 	return (error);
 }
 
@@ -1277,10 +1246,10 @@ kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat)
 		return (error);
 #endif
 
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	lf = linker_find_file_by_id(fileid);
 	if (lf == NULL) {
-		KLD_UNLOCK();
+		sx_xunlock(&kld_sx);
 		return (ENOENT);
 	}
 
@@ -1298,7 +1267,7 @@ kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat)
 	if (namelen > MAXPATHLEN)
 		namelen = MAXPATHLEN;
 	bcopy(lf->pathname, &stat->pathname[0], namelen);
-	KLD_UNLOCK();
+	sx_xunlock(&kld_sx);
 
 	td->td_retval[0] = 0;
 	return (0);
@@ -1317,7 +1286,7 @@ sys_kldfirstmod(struct thread *td, struct kldfirstmod_args *uap)
 		return (error);
 #endif
 
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	lf = linker_find_file_by_id(uap->fileid);
 	if (lf) {
 		MOD_SLOCK;
@@ -1329,7 +1298,7 @@ sys_kldfirstmod(struct thread *td, struct kldfirstmod_args *uap)
 		MOD_SUNLOCK;
 	} else
 		error = ENOENT;
-	KLD_UNLOCK();
+	sx_xunlock(&kld_sx);
 	return (error);
 }
 
@@ -1357,7 +1326,7 @@ sys_kldsym(struct thread *td, struct kldsym_args *uap)
 	symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
 	if ((error = copyinstr(lookup.symname, symstr, MAXPATHLEN, NULL)) != 0)
 		goto out;
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	if (uap->fileid != 0) {
 		lf = linker_find_file_by_id(uap->fileid);
 		if (lf == NULL)
@@ -1383,7 +1352,7 @@ sys_kldsym(struct thread *td, struct kldsym_args *uap)
 		if (lf == NULL)
 			error = ENOENT;
 	}
-	KLD_UNLOCK();
+	sx_xunlock(&kld_sx);
 out:
 	free(symstr, M_TEMP);
 	return (error);
@@ -1492,6 +1461,7 @@ linker_preload(void *arg)
 	error = 0;
 
 	modptr = NULL;
+	sx_xlock(&kld_sx);
 	while ((modptr = preload_search_next_name(modptr)) != NULL) {
 		modname = (char *)preload_search_info(modptr, MODINFO_NAME);
 		modtype = (char *)preload_search_info(modptr, MODINFO_TYPE);
@@ -1673,6 +1643,7 @@ fail:
 		TAILQ_REMOVE(&depended_files, lf, loaded);
 		linker_file_unload(lf, LINKER_UNLOAD_FORCE);
 	}
+	sx_xunlock(&kld_sx);
 	/* woohoo! we made it! */
 }
 
@@ -1978,7 +1949,7 @@ linker_hwpmc_list_objects(void)
 	int i, nmappings;
 
 	nmappings = 0;
-	KLD_LOCK_READ();
+	sx_slock(&kld_sx);
 	TAILQ_FOREACH(lf, &linker_files, link)
 		nmappings++;
 
@@ -1993,7 +1964,7 @@ linker_hwpmc_list_objects(void)
 		kobase[i].pm_address = (uintptr_t)lf->address;
 		i++;
 	}
-	KLD_UNLOCK_READ();
+	sx_sunlock(&kld_sx);
 
 	KASSERT(i > 0, ("linker_hpwmc_list_objects: no kernel objects?"));
 
@@ -2019,7 +1990,7 @@ linker_load_module(const char *kldname, const char *modname,
 	char *pathname;
 	int error;
 
-	KLD_LOCK_ASSERT();
+	sx_assert(&kld_sx, SA_XLOCKED);
 	if (modname == NULL) {
 		/*
  		 * We have to load KLD
@@ -2093,7 +2064,7 @@ linker_load_dependencies(linker_file_t lf)
 	/*
 	 * All files are dependant on /kernel.
 	 */
-	KLD_LOCK_ASSERT();
+	sx_assert(&kld_sx, SA_XLOCKED);
 	if (linker_kernel_file) {
 		linker_kernel_file->refs++;
 		error = linker_file_add_dependency(lf, linker_kernel_file);
@@ -2185,16 +2156,16 @@ sysctl_kern_function_list(SYSCTL_HANDLER_ARGS)
 	error = sysctl_wire_old_buffer(req, 0);
 	if (error != 0)
 		return (error);
-	KLD_LOCK();
+	sx_xlock(&kld_sx);
 	TAILQ_FOREACH(lf, &linker_files, link) {
 		error = LINKER_EACH_FUNCTION_NAME(lf,
 		    sysctl_kern_function_list_iterate, req);
 		if (error) {
-			KLD_UNLOCK();
+			sx_xunlock(&kld_sx);
 			return (error);
 		}
 	}
-	KLD_UNLOCK();
+	sx_xunlock(&kld_sx);
 	return (SYSCTL_OUT(req, "", 1));
 }
 
diff --git a/freebsd/sys/kern/kern_mbuf.c b/freebsd/sys/kern/kern_mbuf.c
index 98cfb1f..74e7aa1 100644
--- a/freebsd/sys/kern/kern_mbuf.c
+++ b/freebsd/sys/kern/kern_mbuf.c
@@ -2,7 +2,7 @@
 
 /*-
  * Copyright (c) 2004, 2005,
- * 	Bosko Milekic <bmilekic at FreeBSD.org>.  All rights reserved.
+ *	Bosko Milekic <bmilekic at FreeBSD.org>.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -49,9 +49,13 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_extern.h>
 #include <vm/vm_kern.h>
 #include <vm/vm_page.h>
+#include <vm/vm_map.h>
 #include <vm/uma.h>
 #include <vm/uma_int.h>
 #include <vm/uma_dbg.h>
+#ifdef __rtems__
+#include <rtems/bsd/bsd.h>
+#endif /* __rtems__ */
 
 /*
  * In FreeBSD, Mbufs and Mbuf Clusters are allocated from UMA
@@ -78,7 +82,7 @@ __FBSDID("$FreeBSD$");
  *  [ Cluster Zone  ]   [     Zone     ]   [ Mbuf Master Zone ]
  *        |                       \________         |
  *  [ Cluster Keg   ]                      \       /
- *        |    	                         [ Mbuf Keg   ]
+ *        |	                         [ Mbuf Keg   ]
  *  [ Cluster Slabs ]                         |
  *        |                              [ Mbuf Slabs ]
  *         \____________(VM)_________________/
@@ -98,39 +102,69 @@ __FBSDID("$FreeBSD$");
  *
  */
 
+int nmbufs;			/* limits number of mbufs */
 int nmbclusters;		/* limits number of mbuf clusters */
 int nmbjumbop;			/* limits number of page size jumbo clusters */
 int nmbjumbo9;			/* limits number of 9k jumbo clusters */
 int nmbjumbo16;			/* limits number of 16k jumbo clusters */
 struct mbstat mbstat;
 
+static quad_t maxmbufmem;	/* overall real memory limit for all mbufs */
+
+SYSCTL_QUAD(_kern_ipc, OID_AUTO, maxmbufmem, CTLFLAG_RDTUN, &maxmbufmem, 0,
+    "Maximum real memory allocateable to various mbuf types");
+
 /*
- * tunable_mbinit() has to be run before init_maxsockets() thus
- * the SYSINIT order below is SI_ORDER_MIDDLE while init_maxsockets()
- * runs at SI_ORDER_ANY.
+ * tunable_mbinit() has to be run before any mbuf allocations are done.
  */
 static void
 tunable_mbinit(void *dummy)
 {
+#ifndef __rtems__
+	quad_t realmem;
+
+	/*
+	 * The default limit for all mbuf related memory is 1/2 of all
+	 * available kernel memory (physical or kmem).
+	 * At most it can be 3/4 of available kernel memory.
+	 */
+	realmem = qmin((quad_t)physmem * PAGE_SIZE,
+	    vm_map_max(kmem_map) - vm_map_min(kmem_map));
+	maxmbufmem = realmem / 2;
+	TUNABLE_QUAD_FETCH("kern.ipc.maxmbufmem", &maxmbufmem);
+	if (maxmbufmem > realmem / 4 * 3)
+		maxmbufmem = realmem / 4 * 3;
+#else /* __rtems__ */
+	maxmbufmem = rtems_bsd_get_allocator_domain_size(
+	    RTEMS_BSD_ALLOCATOR_DOMAIN_MBUF);
+#endif /* __rtems__ */
 
-	/* This has to be done before VM init. */
 	TUNABLE_INT_FETCH("kern.ipc.nmbclusters", &nmbclusters);
 	if (nmbclusters == 0)
-		nmbclusters = 1024 + maxusers * 64;
+		nmbclusters = maxmbufmem / MCLBYTES / 4;
 
 	TUNABLE_INT_FETCH("kern.ipc.nmbjumbop", &nmbjumbop);
 	if (nmbjumbop == 0)
-		nmbjumbop = nmbclusters / 2;
+		nmbjumbop = maxmbufmem / MJUMPAGESIZE / 4;
 
 	TUNABLE_INT_FETCH("kern.ipc.nmbjumbo9", &nmbjumbo9);
 	if (nmbjumbo9 == 0)
-		nmbjumbo9 = nmbclusters / 4;
+		nmbjumbo9 = maxmbufmem / MJUM9BYTES / 6;
 
 	TUNABLE_INT_FETCH("kern.ipc.nmbjumbo16", &nmbjumbo16);
 	if (nmbjumbo16 == 0)
-		nmbjumbo16 = nmbclusters / 8;
+		nmbjumbo16 = maxmbufmem / MJUM16BYTES / 6;
+
+	/*
+	 * We need at least as many mbufs as we have clusters of
+	 * the various types added together.
+	 */
+	TUNABLE_INT_FETCH("kern.ipc.nmbufs", &nmbufs);
+	if (nmbufs < nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16)
+		nmbufs = lmax(maxmbufmem / MSIZE / 5,
+		    nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16);
 }
-SYSINIT(tunable_mbinit, SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_mbinit, NULL);
+SYSINIT(tunable_mbinit, SI_SUB_KMEM, SI_ORDER_MIDDLE, tunable_mbinit, NULL);
 
 static int
 sysctl_nmbclusters(SYSCTL_HANDLER_ARGS)
@@ -138,11 +172,12 @@ sysctl_nmbclusters(SYSCTL_HANDLER_ARGS)
 	int error, newnmbclusters;
 
 	newnmbclusters = nmbclusters;
-	error = sysctl_handle_int(oidp, &newnmbclusters, 0, req); 
-	if (error == 0 && req->newptr) {
-		if (newnmbclusters > nmbclusters) {
+	error = sysctl_handle_int(oidp, &newnmbclusters, 0, req);
+	if (error == 0 && req->newptr && newnmbclusters != nmbclusters) {
+		if (newnmbclusters > nmbclusters &&
+		    nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) {
 			nmbclusters = newnmbclusters;
-			uma_zone_set_max(zone_clust, nmbclusters);
+			nmbclusters = uma_zone_set_max(zone_clust, nmbclusters);
 #ifndef __rtems__
 			EVENTHANDLER_INVOKE(nmbclusters_change);
 #endif /* __rtems__ */
@@ -161,11 +196,12 @@ sysctl_nmbjumbop(SYSCTL_HANDLER_ARGS)
 	int error, newnmbjumbop;
 
 	newnmbjumbop = nmbjumbop;
-	error = sysctl_handle_int(oidp, &newnmbjumbop, 0, req); 
-	if (error == 0 && req->newptr) {
-		if (newnmbjumbop> nmbjumbop) {
+	error = sysctl_handle_int(oidp, &newnmbjumbop, 0, req);
+	if (error == 0 && req->newptr && newnmbjumbop != nmbjumbop) {
+		if (newnmbjumbop > nmbjumbop &&
+		    nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) {
 			nmbjumbop = newnmbjumbop;
-			uma_zone_set_max(zone_jumbop, nmbjumbop);
+			nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop);
 		} else
 			error = EINVAL;
 	}
@@ -173,8 +209,7 @@ sysctl_nmbjumbop(SYSCTL_HANDLER_ARGS)
 }
 SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbjumbop, CTLTYPE_INT|CTLFLAG_RW,
 &nmbjumbop, 0, sysctl_nmbjumbop, "IU",
-	 "Maximum number of mbuf page size jumbo clusters allowed");
-
+    "Maximum number of mbuf page size jumbo clusters allowed");
 
 static int
 sysctl_nmbjumbo9(SYSCTL_HANDLER_ARGS)
@@ -182,11 +217,12 @@ sysctl_nmbjumbo9(SYSCTL_HANDLER_ARGS)
 	int error, newnmbjumbo9;
 
 	newnmbjumbo9 = nmbjumbo9;
-	error = sysctl_handle_int(oidp, &newnmbjumbo9, 0, req); 
-	if (error == 0 && req->newptr) {
-		if (newnmbjumbo9> nmbjumbo9) {
+	error = sysctl_handle_int(oidp, &newnmbjumbo9, 0, req);
+	if (error == 0 && req->newptr && newnmbjumbo9 != nmbjumbo9) {
+		if (newnmbjumbo9 > nmbjumbo9 &&
+		    nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) {
 			nmbjumbo9 = newnmbjumbo9;
-			uma_zone_set_max(zone_jumbo9, nmbjumbo9);
+			nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9);
 		} else
 			error = EINVAL;
 	}
@@ -194,7 +230,7 @@ sysctl_nmbjumbo9(SYSCTL_HANDLER_ARGS)
 }
 SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbjumbo9, CTLTYPE_INT|CTLFLAG_RW,
 &nmbjumbo9, 0, sysctl_nmbjumbo9, "IU",
-	"Maximum number of mbuf 9k jumbo clusters allowed"); 
+    "Maximum number of mbuf 9k jumbo clusters allowed");
 
 static int
 sysctl_nmbjumbo16(SYSCTL_HANDLER_ARGS)
@@ -202,11 +238,12 @@ sysctl_nmbjumbo16(SYSCTL_HANDLER_ARGS)
 	int error, newnmbjumbo16;
 
 	newnmbjumbo16 = nmbjumbo16;
-	error = sysctl_handle_int(oidp, &newnmbjumbo16, 0, req); 
-	if (error == 0 && req->newptr) {
-		if (newnmbjumbo16> nmbjumbo16) {
+	error = sysctl_handle_int(oidp, &newnmbjumbo16, 0, req);
+	if (error == 0 && req->newptr && newnmbjumbo16 != nmbjumbo16) {
+		if (newnmbjumbo16 > nmbjumbo16 &&
+		    nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) {
 			nmbjumbo16 = newnmbjumbo16;
-			uma_zone_set_max(zone_jumbo16, nmbjumbo16);
+			nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16);
 		} else
 			error = EINVAL;
 	}
@@ -216,7 +253,26 @@ SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbjumbo16, CTLTYPE_INT|CTLFLAG_RW,
 &nmbjumbo16, 0, sysctl_nmbjumbo16, "IU",
     "Maximum number of mbuf 16k jumbo clusters allowed");
 
-
+static int
+sysctl_nmbufs(SYSCTL_HANDLER_ARGS)
+{
+	int error, newnmbufs;
+
+	newnmbufs = nmbufs;
+	error = sysctl_handle_int(oidp, &newnmbufs, 0, req);
+	if (error == 0 && req->newptr && newnmbufs != nmbufs) {
+		if (newnmbufs > nmbufs) {
+			nmbufs = newnmbufs;
+			nmbufs = uma_zone_set_max(zone_mbuf, nmbufs);
+			EVENTHANDLER_INVOKE(nmbufs_change);
+		} else
+			error = EINVAL;
+	}
+	return (error);
+}
+SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbufs, CTLTYPE_INT|CTLFLAG_RW,
+&nmbufs, 0, sysctl_nmbufs, "IU",
+    "Maximum number of mbufs allowed");
 
 SYSCTL_STRUCT(_kern_ipc, OID_AUTO, mbstat, CTLFLAG_RD, &mbstat, mbstat,
     "Mbuf general information and statistics");
@@ -245,7 +301,6 @@ static int	mb_zinit_pack(void *, int, int);
 static void	mb_zfini_pack(void *, int);
 
 static void	mb_reclaim(void *);
-static void	mbuf_init(void *);
 static void    *mbuf_jumbo_alloc(uma_zone_t, int, uint8_t *, int);
 
 /* Ensure that MSIZE doesn't break dtom() - it must be a power of 2 */
@@ -254,7 +309,6 @@ CTASSERT((((MSIZE - 1) ^ MSIZE) + 1) >> 1 == MSIZE);
 /*
  * Initialize FreeBSD Network buffer allocation.
  */
-SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbuf_init, NULL);
 static void
 mbuf_init(void *dummy)
 {
@@ -270,6 +324,8 @@ mbuf_init(void *dummy)
 	    NULL, NULL,
 #endif
 	    MSIZE - 1, UMA_ZONE_MAXBUCKET);
+	if (nmbufs > 0)
+		nmbufs = uma_zone_set_max(zone_mbuf, nmbufs);
 
 	zone_clust = uma_zcreate(MBUF_CLUSTER_MEM_NAME, MCLBYTES,
 	    mb_ctor_clust, mb_dtor_clust,
@@ -280,7 +336,7 @@ mbuf_init(void *dummy)
 #endif
 	    UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
 	if (nmbclusters > 0)
-		uma_zone_set_max(zone_clust, nmbclusters);
+		nmbclusters = uma_zone_set_max(zone_clust, nmbclusters);
 
 	zone_pack = uma_zsecond_create(MBUF_PACKET_MEM_NAME, mb_ctor_pack,
 	    mb_dtor_pack, mb_zinit_pack, mb_zfini_pack, zone_mbuf);
@@ -295,7 +351,7 @@ mbuf_init(void *dummy)
 #endif
 	    UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
 	if (nmbjumbop > 0)
-		uma_zone_set_max(zone_jumbop, nmbjumbop);
+		nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop);
 
 	zone_jumbo9 = uma_zcreate(MBUF_JUMBO9_MEM_NAME, MJUM9BYTES,
 	    mb_ctor_clust, mb_dtor_clust,
@@ -305,9 +361,9 @@ mbuf_init(void *dummy)
 	    NULL, NULL,
 #endif
 	    UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
-	if (nmbjumbo9 > 0)
-		uma_zone_set_max(zone_jumbo9, nmbjumbo9);
 	uma_zone_set_allocf(zone_jumbo9, mbuf_jumbo_alloc);
+	if (nmbjumbo9 > 0)
+		nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9);
 
 	zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES,
 	    mb_ctor_clust, mb_dtor_clust,
@@ -317,9 +373,9 @@ mbuf_init(void *dummy)
 	    NULL, NULL,
 #endif
 	    UMA_ALIGN_PTR, UMA_ZONE_REFCNT);
-	if (nmbjumbo16 > 0)
-		uma_zone_set_max(zone_jumbo16, nmbjumbo16);
 	uma_zone_set_allocf(zone_jumbo16, mbuf_jumbo_alloc);
+	if (nmbjumbo16 > 0)
+		nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16);
 
 	zone_ext_refcnt = uma_zcreate(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int),
 	    NULL, NULL,
@@ -357,6 +413,7 @@ mbuf_init(void *dummy)
 	mbstat.sf_iocnt = 0;
 	mbstat.sf_allocwait = mbstat.sf_allocfail = 0;
 }
+SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbuf_init, NULL);
 
 /*
  * UMA backend page allocator for the jumbo frame zones.
@@ -445,7 +502,7 @@ static void
 mb_dtor_mbuf(void *mem, int size, void *arg)
 {
 	struct mbuf *m;
-	unsigned long flags; 
+	unsigned long flags;
 
 	m = (struct mbuf *)mem;
 	flags = (unsigned long)arg;
diff --git a/freebsd/sys/kern/kern_mib.c b/freebsd/sys/kern/kern_mib.c
index a8215b3..c360558 100644
--- a/freebsd/sys/kern/kern_mib.c
+++ b/freebsd/sys/kern/kern_mib.c
@@ -271,6 +271,13 @@ SYSCTL_PROC(_hw, HW_MACHINE_ARCH, machine_arch, CTLTYPE_STRING | CTLFLAG_RD,
     NULL, 0, sysctl_hw_machine_arch, "A", "System architecture");
 #endif /* __rtems__ */
 
+SYSCTL_STRING(_kern, OID_AUTO, supported_archs, CTLFLAG_RD | CTLFLAG_MPSAFE,
+#ifdef COMPAT_FREEBSD32
+    MACHINE_ARCH " " MACHINE_ARCH32, 0, "Supported architectures for binaries");
+#else
+    MACHINE_ARCH, 0, "Supported architectures for binaries");
+#endif
+
 static int
 sysctl_hostname(SYSCTL_HANDLER_ARGS)
 {
diff --git a/freebsd/sys/kern/kern_time.c b/freebsd/sys/kern/kern_time.c
index e113aef..dbb10d0 100644
--- a/freebsd/sys/kern/kern_time.c
+++ b/freebsd/sys/kern/kern_time.c
@@ -60,6 +60,12 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_extern.h>
 
 #define MAX_CLOCKS 	(CLOCK_MONOTONIC+1)
+#define CPUCLOCK_BIT		0x80000000
+#define CPUCLOCK_PROCESS_BIT	0x40000000
+#define CPUCLOCK_ID_MASK	(~(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT))
+#define MAKE_THREAD_CPUCLOCK(tid)	(CPUCLOCK_BIT|(tid))
+#define MAKE_PROCESS_CPUCLOCK(pid)	\
+	(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT|(pid))
 
 #ifndef __rtems__
 static struct kclock	posix_clocks[MAX_CLOCKS];
@@ -96,9 +102,6 @@ static int	realtimer_settime(struct itimer *, int,
 static int	realtimer_delete(struct itimer *);
 static void	realtimer_clocktime(clockid_t, struct timespec *);
 static void	realtimer_expire(void *);
-static int	kern_timer_create(struct thread *, clockid_t,
-			struct sigevent *, int *, int);
-static int	kern_timer_delete(struct thread *, int);
 
 int		register_posix_clock(int, struct kclock *);
 void		itimer_fire(struct itimer *it);
@@ -170,6 +173,60 @@ settime(struct thread *td, struct timeval *tv)
 }
 
 #ifndef _SYS_SYSPROTO_H_
+struct clock_getcpuclockid2_args {
+	id_t id;
+	int which,
+	clockid_t *clock_id;
+};
+#endif
+/* ARGSUSED */
+int
+sys_clock_getcpuclockid2(struct thread *td, struct clock_getcpuclockid2_args *uap)
+{
+	clockid_t clk_id;
+	int error;
+
+	error = kern_clock_getcpuclockid2(td, uap->id, uap->which, &clk_id);
+	if (error == 0)
+		error = copyout(&clk_id, uap->clock_id, sizeof(clockid_t));
+	return (error);
+}
+
+int
+kern_clock_getcpuclockid2(struct thread *td, id_t id, int which,
+    clockid_t *clk_id)
+{
+	struct proc *p;
+	pid_t pid;
+	lwpid_t tid;
+	int error;
+
+	switch (which) {
+	case CPUCLOCK_WHICH_PID:
+		if (id != 0) {
+			p = pfind(id);
+			if (p == NULL)
+				return (ESRCH);
+			error = p_cansee(td, p);
+			PROC_UNLOCK(p);
+			if (error != 0)
+				return (error);
+			pid = id;
+		} else {
+			pid = td->td_proc->p_pid;
+		}
+		*clk_id = MAKE_PROCESS_CPUCLOCK(pid);
+		return (0);
+	case CPUCLOCK_WHICH_TID:
+		tid = id == 0 ? td->td_tid : id;
+		*clk_id = MAKE_THREAD_CPUCLOCK(tid);
+		return (0);
+	default:
+		return (EINVAL);
+	}
+}
+
+#ifndef _SYS_SYSPROTO_H_
 struct clock_gettime_args {
 	clockid_t clock_id;
 	struct	timespec *tp;
@@ -192,12 +249,80 @@ sys_clock_gettime(struct thread *td, struct clock_gettime_args *uap)
 #endif
 
 #ifndef __rtems__
+static inline void 
+cputick2timespec(uint64_t runtime, struct timespec *ats)
+{
+	runtime = cputick2usec(runtime);
+	ats->tv_sec = runtime / 1000000;
+	ats->tv_nsec = runtime % 1000000 * 1000;
+}
+
+static void
+get_thread_cputime(struct thread *targettd, struct timespec *ats)
+{
+	uint64_t runtime, curtime, switchtime;
+
+	if (targettd == NULL) { /* current thread */
+		critical_enter();
+		switchtime = PCPU_GET(switchtime);
+		curtime = cpu_ticks();
+		runtime = curthread->td_runtime;
+		critical_exit();
+		runtime += curtime - switchtime;
+	} else {
+		thread_lock(targettd);
+		runtime = targettd->td_runtime;
+		thread_unlock(targettd);
+	}
+	cputick2timespec(runtime, ats);
+}
+
+static void
+get_process_cputime(struct proc *targetp, struct timespec *ats)
+{
+	uint64_t runtime;
+	struct rusage ru;
+
+	PROC_SLOCK(targetp);
+	rufetch(targetp, &ru);
+	runtime = targetp->p_rux.rux_runtime;
+	PROC_SUNLOCK(targetp);
+	cputick2timespec(runtime, ats);
+}
+
+static int
+get_cputime(struct thread *td, clockid_t clock_id, struct timespec *ats)
+{
+	struct proc *p, *p2;
+	struct thread *td2;
+	lwpid_t tid;
+	pid_t pid;
+	int error;
+
+	p = td->td_proc;
+	if ((clock_id & CPUCLOCK_PROCESS_BIT) == 0) {
+		tid = clock_id & CPUCLOCK_ID_MASK;
+		td2 = tdfind(tid, p->p_pid);
+		if (td2 == NULL)
+			return (EINVAL);
+		get_thread_cputime(td2, ats);
+		PROC_UNLOCK(td2->td_proc);
+	} else {
+		pid = clock_id & CPUCLOCK_ID_MASK;
+		error = pget(pid, PGET_CANSEE, &p2);
+		if (error != 0)
+			return (EINVAL);
+		get_process_cputime(p2, ats);
+		PROC_UNLOCK(p2);
+	}
+	return (0);
+}
+
 int
 kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats)
 {
 	struct timeval sys, user;
 	struct proc *p;
-	uint64_t runtime, curtime, switchtime;
 
 	p = td->td_proc;
 	switch (clock_id) {
@@ -240,17 +365,17 @@ kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats)
 		ats->tv_nsec = 0;
 		break;
 	case CLOCK_THREAD_CPUTIME_ID:
-		critical_enter();
-		switchtime = PCPU_GET(switchtime);
-		curtime = cpu_ticks();
-		runtime = td->td_runtime;
-		critical_exit();
-		runtime = cputick2usec(runtime + curtime - switchtime);
-		ats->tv_sec = runtime / 1000000;
-		ats->tv_nsec = runtime % 1000000 * 1000;
+		get_thread_cputime(NULL, ats);
+		break;
+	case CLOCK_PROCESS_CPUTIME_ID:
+		PROC_LOCK(p);
+		get_process_cputime(p, ats);
+		PROC_UNLOCK(p);
 		break;
 	default:
-		return (EINVAL);
+		if ((int)clock_id >= 0)
+			return (EINVAL);
+		return (get_cputime(td, clock_id, ats));
 	}
 	return (0);
 }
@@ -348,12 +473,16 @@ kern_clock_getres(struct thread *td, clockid_t clock_id, struct timespec *ts)
 		ts->tv_nsec = 0;
 		break;
 	case CLOCK_THREAD_CPUTIME_ID:
+	case CLOCK_PROCESS_CPUTIME_ID:
+	cputime:
 		/* sync with cputick2usec */
 		ts->tv_nsec = 1000000 / cpu_tickrate();
 		if (ts->tv_nsec == 0)
 			ts->tv_nsec = 1000;
 		break;
 	default:
+		if ((int)clock_id < 0)
+			goto cputime;
 		return (EINVAL);
 	}
 	return (0);
@@ -939,31 +1068,30 @@ struct ktimer_create_args {
 int
 sys_ktimer_create(struct thread *td, struct ktimer_create_args *uap)
 {
-	struct sigevent *evp1, ev;
+	struct sigevent *evp, ev;
 	int id;
 	int error;
 
-	if (uap->evp != NULL) {
+	if (uap->evp == NULL) {
+		evp = NULL;
+	} else {
 		error = copyin(uap->evp, &ev, sizeof(ev));
 		if (error != 0)
 			return (error);
-		evp1 = &ev;
-	} else
-		evp1 = NULL;
-
-	error = kern_timer_create(td, uap->clock_id, evp1, &id, -1);
-
+		evp = &ev;
+	}
+	error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
 	if (error == 0) {
 		error = copyout(&id, uap->timerid, sizeof(int));
 		if (error != 0)
-			kern_timer_delete(td, id);
+			kern_ktimer_delete(td, id);
 	}
 	return (error);
 }
 
-static int
-kern_timer_create(struct thread *td, clockid_t clock_id,
-	struct sigevent *evp, int *timerid, int preset_id)
+int
+kern_ktimer_create(struct thread *td, clockid_t clock_id, struct sigevent *evp,
+    int *timerid, int preset_id)
 {
 	struct proc *p = td->td_proc;
 	struct itimer *it;
@@ -1078,7 +1206,8 @@ struct ktimer_delete_args {
 int
 sys_ktimer_delete(struct thread *td, struct ktimer_delete_args *uap)
 {
-	return (kern_timer_delete(td, uap->timerid));
+
+	return (kern_ktimer_delete(td, uap->timerid));
 }
 
 static struct itimer *
@@ -1100,8 +1229,8 @@ itimer_find(struct proc *p, int timerid)
 	return (it);
 }
 
-static int
-kern_timer_delete(struct thread *td, int timerid)
+int
+kern_ktimer_delete(struct thread *td, int timerid)
 {
 	struct proc *p = td->td_proc;
 	struct itimer *it;
@@ -1143,35 +1272,40 @@ struct ktimer_settime_args {
 int
 sys_ktimer_settime(struct thread *td, struct ktimer_settime_args *uap)
 {
-	struct proc *p = td->td_proc;
-	struct itimer *it;
 	struct itimerspec val, oval, *ovalp;
 	int error;
 
 	error = copyin(uap->value, &val, sizeof(val));
 	if (error != 0)
 		return (error);
-	
-	if (uap->ovalue != NULL)
-		ovalp = &oval;
-	else
-		ovalp = NULL;
+	ovalp = uap->ovalue != NULL ? &oval : NULL;
+	error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
+	if (error == 0 && uap->ovalue != NULL)
+		error = copyout(ovalp, uap->ovalue, sizeof(*ovalp));
+	return (error);
+}
 
+int
+kern_ktimer_settime(struct thread *td, int timer_id, int flags,
+    struct itimerspec *val, struct itimerspec *oval)
+{
+	struct proc *p;
+	struct itimer *it;
+	int error;
+
+	p = td->td_proc;
 	PROC_LOCK(p);
-	if (uap->timerid < 3 ||
-	    (it = itimer_find(p, uap->timerid)) == NULL) {
+	if (timer_id < 3 || (it = itimer_find(p, timer_id)) == NULL) {
 		PROC_UNLOCK(p);
 		error = EINVAL;
 	} else {
 		PROC_UNLOCK(p);
 		itimer_enter(it);
-		error = CLOCK_CALL(it->it_clockid, timer_settime,
-				(it, uap->flags, &val, ovalp));
+		error = CLOCK_CALL(it->it_clockid, timer_settime, (it,
+		    flags, val, oval));
 		itimer_leave(it);
 		ITIMER_UNLOCK(it);
 	}
-	if (error == 0 && uap->ovalue != NULL)
-		error = copyout(ovalp, uap->ovalue, sizeof(*ovalp));
 	return (error);
 }
 
@@ -1184,26 +1318,34 @@ struct ktimer_gettime_args {
 int
 sys_ktimer_gettime(struct thread *td, struct ktimer_gettime_args *uap)
 {
-	struct proc *p = td->td_proc;
-	struct itimer *it;
 	struct itimerspec val;
 	int error;
 
+	error = kern_ktimer_gettime(td, uap->timerid, &val);
+	if (error == 0)
+		error = copyout(&val, uap->value, sizeof(val));
+	return (error);
+}
+
+int
+kern_ktimer_gettime(struct thread *td, int timer_id, struct itimerspec *val)
+{
+	struct proc *p;
+	struct itimer *it;
+	int error;
+
+	p = td->td_proc;
 	PROC_LOCK(p);
-	if (uap->timerid < 3 ||
-	   (it = itimer_find(p, uap->timerid)) == NULL) {
+	if (timer_id < 3 || (it = itimer_find(p, timer_id)) == NULL) {
 		PROC_UNLOCK(p);
 		error = EINVAL;
 	} else {
 		PROC_UNLOCK(p);
 		itimer_enter(it);
-		error = CLOCK_CALL(it->it_clockid, timer_gettime,
-				(it, &val));
+		error = CLOCK_CALL(it->it_clockid, timer_gettime, (it, val));
 		itimer_leave(it);
 		ITIMER_UNLOCK(it);
 	}
-	if (error == 0)
-		error = copyout(&val, uap->value, sizeof(val));
 	return (error);
 }
 
@@ -1498,7 +1640,7 @@ itimers_event_hook_exit(void *arg, struct proc *p)
 			panic("unhandled event");
 		for (; i < TIMER_MAX; ++i) {
 			if ((it = its->its_timers[i]) != NULL)
-				kern_timer_delete(curthread, i);
+				kern_ktimer_delete(curthread, i);
 		}
 		if (its->its_timers[0] == NULL &&
 		    its->its_timers[1] == NULL &&
diff --git a/freebsd/sys/kern/kern_timeout.c b/freebsd/sys/kern/kern_timeout.c
index 1ca98d9..821b035 100644
--- a/freebsd/sys/kern/kern_timeout.c
+++ b/freebsd/sys/kern/kern_timeout.c
@@ -66,11 +66,9 @@ __FBSDID("$FreeBSD$");
 #define ncallout 16
 #endif /* __rtems__ */
 SDT_PROVIDER_DEFINE(callout_execute);
-SDT_PROBE_DEFINE(callout_execute, kernel, , callout_start, callout-start);
-SDT_PROBE_ARGTYPE(callout_execute, kernel, , callout_start, 0,
+SDT_PROBE_DEFINE1(callout_execute, kernel, , callout__start,
     "struct callout *");
-SDT_PROBE_DEFINE(callout_execute, kernel, , callout_end, callout-end); 
-SDT_PROBE_ARGTYPE(callout_execute, kernel, , callout_end, 0,
+SDT_PROBE_DEFINE1(callout_execute, kernel, , callout__end,
     "struct callout *");
 
 static int avg_depth;
@@ -251,7 +249,7 @@ rtems_bsd_timeout_init_late(void *unused)
 SYSINIT(rtems_bsd_timeout_early, SI_SUB_VM, SI_ORDER_FIRST,
     rtems_bsd_timeout_init_early, NULL);
 
-SYSINIT(rtems_bsd_timeout_late, SI_SUB_RUN_SCHEDULER, SI_ORDER_FIRST,
+SYSINIT(rtems_bsd_timeout_late, SI_SUB_LAST, SI_ORDER_FIRST,
     rtems_bsd_timeout_init_late, NULL);
 
 static void
@@ -580,11 +578,11 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc, int *mpcalls,
 #endif
 #ifndef __rtems__
 	THREAD_NO_SLEEPING();
-	SDT_PROBE(callout_execute, kernel, , callout_start, c, 0, 0, 0, 0);
+	SDT_PROBE(callout_execute, kernel, , callout__start, c, 0, 0, 0, 0);
 #endif /* __rtems__ */
 	c_func(c_arg);
 #ifndef __rtems__
-	SDT_PROBE(callout_execute, kernel, , callout_end, c, 0, 0, 0, 0);
+	SDT_PROBE(callout_execute, kernel, , callout__end, c, 0, 0, 0, 0);
 	THREAD_SLEEPING_OK();
 #endif /* __rtems__ */
 #ifdef DIAGNOSTIC
@@ -943,11 +941,13 @@ _callout_stop_safe(c, safe)
 	struct	callout *c;
 	int	safe;
 {
+#ifndef __rtems__
 	struct callout_cpu *cc, *old_cc;
 	struct lock_class *class;
-#ifndef __rtems__
 	int use_lock, sq_locked;
 #else /* __rtems__ */
+	struct callout_cpu *cc;
+	struct lock_class *class;
 	int use_lock;
 #endif /* __rtems__ */
 
diff --git a/freebsd/sys/kern/subr_lock.c b/freebsd/sys/kern/subr_lock.c
index dea7d40..4a55a95 100644
--- a/freebsd/sys/kern/subr_lock.c
+++ b/freebsd/sys/kern/subr_lock.c
@@ -12,9 +12,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -69,6 +66,7 @@ struct lock_class *lock_classes[LOCK_CLASS_MAX + 1] = {
 	&lock_class_sx,
 #ifndef __rtems__
 	&lock_class_rm,
+	&lock_class_rm_sleepable,
 #endif /* __rtems__ */
 	&lock_class_rw,
 #ifndef __rtems__
diff --git a/freebsd/sys/kern/subr_rman.c b/freebsd/sys/kern/subr_rman.c
index 668201a..c158b36 100644
--- a/freebsd/sys/kern/subr_rman.c
+++ b/freebsd/sys/kern/subr_rman.c
@@ -453,7 +453,7 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end,
 	mtx_lock(rm->rm_mtx);
 
 	for (r = TAILQ_FIRST(&rm->rm_list);
-	     r && r->r_end < start;
+	     r && r->r_end < start + count - 1;
 	     r = TAILQ_NEXT(r, r_link))
 		;
 
@@ -463,6 +463,11 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end,
 	}
 
 	amask = (1ul << RF_ALIGNMENT(flags)) - 1;
+	if (start > ULONG_MAX - amask) {
+		DPRINTF(("start+amask would wrap around\n"));
+		goto out;
+	}
+
 	/* If bound is 0, bmask will also be 0 */
 	bmask = ~(bound - 1);
 	/*
@@ -470,11 +475,20 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end,
 	 */
 	for (s = r; s; s = TAILQ_NEXT(s, r_link)) {
 		DPRINTF(("considering [%#lx, %#lx]\n", s->r_start, s->r_end));
-		if (s->r_start + count - 1 > end) {
+		/*
+		 * The resource list is sorted, so there is no point in
+		 * searching further once r_start is too large.
+		 */
+		if (s->r_start > end - (count - 1)) {
 			DPRINTF(("s->r_start (%#lx) + count - 1> end (%#lx)\n",
 			    s->r_start, end));
 			break;
 		}
+		if (s->r_start > ULONG_MAX - amask) {
+			DPRINTF(("s->r_start (%#lx) + amask (%#lx) too large\n",
+			    s->r_start, amask));
+			break;
+		}
 		if (s->r_flags & RF_ALLOCATED) {
 			DPRINTF(("region is allocated\n"));
 			continue;
@@ -585,15 +599,10 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end,
 	if ((flags & (RF_SHAREABLE | RF_TIMESHARE)) == 0)
 		goto out;
 
-	for (s = r; s; s = TAILQ_NEXT(s, r_link)) {
-		if (s->r_start > end)
-			break;
-		if ((s->r_flags & flags) != flags)
-			continue;
-		rstart = ulmax(s->r_start, start);
-		rend = ulmin(s->r_end, ulmax(start + count - 1, end));
-		if (s->r_start >= start && s->r_end <= end
-		    && (s->r_end - s->r_start + 1) == count &&
+	for (s = r; s && s->r_end <= end; s = TAILQ_NEXT(s, r_link)) {
+		if ((s->r_flags & flags) == flags &&
+		    s->r_start >= start &&
+		    (s->r_end - s->r_start + 1) == count &&
 		    (s->r_start & amask) == 0 &&
 		    ((s->r_start ^ s->r_end) & bmask) == 0) {
 			rv = int_alloc_resource(M_NOWAIT);
diff --git a/freebsd/sys/kern/subr_sbuf.c b/freebsd/sys/kern/subr_sbuf.c
index 9ea1199..e61b084 100644
--- a/freebsd/sys/kern/subr_sbuf.c
+++ b/freebsd/sys/kern/subr_sbuf.c
@@ -708,9 +708,10 @@ sbuf_finish(struct sbuf *s)
 #ifdef _KERNEL
 	return (s->s_error);
 #else
-	errno = s->s_error;
-	if (s->s_error)
+	if (s->s_error != 0) {
+		errno = s->s_error;
 		return (-1);
+	}
 	return (0);
 #endif
 }
diff --git a/freebsd/sys/kern/subr_taskqueue.c b/freebsd/sys/kern/subr_taskqueue.c
index 867b0e6..259b152 100644
--- a/freebsd/sys/kern/subr_taskqueue.c
+++ b/freebsd/sys/kern/subr_taskqueue.c
@@ -291,6 +291,15 @@ taskqueue_enqueue_timeout(struct taskqueue *queue,
 	return (res);
 }
 
+static void
+taskqueue_drain_running(struct taskqueue *queue)
+{
+
+	while (!TAILQ_EMPTY(&queue->tq_active))
+		TQ_SLEEP(queue, &queue->tq_active, &queue->tq_mutex,
+		    PWAIT, "-", 0);
+}
+
 void
 taskqueue_block(struct taskqueue *queue)
 {
@@ -343,6 +352,8 @@ taskqueue_run_locked(struct taskqueue *queue)
 		wakeup(task);
 	}
 	TAILQ_REMOVE(&queue->tq_active, &tb, tb_link);
+	if (TAILQ_EMPTY(&queue->tq_active))
+		wakeup(&queue->tq_active);
 }
 
 void
@@ -383,11 +394,9 @@ taskqueue_cancel_locked(struct taskqueue *queue, struct task *task,
 int
 taskqueue_cancel(struct taskqueue *queue, struct task *task, u_int *pendp)
 {
-	u_int pending;
 	int error;
 
 	TQ_LOCK(queue);
-	pending = task->ta_pending;
 	error = taskqueue_cancel_locked(queue, task, pendp);
 	TQ_UNLOCK(queue);
 
@@ -431,6 +440,27 @@ taskqueue_drain(struct taskqueue *queue, struct task *task)
 }
 
 void
+taskqueue_drain_all(struct taskqueue *queue)
+{
+	struct task *task;
+
+#ifndef __rtems__
+	if (!queue->tq_spin)
+		WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__);
+#endif /* __rtems__ */
+
+	TQ_LOCK(queue);
+	task = STAILQ_LAST(&queue->tq_queue, task, ta_link);
+	if (task != NULL)
+		while (task->ta_pending != 0)
+			TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0);
+	taskqueue_drain_running(queue);
+	KASSERT(STAILQ_EMPTY(&queue->tq_queue),
+	    ("taskqueue queue is not empty after draining"));
+	TQ_UNLOCK(queue);
+}
+
+void
 taskqueue_drain_timeout(struct taskqueue *queue,
     struct timeout_task *timeout_task)
 {
@@ -614,7 +644,6 @@ taskqueue_member(struct taskqueue *queue, struct thread *td)
 {
 	int i, j, ret = 0;
 
-	TQ_LOCK(queue);
 	for (i = 0, j = 0; ; i++) {
 		if (queue->tq_threads[i] == NULL)
 			continue;
@@ -625,6 +654,5 @@ taskqueue_member(struct taskqueue *queue, struct thread *td)
 		if (++j >= queue->tq_tcount)
 			break;
 	}
-	TQ_UNLOCK(queue);
 	return (ret);
 }
diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c
index 6fc16fc..eb1ed37 100644
--- a/freebsd/sys/kern/sys_generic.c
+++ b/freebsd/sys/kern/sys_generic.c
@@ -83,6 +83,10 @@ __FBSDID("$FreeBSD$");
 int iosize_max_clamp = 1;
 SYSCTL_INT(_debug, OID_AUTO, iosize_max_clamp, CTLFLAG_RW,
     &iosize_max_clamp, 0, "Clamp max i/o size to INT_MAX");
+int devfs_iosize_max_clamp = 1;
+SYSCTL_INT(_debug, OID_AUTO, devfs_iosize_max_clamp, CTLFLAG_RW,
+    &devfs_iosize_max_clamp, 0, "Clamp max i/o size to INT_MAX for devices");
+
 /*
  * Assert that the return value of read(2) and write(2) syscalls fits
  * into a register.  If not, an architecture will need to provide the
diff --git a/freebsd/sys/kern/uipc_sockbuf.c b/freebsd/sys/kern/uipc_sockbuf.c
index 2a0e527..03b18b9 100644
--- a/freebsd/sys/kern/uipc_sockbuf.c
+++ b/freebsd/sys/kern/uipc_sockbuf.c
@@ -623,29 +623,12 @@ sbappendrecord(struct sockbuf *sb, struct mbuf *m0)
 	SOCKBUF_UNLOCK(sb);
 }
 
-/*
- * Append address and data, and optionally, control (ancillary) data to the
- * receive queue of a socket.  If present, m0 must include a packet header
- * with total length.  Returns 0 if no space in sockbuf or insufficient
- * mbufs.
- */
-int
-sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
-    struct mbuf *m0, struct mbuf *control)
+/* Helper routine that appends data, control, and address to a sockbuf. */
+static int
+sbappendaddr_locked_internal(struct sockbuf *sb, const struct sockaddr *asa,
+    struct mbuf *m0, struct mbuf *control, struct mbuf *ctrl_last)
 {
 	struct mbuf *m, *n, *nlast;
-	int space = asa->sa_len;
-
-	SOCKBUF_LOCK_ASSERT(sb);
-
-	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
-		panic("sbappendaddr_locked");
-	if (m0)
-		space += m0->m_pkthdr.len;
-	space += m_length(control, &n);
-
-	if (space > sbspace(sb))
-		return (0);
 #if MSIZE <= 256
 	if (asa->sa_len > MLEN)
 		return (0);
@@ -655,8 +638,8 @@ sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
 		return (0);
 	m->m_len = asa->sa_len;
 	bcopy(asa, mtod(m, caddr_t), asa->sa_len);
-	if (n)
-		n->m_next = m0;		/* concatenate data to control */
+	if (ctrl_last)
+		ctrl_last->m_next = m0;	/* concatenate data to control */
 	else
 		control = m0;
 	m->m_next = control;
@@ -680,6 +663,50 @@ sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
  * mbufs.
  */
 int
+sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
+    struct mbuf *m0, struct mbuf *control)
+{
+	struct mbuf *ctrl_last;
+	int space = asa->sa_len;
+
+	SOCKBUF_LOCK_ASSERT(sb);
+
+	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
+		panic("sbappendaddr_locked");
+	if (m0)
+		space += m0->m_pkthdr.len;
+	space += m_length(control, &ctrl_last);
+
+	if (space > sbspace(sb))
+		return (0);
+	return (sbappendaddr_locked_internal(sb, asa, m0, control, ctrl_last));
+}
+
+/*
+ * Append address and data, and optionally, control (ancillary) data to the
+ * receive queue of a socket.  If present, m0 must include a packet header
+ * with total length.  Returns 0 if insufficient mbufs.  Does not validate space
+ * on the receiving sockbuf.
+ */
+int
+sbappendaddr_nospacecheck_locked(struct sockbuf *sb, const struct sockaddr *asa,
+    struct mbuf *m0, struct mbuf *control)
+{
+	struct mbuf *ctrl_last;
+
+	SOCKBUF_LOCK_ASSERT(sb);
+
+	ctrl_last = (control == NULL) ? NULL : m_last(control);
+	return (sbappendaddr_locked_internal(sb, asa, m0, control, ctrl_last));
+}
+
+/*
+ * Append address and data, and optionally, control (ancillary) data to the
+ * receive queue of a socket.  If present, m0 must include a packet header
+ * with total length.  Returns 0 if no space in sockbuf or insufficient
+ * mbufs.
+ */
+int
 sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
     struct mbuf *m0, struct mbuf *control)
 {
@@ -1024,6 +1051,11 @@ sbcreatecontrol(caddr_t p, int size, int type, int level)
 	m->m_len = 0;
 	KASSERT(CMSG_SPACE((u_int)size) <= M_TRAILINGSPACE(m),
 	    ("sbcreatecontrol: short mbuf"));
+	/*
+	 * Don't leave the padding between the msg header and the
+	 * cmsg data and the padding after the cmsg data un-initialized.
+	 */
+	bzero(cp, CMSG_SPACE((u_int)size));
 	if (p != NULL)
 		(void)memcpy(CMSG_DATA(cp), p, size);
 	m->m_len = CMSG_SPACE(size);
diff --git a/freebsd/sys/kern/uipc_socket.c b/freebsd/sys/kern/uipc_socket.c
index 9ca2c14..2dc76a9 100644
--- a/freebsd/sys/kern/uipc_socket.c
+++ b/freebsd/sys/kern/uipc_socket.c
@@ -151,6 +151,10 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysent.h>
 #include <compat/freebsd32/freebsd32.h>
 #endif
+#ifdef __rtems__
+#include <rtems/libio.h>
+#define maxfiles rtems_libio_number_iops
+#endif /* __rtems__ */
 
 static int	soreceive_rcvoob(struct socket *so, struct uio *uio,
 		    int flags);
@@ -256,12 +260,14 @@ SYSCTL_NODE(_kern, KERN_IPC, ipc, CTLFLAG_RW, 0, "IPC");
 uma_zone_t socket_zone;
 int	maxsockets;
 
+#ifndef __rtems__
 static void
 socket_zone_change(void *tag)
 {
 
 	uma_zone_set_max(socket_zone, maxsockets);
 }
+#endif /* __rtems__ */
 
 static void
 socket_init(void *tag)
@@ -270,8 +276,10 @@ socket_init(void *tag)
         socket_zone = uma_zcreate("socket", sizeof(struct socket), NULL, NULL,
             NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
         uma_zone_set_max(socket_zone, maxsockets);
+#ifndef __rtems__
         EVENTHANDLER_REGISTER(maxsockets_change, socket_zone_change, NULL,
                 EVENTHANDLER_PRI_FIRST);
+#endif /* __rtems__ */
 }
 SYSINIT(socket, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, socket_init, NULL);
 
@@ -284,11 +292,7 @@ init_maxsockets(void *ignored)
 {
 
 	TUNABLE_INT_FETCH("kern.ipc.maxsockets", &maxsockets);
-#ifndef __rtems__
-	maxsockets = imax(maxsockets, imax(maxfiles, nmbclusters));
-#else /* __rtems__ */
-	maxsockets = imax(maxsockets, nmbclusters);
-#endif /* __rtems__ */
+	maxsockets = imax(maxsockets, maxfiles);
 }
 SYSINIT(param, SI_SUB_TUNABLES, SI_ORDER_ANY, init_maxsockets, NULL);
 
@@ -304,15 +308,12 @@ sysctl_maxsockets(SYSCTL_HANDLER_ARGS)
 	newmaxsockets = maxsockets;
 	error = sysctl_handle_int(oidp, &newmaxsockets, 0, req);
 	if (error == 0 && req->newptr) {
-		if (newmaxsockets > maxsockets) {
+		if (newmaxsockets > maxsockets &&
+		    newmaxsockets <= maxfiles) {
 			maxsockets = newmaxsockets;
 #ifndef __rtems__
-			if (maxsockets > ((maxfiles / 4) * 3)) {
-				maxfiles = (maxsockets * 5) / 4;
-				maxfilesperproc = (maxfiles * 9) / 10;
-			}
-#endif /* __rtems__ */
 			EVENTHANDLER_INVOKE(maxsockets_change);
+#endif /* __rtems__ */
 		} else
 			error = EINVAL;
 	}
@@ -498,6 +499,10 @@ SYSCTL_INT(_regression, OID_AUTO, sonewconn_earlytest, CTLFLAG_RW,
 struct socket *
 sonewconn(struct socket *head, int connstatus)
 {
+	static struct timeval lastover;
+	static struct timeval overinterval = { 60, 0 };
+	static int overcount;
+
 	struct socket *so;
 	int over;
 
@@ -509,9 +514,17 @@ sonewconn(struct socket *head, int connstatus)
 #else
 	if (over) {
 #endif
-		log(LOG_DEBUG, "%s: pcb %p: Listen queue overflow: "
-		    "%i already in queue awaiting acceptance\n",
-		    __func__, head->so_pcb, head->so_qlen);
+		overcount++;
+
+		if (ratecheck(&lastover, &overinterval)) {
+			log(LOG_DEBUG, "%s: pcb %p: Listen queue overflow: "
+			    "%i already in queue awaiting acceptance "
+			    "(%d occurrences)\n",
+			    __func__, head->so_pcb, head->so_qlen, overcount);
+
+			overcount = 0;
+		}
+
 		return (NULL);
 	}
 	VNET_ASSERT(head->so_vnet != NULL, ("%s:%d so_vnet is NULL, head=%p",
@@ -2679,22 +2692,12 @@ sosetopt(struct socket *so, struct sockopt *sopt)
 				    sizeof tv);
 			if (error)
 				goto bad;
-
-			/* assert(hz > 0); */
-			if (tv.tv_sec < 0 || tv.tv_sec > INT_MAX / hz ||
-			    tv.tv_usec < 0 || tv.tv_usec >= 1000000) {
+			if (tv.tv_sec < 0 || tv.tv_usec < 0 ||
+			    tv.tv_usec >= 1000000) {
 				error = EDOM;
 				goto bad;
 			}
-			/* assert(tick > 0); */
-			/* assert(ULONG_MAX - INT_MAX >= 1000000); */
-			val = (u_long)(tv.tv_sec * hz) + tv.tv_usec / tick;
-			if (val > INT_MAX) {
-				error = EDOM;
-				goto bad;
-			}
-			if (val == 0 && tv.tv_usec != 0)
-				val = 1;
+			val = tvtohz(&tv);
 
 			switch (sopt->sopt_name) {
 			case SO_SNDTIMEO:
@@ -3039,8 +3042,10 @@ void
 sohasoutofband(struct socket *so)
 {
 
+#ifndef __rtems__
 	if (so->so_sigio != NULL)
 		pgsigio(&so->so_sigio, SIGURG, 0);
+#endif /* __rtems__ */
 	selwakeuppri(&so->so_rcv.sb_sel, PSOCK);
 }
 
diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c
index 738b5c3..b0c83e6 100644
--- a/freebsd/sys/kern/uipc_syscalls.c
+++ b/freebsd/sys/kern/uipc_syscalls.c
@@ -111,6 +111,13 @@ static int kern_getsockopt( struct thread *td, int s, int level, int name,
     void *val, enum uio_seg valseg, socklen_t *valsize);
 #endif /* __rtems__ */
 
+/*
+ * Creation flags, OR'ed into socket() and socketpair() type argument.
+ * For stable/9, these are supported but not exposed in the header file.
+ */
+#define	SOCK_CLOEXEC	0x10000000
+#define	SOCK_NONBLOCK	0x20000000
+
 static int sendit(struct thread *td, int s, struct msghdr *mp, int flags);
 static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp);
 
@@ -239,11 +246,26 @@ sys_socket(td, uap)
 #endif /* __rtems__ */
 	struct socket *so;
 	struct file *fp;
-	int fd, error;
+	int fd, error, type, oflag, fflag;
 
 	AUDIT_ARG_SOCKET(uap->domain, uap->type, uap->protocol);
+
+	type = uap->type;
+	oflag = 0;
+	fflag = 0;
+#ifndef __rtems__
+	if ((type & SOCK_CLOEXEC) != 0) {
+		type &= ~SOCK_CLOEXEC;
+		oflag |= O_CLOEXEC;
+	}
+#endif /* __rtems__ */
+	if ((type & SOCK_NONBLOCK) != 0) {
+		type &= ~SOCK_NONBLOCK;
+		fflag |= FNONBLOCK;
+	}
+
 #ifdef MAC
-	error = mac_socket_check_create(td->td_ucred, uap->domain, uap->type,
+	error = mac_socket_check_create(td->td_ucred, uap->domain, type,
 	    uap->protocol);
 	if (error)
 		return (error);
@@ -251,16 +273,18 @@ sys_socket(td, uap)
 #ifndef __rtems__
 	fdp = td->td_proc->p_fd;
 #endif /* __rtems__ */
-	error = falloc(td, &fp, &fd, 0);
+	error = falloc(td, &fp, &fd, oflag);
 	if (error)
 		return (error);
 	/* An extra reference on `fp' has been held for us by falloc(). */
-	error = socreate(uap->domain, &so, uap->type, uap->protocol,
+	error = socreate(uap->domain, &so, type, uap->protocol,
 	    td->td_ucred, td);
 	if (error) {
 		fdclose(fdp, fp, fd, td);
 	} else {
-		finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &socketops);
+		finit(fp, FREAD | FWRITE | fflag, DTYPE_SOCKET, so, &socketops);
+		if ((fflag & FNONBLOCK) != 0)
+			(void) fo_ioctl(fp, FIONBIO, &fflag, td->td_ucred, td);
 		td->td_retval[0] = fd;
 	}
 	fdrop(fp, td);
@@ -798,9 +822,20 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol,
 	struct filedesc *fdp = td->td_proc->p_fd;
 	struct file *fp1, *fp2;
 	struct socket *so1, *so2;
-	int fd, error;
+	int fd, error, oflag, fflag;
 
 	AUDIT_ARG_SOCKET(domain, type, protocol);
+
+	oflag = 0;
+	fflag = 0;
+	if ((type & SOCK_CLOEXEC) != 0) {
+		type &= ~SOCK_CLOEXEC;
+		oflag |= O_CLOEXEC;
+	}
+	if ((type & SOCK_NONBLOCK) != 0) {
+		type &= ~SOCK_NONBLOCK;
+		fflag |= FNONBLOCK;
+	}
 #ifdef MAC
 	/* We might want to have a separate check for socket pairs. */
 	error = mac_socket_check_create(td->td_ucred, domain, type,
@@ -815,12 +850,12 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol,
 	if (error)
 		goto free1;
 	/* On success extra reference to `fp1' and 'fp2' is set by falloc. */
-	error = falloc(td, &fp1, &fd, 0);
+	error = falloc(td, &fp1, &fd, oflag);
 	if (error)
 		goto free2;
 	rsv[0] = fd;
 	fp1->f_data = so1;	/* so1 already has ref count */
-	error = falloc(td, &fp2, &fd, 0);
+	error = falloc(td, &fp2, &fd, oflag);
 	if (error)
 		goto free3;
 	fp2->f_data = so2;	/* so2 already has ref count */
@@ -836,8 +871,14 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol,
 		 if (error)
 			goto free4;
 	}
-	finit(fp1, FREAD | FWRITE, DTYPE_SOCKET, fp1->f_data, &socketops);
-	finit(fp2, FREAD | FWRITE, DTYPE_SOCKET, fp2->f_data, &socketops);
+	finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data,
+	    &socketops);
+	finit(fp2, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp2->f_data,
+	    &socketops);
+	if ((fflag & FNONBLOCK) != 0) {
+		(void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td);
+		(void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td);
+	}
 	fdrop(fp1, td);
 	fdrop(fp2, td);
 	return (0);
diff --git a/freebsd/sys/kern/uipc_usrreq.c b/freebsd/sys/kern/uipc_usrreq.c
index 9254e9b..b7cc060 100644
--- a/freebsd/sys/kern/uipc_usrreq.c
+++ b/freebsd/sys/kern/uipc_usrreq.c
@@ -339,6 +339,7 @@ static struct protosw localsw[] = {
 	 */
 	.pr_flags =		PR_ADDR|PR_ATOMIC|PR_CONNREQUIRED|PR_WANTRCVD|
 				    PR_RIGHTS,
+	.pr_ctloutput =		&uipc_ctloutput,
 	.pr_usrreqs =		&uipc_usrreqs_seqpacket,
 },
 };
@@ -985,7 +986,8 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
 			from = &sun_noname;
 		so2 = unp2->unp_socket;
 		SOCKBUF_LOCK(&so2->so_rcv);
-		if (sbappendaddr_locked(&so2->so_rcv, from, m, control)) {
+		if (sbappendaddr_nospacecheck_locked(&so2->so_rcv, from, m,
+		    control)) {
 			sorwakeup_locked(so2);
 			m = NULL;
 			control = NULL;
@@ -1047,7 +1049,8 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
 		if (unp2->unp_flags & UNP_WANTCRED) {
 #ifndef __rtems__
 			/*
-			 * Credentials are passed only once on SOCK_STREAM.
+			 * Credentials are passed only once on SOCK_STREAM
+			 * and SOCK_SEQPACKET.
 			 */
 			unp2->unp_flags &= ~UNP_WANTCRED;
 			control = unp_addsockcred(td, control);
@@ -1071,8 +1074,14 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
 			const struct sockaddr *from;
 
 			from = &sun_noname;
-			if (sbappendaddr_locked(&so2->so_rcv, from, m,
-			    control))
+			/*
+			 * Don't check for space available in so2->so_rcv.
+			 * Unix domain sockets only check for space in the
+			 * sending sockbuf, and that check is performed one
+			 * level up the stack.
+			 */
+			if (sbappendaddr_nospacecheck_locked(&so2->so_rcv,
+				from, m, control))
 				control = NULL;
 			break;
 			}
@@ -1495,7 +1504,7 @@ unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 		}
 
 		/*
-		 * The connecter's (client's) credentials are copied from its
+		 * The connector's (client's) credentials are copied from its
 		 * process structure at the time of connect() (which is now).
 		 */
 		cru2x(td->td_ucred, &unp3->unp_peercred);
diff --git a/freebsd/sys/mips/include/machine/cpufunc.h b/freebsd/sys/mips/include/machine/cpufunc.h
index bfabe90..7429312 100644
--- a/freebsd/sys/mips/include/machine/cpufunc.h
+++ b/freebsd/sys/mips/include/machine/cpufunc.h
@@ -70,7 +70,7 @@ static __inline void
 mips_barrier(void)
 {
 #ifdef CPU_CNMIPS
-	__asm __volatile("" : : : "memory");
+	__compiler_membar();
 #else
 	__asm __volatile (".set noreorder\n\t"
 			  "nop\n\t"
diff --git a/freebsd/sys/net/ieee8023ad_lacp.c b/freebsd/sys/net/ieee8023ad_lacp.c
index a1c1e49..2028892 100644
--- a/freebsd/sys/net/ieee8023ad_lacp.c
+++ b/freebsd/sys/net/ieee8023ad_lacp.c
@@ -1030,8 +1030,45 @@ lacp_compose_key(struct lacp_port *lp)
 		KASSERT(IFM_TYPE(media) == IFM_ETHER, ("invalid media type"));
 		KASSERT((media & IFM_FDX) != 0, ("aggregating HDX interface"));
 
-		/* bit 0..4:	IFM_SUBTYPE */
-		key = subtype;
+		/* bit 0..4:	IFM_SUBTYPE modulo speed */
+		switch (subtype) {
+		case IFM_10_T:
+		case IFM_10_2:
+		case IFM_10_5:
+		case IFM_10_STP:
+		case IFM_10_FL:
+			key = IFM_10_T;
+			break;
+		case IFM_100_TX:
+		case IFM_100_FX:
+		case IFM_100_T4:
+		case IFM_100_VG:
+		case IFM_100_T2:
+			key = IFM_100_TX;
+			break;
+		case IFM_1000_SX:
+		case IFM_1000_LX:
+		case IFM_1000_CX:
+		case IFM_1000_T:
+			key = IFM_1000_SX;
+			break;
+		case IFM_10G_LR:
+		case IFM_10G_SR:
+		case IFM_10G_CX4:
+		case IFM_10G_TWINAX:
+		case IFM_10G_TWINAX_LONG:
+		case IFM_10G_LRM:
+		case IFM_10G_T:
+			key = IFM_10G_LR;
+			break;
+		case IFM_40G_CR4:
+		case IFM_40G_SR4:
+		case IFM_40G_LR4:
+			key = IFM_40G_CR4;
+			break;
+		default:
+			key = subtype;
+		}
 		/* bit 5..14:	(some bits of) if_index of lagg device */
 		key |= 0x7fe0 & ((sc->sc_ifp->if_index) << 5);
 		/* bit 15:	0 */
diff --git a/freebsd/sys/net/if.c b/freebsd/sys/net/if.c
index ea4a8a4..0bd72e4 100644
--- a/freebsd/sys/net/if.c
+++ b/freebsd/sys/net/if.c
@@ -76,6 +76,7 @@
 #include <net/vnet.h>
 
 #if defined(INET) || defined(INET6)
+#include <net/ethernet.h>
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/ip.h>
@@ -676,7 +677,8 @@ if_attach_internal(struct ifnet *ifp, int vmove)
 #if defined(INET) || defined(INET6)
 		/* Initialize to max value. */
 		if (ifp->if_hw_tsomax == 0)
-			ifp->if_hw_tsomax = IP_MAXPACKET;
+			ifp->if_hw_tsomax = min(IP_MAXPACKET, 32 * MCLBYTES -
+			    (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN));
 		KASSERT(ifp->if_hw_tsomax <= IP_MAXPACKET &&
 		    ifp->if_hw_tsomax >= IP_MAXPACKET / 8,
 		    ("%s: tsomax outside of range", __func__));
diff --git a/freebsd/sys/net/if_lagg.c b/freebsd/sys/net/if_lagg.c
index 4dee2af..b0be364 100644
--- a/freebsd/sys/net/if_lagg.c
+++ b/freebsd/sys/net/if_lagg.c
@@ -56,11 +56,11 @@ __FBSDID("$FreeBSD$");
 
 #if defined(INET) || defined(INET6)
 #include <netinet/in.h>
+#include <netinet/ip.h>
 #endif
 #ifdef INET
 #include <netinet/in_systm.h>
 #include <netinet/if_ether.h>
-#include <netinet/ip.h>
 #endif
 
 #ifdef INET6
@@ -408,6 +408,11 @@ lagg_capabilities(struct lagg_softc *sc)
 	struct lagg_port *lp;
 	int cap = ~0, ena = ~0;
 	u_long hwa = ~0UL;
+#if defined(INET) || defined(INET6)
+	u_int hw_tsomax = IP_MAXPACKET;	/* Initialize to the maximum value. */
+#else
+	u_int hw_tsomax = ~0;	/* if_hw_tsomax is only for INET/INET6, but.. */
+#endif
 
 	LAGG_WLOCK_ASSERT(sc);
 
@@ -416,6 +421,10 @@ lagg_capabilities(struct lagg_softc *sc)
 		cap &= lp->lp_ifp->if_capabilities;
 		ena &= lp->lp_ifp->if_capenable;
 		hwa &= lp->lp_ifp->if_hwassist;
+		/* Set to the minimum value of the lagg ports. */
+		if (lp->lp_ifp->if_hw_tsomax < hw_tsomax &&
+		    lp->lp_ifp->if_hw_tsomax > 0)
+			hw_tsomax = lp->lp_ifp->if_hw_tsomax;
 	}
 	cap = (cap == ~0 ? 0 : cap);
 	ena = (ena == ~0 ? 0 : ena);
@@ -423,10 +432,12 @@ lagg_capabilities(struct lagg_softc *sc)
 
 	if (sc->sc_ifp->if_capabilities != cap ||
 	    sc->sc_ifp->if_capenable != ena ||
-	    sc->sc_ifp->if_hwassist != hwa) {
+	    sc->sc_ifp->if_hwassist != hwa ||
+	    sc->sc_ifp->if_hw_tsomax != hw_tsomax) {
 		sc->sc_ifp->if_capabilities = cap;
 		sc->sc_ifp->if_capenable = ena;
 		sc->sc_ifp->if_hwassist = hwa;
+		sc->sc_ifp->if_hw_tsomax = hw_tsomax;
 		getmicrotime(&sc->sc_ifp->if_lastchange);
 
 		if (sc->sc_ifflags & IFF_DEBUG)
@@ -822,7 +833,7 @@ lagg_port_output(struct ifnet *ifp, struct mbuf *m,
 
 	/* drop any other frames */
 	m_freem(m);
-	return (EBUSY);
+	return (ENETDOWN);
 }
 
 static void
@@ -1895,7 +1906,7 @@ lagg_lacp_start(struct lagg_softc *sc, struct mbuf *m)
 	lp = lacp_select_tx_port(sc, m);
 	if (lp == NULL) {
 		m_freem(m);
-		return (EBUSY);
+		return (ENETDOWN);
 	}
 
 	/* Send mbuf */
diff --git a/freebsd/sys/net/if_media.h b/freebsd/sys/net/if_media.h
index 6424d66..1258509 100644
--- a/freebsd/sys/net/if_media.h
+++ b/freebsd/sys/net/if_media.h
@@ -153,7 +153,10 @@ uint64_t	ifmedia_baudrate(int);
 #define	IFM_40G_CR4	27		/* 40GBase-CR4 */
 #define	IFM_40G_SR4	28		/* 40GBase-SR4 */
 #define	IFM_40G_LR4	29		/* 40GBase-LR4 */
-
+/*
+ * Please update ieee8023ad_lacp.c:lacp_compose_key()
+ * after adding new Ethernet media types.
+ */
 /* note 31 is the max! */
 
 #define	IFM_ETH_MASTER	0x00000100	/* master mode (1000baseT) */
diff --git a/freebsd/sys/net/if_spppsubr.c b/freebsd/sys/net/if_spppsubr.c
index 4f2f6d0..fa6a7c1 100644
--- a/freebsd/sys/net/if_spppsubr.c
+++ b/freebsd/sys/net/if_spppsubr.c
@@ -3621,7 +3621,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len)
 				continue;
 			}
 
-			bzero(&suggestaddr, sizeof(&suggestaddr));
+			bzero(&suggestaddr, sizeof(suggestaddr));
 			if (collision && nohisaddr) {
 				/* collision, hisaddr unknown - Conf-Rej */
 				type = CONF_REJ;
diff --git a/freebsd/sys/net/if_tap.c b/freebsd/sys/net/if_tap.c
index 9c501f1..599905e 100644
--- a/freebsd/sys/net/if_tap.c
+++ b/freebsd/sys/net/if_tap.c
@@ -215,14 +215,10 @@ tap_destroy(struct tap_softc *tp)
 {
 	struct ifnet *ifp = tp->tap_ifp;
 
-	/* Unlocked read. */
-	KASSERT(!(tp->tap_flags & TAP_OPEN),
-		("%s flags is out of sync", ifp->if_xname));
-
 	CURVNET_SET(ifp->if_vnet);
+	destroy_dev(tp->tap_dev);
 	seldrain(&tp->tap_rsel);
 	knlist_destroy(&tp->tap_rsel.si_note);
-	destroy_dev(tp->tap_dev);
 	ether_ifdetach(ifp);
 	if_free_type(ifp, IFT_ETHER);
 
diff --git a/freebsd/sys/net/if_tun.c b/freebsd/sys/net/if_tun.c
index 25b7329..556a486 100644
--- a/freebsd/sys/net/if_tun.c
+++ b/freebsd/sys/net/if_tun.c
@@ -324,6 +324,7 @@ static moduledata_t tun_mod = {
 };
 
 DECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+MODULE_VERSION(if_tun, 1);
 
 static void
 tunstart(struct ifnet *ifp)
diff --git a/freebsd/sys/net/if_vlan.c b/freebsd/sys/net/if_vlan.c
index f31b9be..accfbbb 100644
--- a/freebsd/sys/net/if_vlan.c
+++ b/freebsd/sys/net/if_vlan.c
@@ -1503,6 +1503,8 @@ vlan_capabilities(struct ifvlan *ifv)
 	 * propagate the hardware-assisted flag. TSO on VLANs
 	 * does not necessarily require hardware VLAN tagging.
 	 */
+	if (p->if_hw_tsomax > 0)
+		ifp->if_hw_tsomax = p->if_hw_tsomax;
 	if (p->if_capabilities & IFCAP_VLAN_HWTSO)
 		ifp->if_capabilities |= p->if_capabilities & IFCAP_TSO;
 	if (p->if_capenable & IFCAP_VLAN_HWTSO) {
diff --git a/freebsd/sys/net/radix.c b/freebsd/sys/net/radix.c
index 875a482..ba15eb5 100644
--- a/freebsd/sys/net/radix.c
+++ b/freebsd/sys/net/radix.c
@@ -68,27 +68,27 @@ static struct radix_node
 	 *rn_search(void *, struct radix_node *),
 	 *rn_search_m(void *, struct radix_node *, void *);
 
-static int	max_keylen;
-static struct radix_mask *rn_mkfreelist;
-static struct radix_node_head *mask_rnhead;
+static void rn_detachhead_internal(void **head);
+static int rn_inithead_internal(void **head, int off);
+
+#define	RADIX_MAX_KEY_LEN	32
+
+static char rn_zeros[RADIX_MAX_KEY_LEN];
+static char rn_ones[RADIX_MAX_KEY_LEN] = {
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1,
+};
+
 /*
- * Work area -- the following point to 3 buffers of size max_keylen,
- * allocated in this order in a block of memory malloc'ed by rn_init.
- * rn_zeros, rn_ones are set in rn_init and used in readonly afterwards.
- * addmask_key is used in rn_addmask in rw mode and not thread-safe.
+ * XXX: Compat stuff for old rn_addmask() users
  */
-static char *rn_zeros, *rn_ones, *addmask_key;
-
-#define MKGet(m) {						\
-	if (rn_mkfreelist) {					\
-		m = rn_mkfreelist;				\
-		rn_mkfreelist = (m)->rm_mklist;			\
-	} else							\
-		R_Malloc(m, struct radix_mask *, sizeof (struct radix_mask)); }
- 
-#define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);}
+static struct radix_node_head *mask_rnhead_compat;
+#ifdef	_KERNEL
+static struct mtx mask_mtx;
+#endif
 
-#define rn_masktop (mask_rnhead->rnh_treetop)
 
 static int	rn_lexobetter(void *m_arg, void *n_arg);
 static struct radix_mask *
@@ -158,12 +158,10 @@ static int	rn_satisfies_leaf(char *trial, struct radix_node *leaf,
  * Search a node in the tree matching the key.
  */
 static struct radix_node *
-rn_search(v_arg, head)
-	void *v_arg;
-	struct radix_node *head;
+rn_search(void *v_arg, struct radix_node *head)
 {
-	register struct radix_node *x;
-	register caddr_t v;
+	struct radix_node *x;
+	caddr_t v;
 
 	for (x = head, v = v_arg; x->rn_bit >= 0;) {
 		if (x->rn_bmask & v[x->rn_offset])
@@ -179,12 +177,10 @@ rn_search(v_arg, head)
  * XXX note this function is used only once.
  */
 static struct radix_node *
-rn_search_m(v_arg, head, m_arg)
-	struct radix_node *head;
-	void *v_arg, *m_arg;
+rn_search_m(void *v_arg, struct radix_node *head, void *m_arg)
 {
-	register struct radix_node *x;
-	register caddr_t v = v_arg, m = m_arg;
+	struct radix_node *x;
+	caddr_t v = v_arg, m = m_arg;
 
 	for (x = head; x->rn_bit >= 0;) {
 		if ((x->rn_bmask & m[x->rn_offset]) &&
@@ -193,15 +189,14 @@ rn_search_m(v_arg, head, m_arg)
 		else
 			x = x->rn_left;
 	}
-	return x;
+	return (x);
 }
 
 int
-rn_refines(m_arg, n_arg)
-	void *m_arg, *n_arg;
+rn_refines(void *m_arg, void *n_arg)
 {
-	register caddr_t m = m_arg, n = n_arg;
-	register caddr_t lim, lim2 = lim = n + LEN(n);
+	caddr_t m = m_arg, n = n_arg;
+	caddr_t lim, lim2 = lim = n + LEN(n);
 	int longer = LEN(n++) - LEN(m++);
 	int masks_are_equal = 1;
 
@@ -209,49 +204,71 @@ rn_refines(m_arg, n_arg)
 		lim -= longer;
 	while (n < lim) {
 		if (*n & ~(*m))
-			return 0;
+			return (0);
 		if (*n++ != *m++)
 			masks_are_equal = 0;
 	}
 	while (n < lim2)
 		if (*n++)
-			return 0;
+			return (0);
 	if (masks_are_equal && (longer < 0))
 		for (lim2 = m - longer; m < lim2; )
 			if (*m++)
-				return 1;
+				return (1);
 	return (!masks_are_equal);
 }
 
+/*
+ * Search for exact match in given @head.
+ * Assume host bits are cleared in @v_arg if @m_arg is not NULL
+ * Note that prefixes with /32 or /128 masks are treated differently
+ * from host routes.
+ */
 struct radix_node *
-rn_lookup(v_arg, m_arg, head)
-	void *v_arg, *m_arg;
-	struct radix_node_head *head;
+rn_lookup(void *v_arg, void *m_arg, struct radix_node_head *head)
 {
-	register struct radix_node *x;
-	caddr_t netmask = 0;
+	struct radix_node *x;
+	caddr_t netmask;
 
-	if (m_arg) {
-		x = rn_addmask(m_arg, 1, head->rnh_treetop->rn_offset);
-		if (x == 0)
-			return (0);
+	if (m_arg != NULL) {
+		/*
+		 * Most common case: search exact prefix/mask
+		 */
+		x = rn_addmask_r(m_arg, head->rnh_masks, 1,
+		    head->rnh_treetop->rn_offset);
+		if (x == NULL)
+			return (NULL);
 		netmask = x->rn_key;
-	}
-	x = rn_match(v_arg, head);
-	if (x && netmask) {
-		while (x && x->rn_mask != netmask)
+
+		x = rn_match(v_arg, head);
+
+		while (x != NULL && x->rn_mask != netmask)
 			x = x->rn_dupedkey;
+
+		return (x);
 	}
-	return x;
+
+	/*
+	 * Search for host address.
+	 */
+	if ((x = rn_match(v_arg, head)) == NULL)
+		return (NULL);
+
+	/* Check if found key is the same */
+	if (LEN(x->rn_key) != LEN(v_arg) || bcmp(x->rn_key, v_arg, LEN(v_arg)))
+		return (NULL);
+
+	/* Check if this is not host route */
+	if (x->rn_mask != NULL)
+		return (NULL);
+
+	return (x);
 }
 
 static int
-rn_satisfies_leaf(trial, leaf, skip)
-	char *trial;
-	register struct radix_node *leaf;
-	int skip;
+rn_satisfies_leaf(char *trial, struct radix_node *leaf, int skip)
 {
-	register char *cp = trial, *cp2 = leaf->rn_key, *cp3 = leaf->rn_mask;
+	char *cp = trial, *cp2 = leaf->rn_key, *cp3 = leaf->rn_mask;
 	char *cplim;
 	int length = min(LEN(cp), LEN(cp2));
 
@@ -262,22 +279,23 @@ rn_satisfies_leaf(trial, leaf, skip)
 	cplim = cp + length; cp3 += skip; cp2 += skip;
 	for (cp += skip; cp < cplim; cp++, cp2++, cp3++)
 		if ((*cp ^ *cp2) & *cp3)
-			return 0;
-	return 1;
+			return (0);
+	return (1);
 }
 
+/*
+ * Search for longest-prefix match in given @head
+ */
 struct radix_node *
-rn_match(v_arg, head)
-	void *v_arg;
-	struct radix_node_head *head;
+rn_match(void *v_arg, struct radix_node_head *head)
 {
 	caddr_t v = v_arg;
-	register struct radix_node *t = head->rnh_treetop, *x;
-	register caddr_t cp = v, cp2;
+	struct radix_node *t = head->rnh_treetop, *x;
+	caddr_t cp = v, cp2;
 	caddr_t cplim;
 	struct radix_node *saved_t, *top = t;
 	int off = t->rn_offset, vlen = LEN(cp), matched_off;
-	register int test, b, rn_bit;
+	int test, b, rn_bit;
 
 	/*
 	 * Open code rn_search(v, top) to avoid overhead of extra
@@ -315,7 +333,7 @@ rn_match(v_arg, head)
 	 */
 	if (t->rn_flags & RNF_ROOT)
 		t = t->rn_dupedkey;
-	return t;
+	return (t);
 on1:
 	test = (*cp ^ *cp2) & 0xff; /* find first bit that differs */
 	for (b = 7; (test >>= 1) > 0;)
@@ -336,13 +354,13 @@ on1:
 		 */
 		if (t->rn_flags & RNF_NORMAL) {
 			if (rn_bit <= t->rn_bit)
-				return t;
+				return (t);
 		} else if (rn_satisfies_leaf(v, t, matched_off))
-				return t;
+				return (t);
 	t = saved_t;
 	/* start searching up the tree */
 	do {
-		register struct radix_mask *m;
+		struct radix_mask *m;
 		t = t->rn_parent;
 		m = t->rn_mklist;
 		/*
@@ -361,12 +379,12 @@ on1:
 				while (x && x->rn_mask != m->rm_mask)
 					x = x->rn_dupedkey;
 				if (x && rn_satisfies_leaf(v, x, off))
-					return x;
+					return (x);
 			}
 			m = m->rm_mklist;
 		}
 	} while (t != top);
-	return 0;
+	return (0);
 }
 
 #ifdef RN_DEBUG
@@ -388,12 +406,9 @@ int	rn_debug =  1;
  */
 
 static struct radix_node *
-rn_newpair(v, b, nodes)
-	void *v;
-	int b;
-	struct radix_node nodes[2];
+rn_newpair(void *v, int b, struct radix_node nodes[2])
 {
-	register struct radix_node *tt = nodes, *t = tt + 1;
+	struct radix_node *tt = nodes, *t = tt + 1;
 	t->rn_bit = b;
 	t->rn_bmask = 0x80 >> (b & 7);
 	t->rn_left = tt;
@@ -417,44 +432,39 @@ rn_newpair(v, b, nodes)
 	tt->rn_ybro = rn_clist;
 	rn_clist = tt;
 #endif
-	return t;
+	return (t);
 }
 
 static struct radix_node *
-rn_insert(v_arg, head, dupentry, nodes)
-	void *v_arg;
-	struct radix_node_head *head;
-	int *dupentry;
-	struct radix_node nodes[2];
+rn_insert(void *v_arg, struct radix_node_head *head, int *dupentry,
+    struct radix_node nodes[2])
 {
 	caddr_t v = v_arg;
 	struct radix_node *top = head->rnh_treetop;
 	int head_off = top->rn_offset, vlen = LEN(v);
-	register struct radix_node *t = rn_search(v_arg, top);
-	register caddr_t cp = v + head_off;
-	register int b;
-	struct radix_node *tt;
+	struct radix_node *t = rn_search(v_arg, top);
+	caddr_t cp = v + head_off;
+	int b;
+	struct radix_node *p, *tt, *x;
     	/*
 	 * Find first bit at which v and t->rn_key differ
 	 */
-    {
-	register caddr_t cp2 = t->rn_key + head_off;
-	register int cmp_res;
+	caddr_t cp2 = t->rn_key + head_off;
+	int cmp_res;
 	caddr_t cplim = v + vlen;
 
 	while (cp < cplim)
 		if (*cp2++ != *cp++)
 			goto on1;
 	*dupentry = 1;
-	return t;
+	return (t);
 on1:
 	*dupentry = 0;
 	cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
 	for (b = (cp - v) << 3; cmp_res; b--)
 		cmp_res >>= 1;
-    }
-    {
-	register struct radix_node *p, *x = top;
+
+	x = top;
 	cp = v;
 	do {
 		p = x;
@@ -486,58 +496,51 @@ on1:
 	if (rn_debug)
 		log(LOG_DEBUG, "rn_insert: Coming Out:\n"), traverse(p);
 #endif
-    }
 	return (tt);
 }
 
 struct radix_node *
-rn_addmask(n_arg, search, skip)
-	int search, skip;
-	void *n_arg;
+rn_addmask_r(void *arg, struct radix_node_head *maskhead, int search, int skip)
 {
-	caddr_t netmask = (caddr_t)n_arg;
-	register struct radix_node *x;
-	register caddr_t cp, cplim;
-	register int b = 0, mlen, j;
-	int maskduplicated, m0, isnormal;
+	unsigned char *netmask = arg;
+	unsigned char *cp, *cplim;
+	struct radix_node *x;
+	int b = 0, mlen, j;
+	int maskduplicated, isnormal;
 	struct radix_node *saved_x;
-	static int last_zeroed = 0;
+	unsigned char addmask_key[RADIX_MAX_KEY_LEN];
 
-	if ((mlen = LEN(netmask)) > max_keylen)
-		mlen = max_keylen;
+	if ((mlen = LEN(netmask)) > RADIX_MAX_KEY_LEN)
+		mlen = RADIX_MAX_KEY_LEN;
 	if (skip == 0)
 		skip = 1;
 	if (mlen <= skip)
-		return (mask_rnhead->rnh_nodes);
+		return (maskhead->rnh_nodes);
+
+	bzero(addmask_key, RADIX_MAX_KEY_LEN);
 	if (skip > 1)
 		bcopy(rn_ones + 1, addmask_key + 1, skip - 1);
-	if ((m0 = mlen) > skip)
-		bcopy(netmask + skip, addmask_key + skip, mlen - skip);
+	bcopy(netmask + skip, addmask_key + skip, mlen - skip);
 	/*
 	 * Trim trailing zeroes.
 	 */
 	for (cp = addmask_key + mlen; (cp > addmask_key) && cp[-1] == 0;)
 		cp--;
 	mlen = cp - addmask_key;
-	if (mlen <= skip) {
-		if (m0 >= last_zeroed)
-			last_zeroed = mlen;
-		return (mask_rnhead->rnh_nodes);
-	}
-	if (m0 < last_zeroed)
-		bzero(addmask_key + m0, last_zeroed - m0);
-	*addmask_key = last_zeroed = mlen;
-	x = rn_search(addmask_key, rn_masktop);
+	if (mlen <= skip)
+		return (maskhead->rnh_nodes);
+	*addmask_key = mlen;
+	x = rn_search(addmask_key, maskhead->rnh_treetop);
 	if (bcmp(addmask_key, x->rn_key, mlen) != 0)
 		x = 0;
 	if (x || search)
 		return (x);
-	R_Zalloc(x, struct radix_node *, max_keylen + 2 * sizeof (*x));
+	R_Zalloc(x, struct radix_node *, RADIX_MAX_KEY_LEN + 2 * sizeof (*x));
 	if ((saved_x = x) == 0)
 		return (0);
 	netmask = cp = (caddr_t)(x + 2);
 	bcopy(addmask_key, cp, mlen);
-	x = rn_insert(cp, mask_rnhead, &maskduplicated, x);
+	x = rn_insert(cp, maskhead, &maskduplicated, x);
 	if (maskduplicated) {
 		log(LOG_ERR, "rn_addmask: mask impossibly already in tree");
 		Free(saved_x);
@@ -547,20 +550,18 @@ rn_addmask(n_arg, search, skip)
 	 * Calculate index of mask, and check for normalcy.
 	 * First find the first byte with a 0 bit, then if there are
 	 * more bits left (remember we already trimmed the trailing 0's),
-	 * the pattern must be one of those in normal_chars[], or we have
+	 * the bits should be contiguous, otherwise we have got
 	 * a non-contiguous mask.
 	 */
+#define	CONTIG(_c)	(((~(_c) + 1) & (_c)) == (unsigned char)(~(_c) + 1))
 	cplim = netmask + mlen;
 	isnormal = 1;
 	for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;)
 		cp++;
 	if (cp != cplim) {
-		static char normal_chars[] = {
-			0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
-
 		for (j = 0x80; (j & *cp) != 0; j >>= 1)
 			b++;
-		if (*cp != normal_chars[b] || cp != (cplim - 1))
+		if (!CONTIG(*cp) || cp != (cplim - 1))
 			isnormal = 0;
 	}
 	b += (cp - netmask) << 3;
@@ -570,34 +571,48 @@ rn_addmask(n_arg, search, skip)
 	return (x);
 }
 
+struct radix_node *
+rn_addmask(void *n_arg, int search, int skip)
+{
+	struct radix_node *tt;
+
+#ifdef _KERNEL
+	mtx_lock(&mask_mtx);
+#endif
+	tt = rn_addmask_r(&mask_rnhead_compat, n_arg, search, skip);
+
+#ifdef _KERNEL
+	mtx_unlock(&mask_mtx);
+#endif
+
+	return (tt);
+}
+
 static int	/* XXX: arbitrary ordering for non-contiguous masks */
-rn_lexobetter(m_arg, n_arg)
-	void *m_arg, *n_arg;
+rn_lexobetter(void *m_arg, void *n_arg)
 {
-	register u_char *mp = m_arg, *np = n_arg, *lim;
+	u_char *mp = m_arg, *np = n_arg, *lim;
 
 	if (LEN(mp) > LEN(np))
-		return 1;  /* not really, but need to check longer one first */
+		return (1);  /* not really, but need to check longer one first */
 	if (LEN(mp) == LEN(np))
 		for (lim = mp + LEN(mp); mp < lim;)
 			if (*mp++ > *np++)
-				return 1;
-	return 0;
+				return (1);
+	return (0);
 }
 
 static struct radix_mask *
-rn_new_radix_mask(tt, next)
-	register struct radix_node *tt;
-	register struct radix_mask *next;
+rn_new_radix_mask(struct radix_node *tt, struct radix_mask *next)
 {
-	register struct radix_mask *m;
+	struct radix_mask *m;
 
-	MKGet(m);
-	if (m == 0) {
-		log(LOG_ERR, "Mask for route not entered\n");
+	R_Malloc(m, struct radix_mask *, sizeof (struct radix_mask));
+	if (m == NULL) {
+		log(LOG_ERR, "Failed to allocate route mask\n");
 		return (0);
 	}
-	bzero(m, sizeof *m);
+	bzero(m, sizeof(*m));
 	m->rm_bit = tt->rn_bit;
 	m->rm_flags = tt->rn_flags;
 	if (tt->rn_flags & RNF_NORMAL)
@@ -606,17 +621,15 @@ rn_new_radix_mask(tt, next)
 		m->rm_mask = tt->rn_mask;
 	m->rm_mklist = next;
 	tt->rn_mklist = m;
-	return m;
+	return (m);
 }
 
 struct radix_node *
-rn_addroute(v_arg, n_arg, head, treenodes)
-	void *v_arg, *n_arg;
-	struct radix_node_head *head;
-	struct radix_node treenodes[2];
+rn_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
+    struct radix_node treenodes[2])
 {
 	caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
-	register struct radix_node *t, *x = 0, *tt;
+	struct radix_node *t, *x = 0, *tt;
 	struct radix_node *saved_tt, *top = head->rnh_treetop;
 	short b = 0, b_leaf = 0;
 	int keyduplicated;
@@ -631,7 +644,8 @@ rn_addroute(v_arg, n_arg, head, treenodes)
 	 * nodes and possibly save time in calculating indices.
 	 */
 	if (netmask)  {
-		if ((x = rn_addmask(netmask, 0, top->rn_offset)) == 0)
+		x = rn_addmask_r(netmask, head->rnh_masks, 0, top->rn_offset);
+		if (x == NULL)
 			return (0);
 		b_leaf = x->rn_bit;
 		b = -1 - x->rn_bit;
@@ -743,7 +757,7 @@ rn_addroute(v_arg, n_arg, head, treenodes)
 on2:
 	/* Add new route to highest possible ancestor's list */
 	if ((netmask == 0) || (b > t->rn_bit ))
-		return tt; /* can't lift at all */
+		return (tt); /* can't lift at all */
 	b_leaf = tt->rn_bit;
 	do {
 		x = t;
@@ -767,29 +781,27 @@ on2:
 			    log(LOG_ERR,
 			        "Non-unique normal route, mask not entered\n");
 #endif
-				return tt;
+				return (tt);
 			}
 		} else
 			mmask = m->rm_mask;
 		if (mmask == netmask) {
 			m->rm_refs++;
 			tt->rn_mklist = m;
-			return tt;
+			return (tt);
 		}
 		if (rn_refines(netmask, mmask)
 		    || rn_lexobetter(netmask, mmask))
 			break;
 	}
 	*mp = rn_new_radix_mask(tt, *mp);
-	return tt;
+	return (tt);
 }
 
 struct radix_node *
-rn_delete(v_arg, netmask_arg, head)
-	void *v_arg, *netmask_arg;
-	struct radix_node_head *head;
+rn_delete(void *v_arg, void *netmask_arg, struct radix_node_head *head)
 {
-	register struct radix_node *t, *p, *x, *tt;
+	struct radix_node *t, *p, *x, *tt;
 	struct radix_mask *m, *saved_m, **mp;
 	struct radix_node *dupedkey, *saved_tt, *top;
 	caddr_t v, netmask;
@@ -810,7 +822,8 @@ rn_delete(v_arg, netmask_arg, head)
 	 * Delete our route from mask lists.
 	 */
 	if (netmask) {
-		if ((x = rn_addmask(netmask, 1, head_off)) == 0)
+		x = rn_addmask_r(netmask, head->rnh_masks, 1, head_off);
+		if (x == NULL)
 			return (0);
 		netmask = x->rn_key;
 		while (tt->rn_mask != netmask)
@@ -822,7 +835,7 @@ rn_delete(v_arg, netmask_arg, head)
 	if (tt->rn_flags & RNF_NORMAL) {
 		if (m->rm_leaf != tt || m->rm_refs > 0) {
 			log(LOG_ERR, "rn_delete: inconsistent annotation\n");
-			return 0;  /* dangling ref could cause disaster */
+			return (0);  /* dangling ref could cause disaster */
 		}
 	} else {
 		if (m->rm_mask != tt->rn_mask) {
@@ -843,7 +856,7 @@ rn_delete(v_arg, netmask_arg, head)
 	for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist)
 		if (m == saved_m) {
 			*mp = m->rm_mklist;
-			MKFree(m);
+			Free(m);
 			break;
 		}
 	if (m == 0) {
@@ -934,7 +947,7 @@ on1:
 					struct radix_mask *mm = m->rm_mklist;
 					x->rn_mklist = 0;
 					if (--(m->rm_refs) < 0)
-						MKFree(m);
+						Free(m);
 					m = mm;
 				}
 			if (m)
@@ -974,17 +987,14 @@ out:
  * exit.
  */
 static int
-rn_walktree_from(h, a, m, f, w)
-	struct radix_node_head *h;
-	void *a, *m;
-	walktree_f_t *f;
-	void *w;
+rn_walktree_from(struct radix_node_head *h, void *a, void *m,
+    walktree_f_t *f, void *w)
 {
 	int error;
 	struct radix_node *base, *next;
 	u_char *xa = (u_char *)a;
 	u_char *xm = (u_char *)m;
-	register struct radix_node *rn, *last = 0 /* shut up gcc */;
+	struct radix_node *rn, *last = NULL; /* shut up gcc */
 	int stopping = 0;
 	int lastb;
 
@@ -1077,18 +1087,15 @@ rn_walktree_from(h, a, m, f, w)
 		}
 
 	}
-	return 0;
+	return (0);
 }
 
 static int
-rn_walktree(h, f, w)
-	struct radix_node_head *h;
-	walktree_f_t *f;
-	void *w;
+rn_walktree(struct radix_node_head *h, walktree_f_t *f, void *w)
 {
 	int error;
 	struct radix_node *base, *next;
-	register struct radix_node *rn = h->rnh_treetop;
+	struct radix_node *rn = h->rnh_treetop;
 	/*
 	 * This gets complicated because we may delete the node
 	 * while applying the function f to it, so we need to calculate
@@ -1130,13 +1137,11 @@ rn_walktree(h, f, w)
  * bits starting at 'off'.
  * Return 1 on success, 0 on error.
  */
-int
-rn_inithead(head, off)
-	void **head;
-	int off;
+static int
+rn_inithead_internal(void **head, int off)
 {
-	register struct radix_node_head *rnh;
-	register struct radix_node *t, *tt, *ttt;
+	struct radix_node_head *rnh;
+	struct radix_node *t, *tt, *ttt;
 	if (*head)
 		return (1);
 	R_Zalloc(rnh, struct radix_node_head *, sizeof (*rnh));
@@ -1165,8 +1170,8 @@ rn_inithead(head, off)
 	return (1);
 }
 
-int
-rn_detachhead(void **head)
+static void
+rn_detachhead_internal(void **head)
 {
 	struct radix_node_head *rnh;
 
@@ -1178,28 +1183,60 @@ rn_detachhead(void **head)
 	Free(rnh);
 
 	*head = NULL;
+}
+
+int
+rn_inithead(void **head, int off)
+{
+	struct radix_node_head *rnh;
+
+	if (*head != NULL)
+		return (1);
+
+	if (rn_inithead_internal(head, off) == 0)
+		return (0);
+
+	rnh = (struct radix_node_head *)(*head);
+
+	if (rn_inithead_internal((void **)&rnh->rnh_masks, 0) == 0) {
+		rn_detachhead_internal(head);
+		return (0);
+	}
+
+	return (1);
+}
+
+int
+rn_detachhead(void **head)
+{
+	struct radix_node_head *rnh;
+
+	KASSERT((head != NULL && *head != NULL),
+	    ("%s: head already freed", __func__));
+
+	rnh = *head;
+
+	rn_detachhead_internal((void **)&rnh->rnh_masks);
+	rn_detachhead_internal(head);
 	return (1);
 }
 
 void
 rn_init(int maxk)
 {
-	char *cp, *cplim;
-
-	max_keylen = maxk;
-	if (max_keylen == 0) {
+	if ((maxk <= 0) || (maxk > RADIX_MAX_KEY_LEN)) {
 		log(LOG_ERR,
-		    "rn_init: radix functions require max_keylen be set\n");
+		    "rn_init: max_keylen must be within 1..%d\n",
+		    RADIX_MAX_KEY_LEN);
 		return;
 	}
-	R_Malloc(rn_zeros, char *, 3 * max_keylen);
-	if (rn_zeros == NULL)
-		panic("rn_init");
-	bzero(rn_zeros, 3 * max_keylen);
-	rn_ones = cp = rn_zeros + max_keylen;
-	addmask_key = cplim = rn_ones + max_keylen;
-	while (cp < cplim)
-		*cp++ = -1;
-	if (rn_inithead((void **)(void *)&mask_rnhead, 0) == 0)
+
+	/*
+	 * XXX: Compat for old rn_addmask() users
+	 */
+	if (rn_inithead((void **)(void *)&mask_rnhead_compat, 0) == 0)
 		panic("rn_init 2");
+#ifdef _KERNEL
+	mtx_init(&mask_mtx, "radix_mask", NULL, MTX_DEF);
+#endif
 }
diff --git a/freebsd/sys/net/radix.h b/freebsd/sys/net/radix.h
index 5bacaa3..3554c77 100644
--- a/freebsd/sys/net/radix.h
+++ b/freebsd/sys/net/radix.h
@@ -119,9 +119,9 @@ struct radix_node_head {
 		(void *v, void *mask, struct radix_node_head *head);
 	struct	radix_node *(*rnh_delpkt)	/* remove based on packet hdr */
 		(void *v, void *mask, struct radix_node_head *head);
-	struct	radix_node *(*rnh_matchaddr)	/* locate based on sockaddr */
+	struct	radix_node *(*rnh_matchaddr)	/* longest match for sockaddr */
 		(void *v, struct radix_node_head *head);
-	struct	radix_node *(*rnh_lookup)	/* locate based on sockaddr */
+	struct	radix_node *(*rnh_lookup)	/*exact match for sockaddr*/
 		(void *v, void *mask, struct radix_node_head *head);
 	struct	radix_node *(*rnh_matchpkt)	/* locate based on packet hdr */
 		(void *v, struct radix_node_head *head);
@@ -136,6 +136,7 @@ struct radix_node_head {
 #ifdef _KERNEL
 	struct	rwlock rnh_lock;		/* locks entire radix tree */
 #endif
+	struct	radix_node_head *rnh_masks;	/* Storage for our masks */
 };
 
 #ifndef _KERNEL
@@ -167,6 +168,7 @@ int	 rn_detachhead(void **);
 int	 rn_refines(void *, void *);
 struct radix_node
 	 *rn_addmask(void *, int, int),
+	 *rn_addmask_r(void *, struct radix_node_head *, int, int),
 	 *rn_addroute (void *, void *, struct radix_node_head *,
 			struct radix_node [2]),
 	 *rn_delete(void *, void *, struct radix_node_head *),
diff --git a/freebsd/sys/net/radix_mpath.c b/freebsd/sys/net/radix_mpath.c
index 0f89bf5..1bce388 100644
--- a/freebsd/sys/net/radix_mpath.c
+++ b/freebsd/sys/net/radix_mpath.c
@@ -118,11 +118,16 @@ rt_mpath_matchgate(struct rtentry *rt, struct sockaddr *gate)
 		if (rt->rt_gateway->sa_family == AF_LINK) {
 			if (!memcmp(rt->rt_ifa->ifa_addr, gate, gate->sa_len))
 				break;
-		} else {
-			if (rt->rt_gateway->sa_len == gate->sa_len &&
-			    !memcmp(rt->rt_gateway, gate, gate->sa_len))
-				break;
 		}
+
+		/*
+		 * Check for other options:
+		 * 1) Routes with 'real' IPv4/IPv6 gateway
+		 * 2) Loopback host routes (another AF_LINK/sockadd_dl check)
+		 * */
+		if (rt->rt_gateway->sa_len == gate->sa_len &&
+		    !memcmp(rt->rt_gateway, gate, gate->sa_len))
+			break;
 	} while ((rn = rn_mpath_next(rn)) != NULL);
 
 	return (struct rtentry *)rn;
@@ -157,6 +162,7 @@ rt_mpath_deldup(struct rtentry *headrt, struct rtentry *rt)
 
 /*
  * check if we have the same key/mask/gateway on the table already.
+ * Assume @rt rt_key host bits are cleared according to @netmask
  */
 int
 rt_mpath_conflict(struct radix_node_head *rnh, struct rtentry *rt,
@@ -164,76 +170,13 @@ rt_mpath_conflict(struct radix_node_head *rnh, struct rtentry *rt,
 {
 	struct radix_node *rn, *rn1;
 	struct rtentry *rt1;
-	char *p, *q, *eq;
-	int same, l, skip;
 
 	rn = (struct radix_node *)rt;
 	rn1 = rnh->rnh_lookup(rt_key(rt), netmask, rnh);
 	if (!rn1 || rn1->rn_flags & RNF_ROOT)
-		return 0;
-
-	/*
-	 * unlike other functions we have in this file, we have to check
-	 * all key/mask/gateway as rnh_lookup can match less specific entry.
-	 */
-	rt1 = (struct rtentry *)rn1;
-
-	/* compare key. */
-	if (rt_key(rt1)->sa_len != rt_key(rt)->sa_len ||
-	    bcmp(rt_key(rt1), rt_key(rt), rt_key(rt1)->sa_len))
-		goto different;
-
-	/* key was the same.  compare netmask.  hairy... */
-	if (rt_mask(rt1) && netmask) {
-		skip = rnh->rnh_treetop->rn_offset;
-		if (rt_mask(rt1)->sa_len > netmask->sa_len) {
-			/*
-			 * as rt_mask(rt1) is made optimal by radix.c,
-			 * there must be some 1-bits on rt_mask(rt1)
-			 * after netmask->sa_len.  therefore, in
-			 * this case, the entries are different.
-			 */
-			if (rt_mask(rt1)->sa_len > skip)
-				goto different;
-			else {
-				/* no bits to compare, i.e. same*/
-				goto maskmatched;
-			}
-		}
-
-		l = rt_mask(rt1)->sa_len;
-		if (skip > l) {
-			/* no bits to compare, i.e. same */
-			goto maskmatched;
-		}
-		p = (char *)rt_mask(rt1);
-		q = (char *)netmask;
-		if (bcmp(p + skip, q + skip, l - skip))
-			goto different;
-		/*
-		 * need to go through all the bit, as netmask is not
-		 * optimal and can contain trailing 0s
-		 */
-		eq = (char *)netmask + netmask->sa_len;
-		q += l;
-		same = 1;
-		while (eq > q)
-			if (*q++) {
-				same = 0;
-				break;
-			}
-		if (!same)
-			goto different;
-	} else if (!rt_mask(rt1) && !netmask)
-		; /* no mask to compare, i.e. same */
-	else {
-		/* one has mask and the other does not, different */
-		goto different;
-	}
-
-maskmatched:
+		return (0);
 
-	/* key/mask were the same.  compare gateway for all multipaths */
+	/* key/mask are the same. compare gateway for all multipaths */
 	do {
 		rt1 = (struct rtentry *)rn1;
 
@@ -254,11 +197,10 @@ maskmatched:
 		}
 
 		/* all key/mask/gateway are the same.  conflicting entry. */
-		return EEXIST;
+		return (EEXIST);
 	} while ((rn1 = rn_mpath_next(rn1)) != NULL);
 
-different:
-	return 0;
+	return (0);
 }
 
 void
diff --git a/freebsd/sys/net/route.c b/freebsd/sys/net/route.c
index fdd8a12..b444b74 100644
--- a/freebsd/sys/net/route.c
+++ b/freebsd/sys/net/route.c
@@ -39,6 +39,7 @@
 #include <rtems/bsd/local/opt_inet.h>
 #include <rtems/bsd/local/opt_inet6.h>
 #include <rtems/bsd/local/opt_route.h>
+#include <rtems/bsd/local/opt_sctp.h>
 #include <rtems/bsd/local/opt_mrouting.h>
 #include <rtems/bsd/local/opt_mpath.h>
 
@@ -92,6 +93,14 @@
 #define	RT_NUMFIBS	1
 #endif
 
+#if defined(INET) || defined(INET6)
+#ifdef SCTP
+extern void sctp_addr_change(struct ifaddr *ifa, int cmd);
+#endif /* SCTP */
+#endif
+
+
+/* This is read-only.. */
 u_int rt_numfibs = RT_NUMFIBS;
 SYSCTL_UINT(_net, OID_AUTO, fibs, CTLFLAG_RD, &rt_numfibs, 0, "");
 /*
@@ -131,7 +140,8 @@ VNET_DEFINE(int, rttrash);		/* routes not in table but not freed */
 
 
 /* compare two sockaddr structures */
-#define	sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
+#define	sa_equal(a1, a2) (((a1)->sa_len == (a2)->sa_len) && \
+    (bcmp((a1), (a2), (a1)->sa_len) == 0))
 
 /*
  * Convert a 'struct radix_node *' to a 'struct rtentry *'.
@@ -974,6 +984,57 @@ bad:
 	return (error);
 }
 
+#if 0
+int p_sockaddr(char *buf, int buflen, struct sockaddr *s);
+int rt_print(char *buf, int buflen, struct rtentry *rt);
+
+int
+p_sockaddr(char *buf, int buflen, struct sockaddr *s)
+{
+	void *paddr = NULL;
+
+	switch (s->sa_family) {
+	case AF_INET:
+		paddr = &((struct sockaddr_in *)s)->sin_addr;
+		break;
+	case AF_INET6:
+		paddr = &((struct sockaddr_in6 *)s)->sin6_addr;
+		break;
+	}
+
+	if (paddr == NULL)
+		return (0);
+
+	if (inet_ntop(s->sa_family, paddr, buf, buflen) == NULL)
+		return (0);
+	
+	return (strlen(buf));
+}
+
+int
+rt_print(char *buf, int buflen, struct rtentry *rt)
+{
+	struct sockaddr *addr, *mask;
+	int i = 0;
+
+	addr = rt_key(rt);
+	mask = rt_mask(rt);
+
+	i = p_sockaddr(buf, buflen, addr);
+	if (!(rt->rt_flags & RTF_HOST)) {
+		buf[i++] = '/';
+		i += p_sockaddr(buf + i, buflen - i, mask);
+	}
+
+	if (rt->rt_flags & RTF_GATEWAY) {
+		buf[i++] = '>';
+		i += p_sockaddr(buf + i, buflen - i, rt->rt_gateway);
+	}
+
+	return (i);
+}
+#endif
+
 #ifdef RADIX_MPATH
 static int
 rn_mpath_update(int req, struct rt_addrinfo *info,
@@ -987,10 +1048,11 @@ rn_mpath_update(int req, struct rt_addrinfo *info,
 	register struct radix_node *rn;
 	int error = 0;
 
-	rn = rnh->rnh_matchaddr(dst, rnh);
+	rn = rnh->rnh_lookup(dst, netmask, rnh);
 	if (rn == NULL)
 		return (ESRCH);
 	rto = rt = RNTORT(rn);
+
 	rt = rt_mpath_matchgate(rt, gateway);
 	if (rt == NULL)
 		return (ESRCH);
@@ -1495,7 +1557,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
 		fibnum = RT_DEFAULT_FIB;
 		break;
 	}
-	if (fibnum == -1) {
+	if (fibnum == RT_ALL_FIBS) {
 		if (rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) {
 #ifndef __rtems__
 			startfib = endfib = curthread->td_proc->p_fibnum;
@@ -1548,10 +1610,10 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
 				/* this table doesn't exist but others might */
 				continue;
 			RADIX_NODE_HEAD_RLOCK(rnh);
+			rn = rnh->rnh_lookup(dst, netmask, rnh);
 #ifdef RADIX_MPATH
 			if (rn_mpath_capable(rnh)) {
 
-				rn = rnh->rnh_matchaddr(dst, rnh);
 				if (rn == NULL) 
 					error = ESRCH;
 				else {
@@ -1565,17 +1627,14 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
 					 */
 					rt = rt_mpath_matchgate(rt,
 					    ifa->ifa_addr);
-					if (!rt) 
+					if (rt == NULL) 
 						error = ESRCH;
 				}
 			}
-			else
 #endif
-			rn = rnh->rnh_lookup(dst, netmask, rnh);
 			error = (rn == NULL ||
 			    (rn->rn_flags & RNF_ROOT) ||
-			    RNTORT(rn)->rt_ifa != ifa ||
-			    !sa_equal((struct sockaddr *)rn->rn_key, dst));
+			    RNTORT(rn)->rt_ifa != ifa);
 			RADIX_NODE_HEAD_RUNLOCK(rnh);
 			if (error) {
 				/* this is only an error if bad on ALL tables */
@@ -1706,7 +1765,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
 int
 rtinit_fib(struct ifaddr *ifa, int cmd, int flags)
 {
-	return (rtinit1(ifa, cmd, flags, -1));
+	return (rtinit1(ifa, cmd, flags, RT_ALL_FIBS));
 }
 #endif
 
@@ -1730,8 +1789,94 @@ rtinit(struct ifaddr *ifa, int cmd, int flags)
 	case AF_INET6:
 	case AF_INET:
 		/* We do support multiple FIBs. */
-		fib = -1;
+		fib = RT_ALL_FIBS;
 		break;
 	}
 	return (rtinit1(ifa, cmd, flags, fib));
 }
+
+/*
+ * Announce interface address arrival/withdraw
+ * Returns 0 on success.
+ */
+int
+rt_addrmsg(int cmd, struct ifaddr *ifa, int fibnum)
+{
+
+	KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
+	    ("unexpected cmd %d", cmd));
+	
+	KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
+	    ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
+
+#if defined(INET) || defined(INET6)
+#ifdef SCTP
+	/*
+	 * notify the SCTP stack
+	 * this will only get called when an address is added/deleted
+	 * XXX pass the ifaddr struct instead if ifa->ifa_addr...
+	 */
+	sctp_addr_change(ifa, cmd);
+#endif /* SCTP */
+#endif
+	return (rtsock_addrmsg(cmd, ifa, fibnum));
+}
+
+/*
+ * Announce route addition/removal.
+ * Users of this function MUST validate input data BEFORE calling.
+ * However we have to be able to handle invalid data:
+ * if some userland app sends us "invalid" route message (invalid mask,
+ * no dst, wrong address families, etc...) we need to pass it back
+ * to app (and any other rtsock consumers) with rtm_errno field set to
+ * non-zero value.
+ * Returns 0 on success.
+ */
+int
+rt_routemsg(int cmd, struct ifnet *ifp, int error, struct rtentry *rt,
+    int fibnum)
+{
+
+	KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
+	    ("unexpected cmd %d", cmd));
+	
+	KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
+	    ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
+
+	KASSERT(rt_key(rt) != NULL, (":%s: rt_key must be supplied", __func__));
+
+	return (rtsock_routemsg(cmd, ifp, error, rt, fibnum));
+}
+
+void
+rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
+{
+
+	rt_newaddrmsg_fib(cmd, ifa, error, rt, RT_ALL_FIBS);
+}
+
+/*
+ * This is called to generate messages from the routing socket
+ * indicating a network interface has had addresses associated with it.
+ */
+void
+rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt,
+    int fibnum)
+{
+
+	KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
+		("unexpected cmd %u", cmd));
+	KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
+	    ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
+
+	if (cmd == RTM_ADD) {
+		rt_addrmsg(cmd, ifa, fibnum);
+		if (rt != NULL)
+			rt_routemsg(cmd, ifa->ifa_ifp, error, rt, fibnum);
+	} else {
+		if (rt != NULL)
+			rt_routemsg(cmd, ifa->ifa_ifp, error, rt, fibnum);
+		rt_addrmsg(cmd, ifa, fibnum);
+	}
+}
+
diff --git a/freebsd/sys/net/route.h b/freebsd/sys/net/route.h
index 997f3cd..0baa9a4 100644
--- a/freebsd/sys/net/route.h
+++ b/freebsd/sys/net/route.h
@@ -92,7 +92,9 @@ struct rt_metrics {
 #define	RTTTOPRHZ(r)	((r) / (RTM_RTTUNIT / PR_SLOWHZ))
 
 #define	RT_DEFAULT_FIB	0	/* Explicitly mark fib=0 restricted cases */
-extern u_int rt_numfibs;	/* number fo usable routing tables */
+#define	RT_ALL_FIBS	-1	/* Announce event for every fib */
+extern u_int rt_numfibs;	/* number of usable routing tables */
+extern u_int rt_add_addr_allfibs;	/* Announce interfaces to all fibs */
 /*
  * XXX kernel function pointer `rt_output' is visible to applications.
  */
@@ -365,10 +367,15 @@ void	 rt_missmsg(int, struct rt_addrinfo *, int, int);
 void	 rt_missmsg_fib(int, struct rt_addrinfo *, int, int, int);
 void	 rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *);
 void	 rt_newaddrmsg_fib(int, struct ifaddr *, int, struct rtentry *, int);
+int	 rt_addrmsg(int, struct ifaddr *, int);
+int	 rt_routemsg(int, struct ifnet *ifp, int, struct rtentry *, int);
 void	 rt_newmaddrmsg(int, struct ifmultiaddr *);
 int	 rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *);
 void 	 rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *);
 
+int	rtsock_addrmsg(int, struct ifaddr *, int);
+int	rtsock_routemsg(int, struct ifnet *ifp, int, struct rtentry *, int);
+
 /*
  * Note the following locking behavior:
  *
diff --git a/freebsd/sys/net/rtsock.c b/freebsd/sys/net/rtsock.c
index 1eebe09..e768e17 100644
--- a/freebsd/sys/net/rtsock.c
+++ b/freebsd/sys/net/rtsock.c
@@ -32,7 +32,6 @@
  * $FreeBSD$
  */
 #include <rtems/bsd/local/opt_compat.h>
-#include <rtems/bsd/local/opt_sctp.h>
 #include <rtems/bsd/local/opt_mpath.h>
 #include <rtems/bsd/local/opt_inet.h>
 #include <rtems/bsd/local/opt_inet6.h>
@@ -69,12 +68,6 @@
 #include <netinet6/scope6_var.h>
 #endif
 
-#if defined(INET) || defined(INET6)
-#ifdef SCTP
-extern void sctp_addr_change(struct ifaddr *ifa, int cmd);
-#endif /* SCTP */
-#endif
-
 #ifdef COMPAT_FREEBSD32
 #include <sys/mount.h>
 #include <compat/freebsd32/freebsd32.h>
@@ -156,7 +149,6 @@ static struct	sockaddr sa_zero   = { sizeof(sa_zero), AF_INET, };
  * notification to a socket bound to a particular FIB.
  */
 #define	RTS_FILTER_FIB	M_PROTO8
-#define	RTS_ALLFIBS	-1
 
 static struct {
 	int	ip_count;	/* attached w/ AF_INET */
@@ -716,10 +708,24 @@ route_output(struct mbuf *m, struct socket *so)
 		    info.rti_info[RTAX_DST]->sa_family);
 		if (rnh == NULL)
 			senderr(EAFNOSUPPORT);
+
 		RADIX_NODE_HEAD_RLOCK(rnh);
-		rt = (struct rtentry *) rnh->rnh_lookup(info.rti_info[RTAX_DST],
-			info.rti_info[RTAX_NETMASK], rnh);
-		if (rt == NULL) {	/* XXX looks bogus */
+
+		if (info.rti_info[RTAX_NETMASK] == NULL &&
+		    rtm->rtm_type == RTM_GET) {
+			/*
+			 * Provide logest prefix match for
+			 * address lookup (no mask).
+			 * 'route -n get addr'
+			 */
+			rt = (struct rtentry *) rnh->rnh_matchaddr(
+			    info.rti_info[RTAX_DST], rnh);
+		} else
+			rt = (struct rtentry *) rnh->rnh_lookup(
+			    info.rti_info[RTAX_DST],
+			    info.rti_info[RTAX_NETMASK], rnh);
+
+		if (rt == NULL) {
 			RADIX_NODE_HEAD_RUNLOCK(rnh);
 			senderr(ESRCH);
 		}
@@ -776,25 +782,6 @@ route_output(struct mbuf *m, struct socket *so)
 		RT_ADDREF(rt);
 		RADIX_NODE_HEAD_RUNLOCK(rnh);
 
-		/* 
-		 * Fix for PR: 82974
-		 *
-		 * RTM_CHANGE/LOCK need a perfect match, rn_lookup()
-		 * returns a perfect match in case a netmask is
-		 * specified.  For host routes only a longest prefix
-		 * match is returned so it is necessary to compare the
-		 * existence of the netmask.  If both have a netmask
-		 * rnh_lookup() did a perfect match and if none of them
-		 * have a netmask both are host routes which is also a
-		 * perfect match.
-		 */
-
-		if (rtm->rtm_type != RTM_GET && 
-		    (!rt_mask(rt) != !info.rti_info[RTAX_NETMASK])) {
-			RT_UNLOCK(rt);
-			senderr(ESRCH);
-		}
-
 		switch(rtm->rtm_type) {
 
 		case RTM_GET:
@@ -1235,7 +1222,7 @@ rt_missmsg_fib(int type, struct rt_addrinfo *rtinfo, int flags, int error,
 	if (m == NULL)
 		return;
 
-	if (fibnum != RTS_ALLFIBS) {
+	if (fibnum != RT_ALL_FIBS) {
 		KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: fibnum out "
 		    "of range 0 <= %d < %d", __func__, fibnum, rt_numfibs));
 		M_SETFIB(m, fibnum);
@@ -1253,7 +1240,7 @@ void
 rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
 {
 
-	rt_missmsg_fib(type, rtinfo, flags, error, RTS_ALLFIBS);
+	rt_missmsg_fib(type, rtinfo, flags, error, RT_ALL_FIBS);
 }
 
 /*
@@ -1282,89 +1269,92 @@ rt_ifmsg(struct ifnet *ifp)
 }
 
 /*
- * This is called to generate messages from the routing socket
- * indicating a network interface has had addresses associated with it.
- * if we ever reverse the logic and replace messages TO the routing
- * socket indicate a request to configure interfaces, then it will
- * be unnecessary as the routing socket will automatically generate
- * copies of it.
+ * Announce interface address arrival/withdraw.
+ * Please do not call directly, use rt_addrmsg().
+ * Assume input data to be valid.
+ * Returns 0 on success.
  */
-void
-rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt,
-    int fibnum)
+int
+rtsock_addrmsg(int cmd, struct ifaddr *ifa, int fibnum)
 {
 	struct rt_addrinfo info;
-	struct sockaddr *sa = NULL;
-	int pass;
-	struct mbuf *m = NULL;
+	struct sockaddr *sa;
+	int ncmd;
+	struct mbuf *m;
+	struct ifa_msghdr *ifam;
 	struct ifnet *ifp = ifa->ifa_ifp;
 
-	KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
-		("unexpected cmd %u", cmd));
-#if defined(INET) || defined(INET6)
-#ifdef SCTP
-	/*
-	 * notify the SCTP stack
-	 * this will only get called when an address is added/deleted
-	 * XXX pass the ifaddr struct instead if ifa->ifa_addr...
-	 */
-	sctp_addr_change(ifa, cmd);
-#endif /* SCTP */
-#endif
 	if (route_cb.any_count == 0)
-		return;
-	for (pass = 1; pass < 3; pass++) {
-		bzero((caddr_t)&info, sizeof(info));
-		if ((cmd == RTM_ADD && pass == 1) ||
-		    (cmd == RTM_DELETE && pass == 2)) {
-			struct ifa_msghdr *ifam;
-			int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR;
-
-			info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr;
-			info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr;
-			info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
-			info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
-			if ((m = rt_msg1(ncmd, &info)) == NULL)
-				continue;
-			ifam = mtod(m, struct ifa_msghdr *);
-			ifam->ifam_index = ifp->if_index;
-			ifam->ifam_metric = ifa->ifa_metric;
-			ifam->ifam_flags = ifa->ifa_flags;
-			ifam->ifam_addrs = info.rti_addrs;
-		}
-		if ((cmd == RTM_ADD && pass == 2) ||
-		    (cmd == RTM_DELETE && pass == 1)) {
-			struct rt_msghdr *rtm;
+		return (0);
 
-			if (rt == NULL)
-				continue;
-			info.rti_info[RTAX_NETMASK] = rt_mask(rt);
-			info.rti_info[RTAX_DST] = sa = rt_key(rt);
-			info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
-			if ((m = rt_msg1(cmd, &info)) == NULL)
-				continue;
-			rtm = mtod(m, struct rt_msghdr *);
-			rtm->rtm_index = ifp->if_index;
-			rtm->rtm_flags |= rt->rt_flags;
-			rtm->rtm_errno = error;
-			rtm->rtm_addrs = info.rti_addrs;
-		}
-		if (fibnum != RTS_ALLFIBS) {
-			KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: "
-			    "fibnum out of range 0 <= %d < %d", __func__,
-			     fibnum, rt_numfibs));
-			M_SETFIB(m, fibnum);
-			m->m_flags |= RTS_FILTER_FIB;
-		}
-		rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC);
+	ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR;
+
+	bzero((caddr_t)&info, sizeof(info));
+	info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr;
+	info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr;
+	info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
+	info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
+	if ((m = rt_msg1(ncmd, &info)) == NULL)
+		return (ENOBUFS);
+	ifam = mtod(m, struct ifa_msghdr *);
+	ifam->ifam_index = ifp->if_index;
+	ifam->ifam_metric = ifa->ifa_metric;
+	ifam->ifam_flags = ifa->ifa_flags;
+	ifam->ifam_addrs = info.rti_addrs;
+
+	if (fibnum != RT_ALL_FIBS) {
+		M_SETFIB(m, fibnum);
+		m->m_flags |= RTS_FILTER_FIB;
 	}
+
+	rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC);
+
+	return (0);
 }
 
-void
-rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
+/*
+ * Announce route addition/removal.
+ * Please do not call directly, use rt_routemsg().
+ * Note that @rt data MAY be inconsistent/invalid:
+ * if some userland app sends us "invalid" route message (invalid mask,
+ * no dst, wrong address families, etc...) we need to pass it back
+ * to app (and any other rtsock consumers) with rtm_errno field set to
+ * non-zero value.
+ *
+ * Returns 0 on success.
+ */
+int
+rtsock_routemsg(int cmd, struct ifnet *ifp, int error, struct rtentry *rt,
+    int fibnum)
 {
+	struct rt_addrinfo info;
+	struct sockaddr *sa;
+	struct mbuf *m;
+	struct rt_msghdr *rtm;
+
+	if (route_cb.any_count == 0)
+		return (0);
 
-	rt_newaddrmsg_fib(cmd, ifa, error, rt, RTS_ALLFIBS);
+	bzero((caddr_t)&info, sizeof(info));
+	info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+	info.rti_info[RTAX_DST] = sa = rt_key(rt);
+	info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+	if ((m = rt_msg1(cmd, &info)) == NULL)
+		return (ENOBUFS);
+	rtm = mtod(m, struct rt_msghdr *);
+	rtm->rtm_index = ifp->if_index;
+	rtm->rtm_flags |= rt->rt_flags;
+	rtm->rtm_errno = error;
+	rtm->rtm_addrs = info.rti_addrs;
+
+	if (fibnum != RT_ALL_FIBS) {
+		M_SETFIB(m, fibnum);
+		m->m_flags |= RTS_FILTER_FIB;
+	}
+
+	rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC);
+
+	return (0);
 }
 
 /*
@@ -1839,7 +1829,7 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
 			fib = BSD_DEFAULT_FIB;
 #endif /* __rtems__ */
 		else if (namelen == 4)
-			fib = (name[3] == -1) ?
+			fib = (name[3] == RT_ALL_FIBS) ?
 #ifndef __rtems__
 			    req->td->td_proc->p_fibnum : name[3];
 #else /* __rtems__ */
diff --git a/freebsd/sys/net80211/ieee80211.h b/freebsd/sys/net80211/ieee80211.h
index 9c12ef0..43d87b3 100644
--- a/freebsd/sys/net80211/ieee80211.h
+++ b/freebsd/sys/net80211/ieee80211.h
@@ -701,6 +701,7 @@ enum {
 	IEEE80211_ELEMID_IBSSDFS	= 41,
 	IEEE80211_ELEMID_ERP		= 42,
 	IEEE80211_ELEMID_HTCAP		= 45,
+	IEEE80211_ELEMID_QOS		= 46,
 	IEEE80211_ELEMID_RSN		= 48,
 	IEEE80211_ELEMID_XRATES		= 50,
 	IEEE80211_ELEMID_HTINFO		= 61,
diff --git a/freebsd/sys/net80211/ieee80211_proto.h b/freebsd/sys/net80211/ieee80211_proto.h
index 7e88216..b2ed3e8 100644
--- a/freebsd/sys/net80211/ieee80211_proto.h
+++ b/freebsd/sys/net80211/ieee80211_proto.h
@@ -134,6 +134,9 @@ struct mbuf *ieee80211_alloc_cts(struct ieee80211com *,
 
 uint8_t *ieee80211_add_rates(uint8_t *, const struct ieee80211_rateset *);
 uint8_t *ieee80211_add_xrates(uint8_t *, const struct ieee80211_rateset *);
+uint8_t *ieee80211_add_wpa(uint8_t *, const struct ieee80211vap *);
+uint8_t *ieee80211_add_rsn(uint8_t *, const struct ieee80211vap *);
+uint8_t *ieee80211_add_qos(uint8_t *, const struct ieee80211_node *);
 uint16_t ieee80211_getcapinfo(struct ieee80211vap *,
 		struct ieee80211_channel *);
 
diff --git a/freebsd/sys/netinet/if_ether.c b/freebsd/sys/netinet/if_ether.c
index 98ed0b3..e4f76fe 100644
--- a/freebsd/sys/netinet/if_ether.c
+++ b/freebsd/sys/netinet/if_ether.c
@@ -156,10 +156,10 @@ arp_ifscrub(struct ifnet *ifp, uint32_t addr)
 	addr4.sin_len    = sizeof(addr4);
 	addr4.sin_family = AF_INET;
 	addr4.sin_addr.s_addr = addr;
-	IF_AFDATA_LOCK(ifp);
+	IF_AFDATA_RLOCK(ifp);
 	lla_lookup(LLTABLE(ifp), (LLE_DELETE | LLE_IFADDR),
 	    (struct sockaddr *)&addr4);
-	IF_AFDATA_UNLOCK(ifp);
+	IF_AFDATA_RUNLOCK(ifp);
 }
 #endif
 
@@ -792,9 +792,9 @@ reply:
 		struct llentry *lle = NULL;
 
 		sin.sin_addr = itaddr;
-		IF_AFDATA_LOCK(ifp);
+		IF_AFDATA_RLOCK(ifp);
 		lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
-		IF_AFDATA_UNLOCK(ifp);
+		IF_AFDATA_RUNLOCK(ifp);
 
 		if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
 			(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
diff --git a/freebsd/sys/netinet/in.c b/freebsd/sys/netinet/in.c
index 0c3f72b..bc7323e 100644
--- a/freebsd/sys/netinet/in.c
+++ b/freebsd/sys/netinet/in.c
@@ -963,45 +963,6 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
 	    ? RTF_HOST : 0)
 
 /*
- * Generate a routing message when inserting or deleting
- * an interface address alias.
- */
-static void in_addralias_rtmsg(int cmd, struct in_addr *prefix,
-    struct in_ifaddr *target)
-{
-	struct route pfx_ro;
-	struct sockaddr_in *pfx_addr;
-	struct rtentry msg_rt;
-
-	/* QL: XXX
-	 * This is a bit questionable because there is no
-	 * additional route entry added/deleted for an address
-	 * alias. Therefore this route report is inaccurate.
-	 */
-	bzero(&pfx_ro, sizeof(pfx_ro));
-	pfx_addr = (struct sockaddr_in *)(&pfx_ro.ro_dst);
-	pfx_addr->sin_len = sizeof(*pfx_addr);
-	pfx_addr->sin_family = AF_INET;
-	pfx_addr->sin_addr = *prefix;
-	rtalloc_ign_fib(&pfx_ro, 0, 0);
-	if (pfx_ro.ro_rt != NULL) {
-		msg_rt = *pfx_ro.ro_rt;
-
-		/* QL: XXX
-		 * Point the gateway to the new interface
-		 * address as if a new prefix route entry has
-		 * been added through the new address alias.
-		 * All other parts of the rtentry is accurate,
-		 * e.g., rt_key, rt_mask, rt_ifp etc.
-		 */
-		msg_rt.rt_gateway = (struct sockaddr *)&target->ia_addr;
-		rt_newaddrmsg(cmd, (struct ifaddr *)target, 0, &msg_rt);
-		RTFREE(pfx_ro.ro_rt);
-	}
-	return;
-}
-
-/*
  * Check if we have a route for the given prefix already or add one accordingly.
  */
 static int
@@ -1009,7 +970,7 @@ in_addprefix(struct in_ifaddr *target, int flags)
 {
 	struct in_ifaddr *ia;
 	struct in_addr prefix, mask, p, m;
-	int error;
+	int error, fibnum;
 
 	if ((flags & RTF_HOST) != 0) {
 		prefix = target->ia_dstaddr.sin_addr;
@@ -1020,6 +981,8 @@ in_addprefix(struct in_ifaddr *target, int flags)
 		prefix.s_addr &= mask.s_addr;
 	}
 
+	fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib;
+
 	IN_IFADDR_RLOCK();
 	TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
 		if (rtinitflags(ia)) {
@@ -1056,7 +1019,7 @@ in_addprefix(struct in_ifaddr *target, int flags)
 				IN_IFADDR_RUNLOCK();
 				return (EEXIST);
 			} else {
-				in_addralias_rtmsg(RTM_ADD, &prefix, target);
+				rt_addrmsg(RTM_ADD, &target->ia_ifa, fibnum);
 				IN_IFADDR_RUNLOCK();
 				return (0);
 			}
@@ -1085,9 +1048,11 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags)
 {
 	struct in_ifaddr *ia;
 	struct in_addr prefix, mask, p;
-	int error = 0;
+	int error = 0, fibnum;
 	struct sockaddr_in prefix0, mask0;
 
+	fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib;
+
 	/*
 	 * Remove the loopback route to the interface address.
 	 * The "useloopback" setting is not consulted because if the
@@ -1139,7 +1104,7 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags)
 	}
 
 	if ((target->ia_flags & IFA_ROUTE) == 0) {
-		in_addralias_rtmsg(RTM_DELETE, &prefix, target);
+		rt_addrmsg(RTM_DELETE, &target->ia_ifa, fibnum);
 		return (0);
 	}
 
@@ -1501,6 +1466,7 @@ in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3add
 #endif
 		if (!(flags & LLE_CREATE))
 			return (NULL);
+		IF_AFDATA_WLOCK_ASSERT(ifp);
 		/*
 		 * A route that covers the given address must have
 		 * been installed 1st because we are doing a resolution,
diff --git a/freebsd/sys/netinet/in_mcast.c b/freebsd/sys/netinet/in_mcast.c
index 6d748f1..4112046 100644
--- a/freebsd/sys/netinet/in_mcast.c
+++ b/freebsd/sys/netinet/in_mcast.c
@@ -140,7 +140,9 @@ static int	in_getmulti(struct ifnet *, const struct in_addr *,
 		    struct in_multi **);
 static int	inm_get_source(struct in_multi *inm, const in_addr_t haddr,
 		    const int noalloc, struct ip_msource **pims);
+#ifdef KTR
 static int	inm_is_ifp_detached(const struct in_multi *);
+#endif
 static int	inm_merge(struct in_multi *, /*const*/ struct in_mfilter *);
 static void	inm_purge(struct in_multi *);
 static void	inm_reap(struct in_multi *);
@@ -181,6 +183,7 @@ static SYSCTL_NODE(_net_inet_ip_mcast, OID_AUTO, filters,
     CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_ip_mcast_filters,
     "Per-interface stack-wide source filters");
 
+#ifdef KTR
 /*
  * Inline function which wraps assertions for a valid ifp.
  * The ifnet layer will set the ifma's ifp pointer to NULL if the ifp
@@ -203,6 +206,7 @@ inm_is_ifp_detached(const struct in_multi *inm)
 
 	return (ifp == NULL);
 }
+#endif
 
 /*
  * Initialize an in_mfilter structure to a known state at t0, t1
@@ -1444,7 +1448,7 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt)
 	error = inm_merge(inm, imf);
 	if (error) {
 		CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__);
-		goto out_imf_rollback;
+		goto out_in_multi_locked;
 	}
 
 	CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__);
@@ -1452,6 +1456,8 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt)
 	if (error)
 		CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__);
 
+out_in_multi_locked:
+
 	IN_MULTI_UNLOCK();
 
 out_imf_rollback:
@@ -2092,8 +2098,12 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
 	if (is_new) {
 		error = in_joingroup_locked(ifp, &gsa->sin.sin_addr, imf,
 		    &inm);
-		if (error)
+		if (error) {
+                        CTR1(KTR_IGMPV3, "%s: in_joingroup_locked failed", 
+                            __func__);
+                        IN_MULTI_UNLOCK();
 			goto out_imo_free;
+                }
 		imo->imo_membership[idx] = inm;
 	} else {
 		CTR1(KTR_IGMPV3, "%s: merge inm state", __func__);
@@ -2101,20 +2111,21 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
 		if (error) {
 			CTR1(KTR_IGMPV3, "%s: failed to merge inm state",
 			    __func__);
-			goto out_imf_rollback;
+			goto out_in_multi_locked;
 		}
 		CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__);
 		error = igmp_change_state(inm);
 		if (error) {
 			CTR1(KTR_IGMPV3, "%s: failed igmp downcall",
 			    __func__);
-			goto out_imf_rollback;
+			goto out_in_multi_locked;
 		}
 	}
 
+out_in_multi_locked:
+
 	IN_MULTI_UNLOCK();
 
-out_imf_rollback:
 	INP_WLOCK_ASSERT(inp);
 	if (error) {
 		imf_rollback(imf);
@@ -2318,7 +2329,7 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
 		if (error) {
 			CTR1(KTR_IGMPV3, "%s: failed to merge inm state",
 			    __func__);
-			goto out_imf_rollback;
+			goto out_in_multi_locked;
 		}
 
 		CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__);
@@ -2329,9 +2340,10 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
 		}
 	}
 
+out_in_multi_locked:
+
 	IN_MULTI_UNLOCK();
 
-out_imf_rollback:
 	if (error)
 		imf_rollback(imf);
 	else
@@ -2565,7 +2577,7 @@ inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt)
 	error = inm_merge(inm, imf);
 	if (error) {
 		CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__);
-		goto out_imf_rollback;
+		goto out_in_multi_locked;
 	}
 
 	CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__);
@@ -2573,6 +2585,8 @@ inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt)
 	if (error)
 		CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__);
 
+out_in_multi_locked:
+
 	IN_MULTI_UNLOCK();
 
 out_imf_rollback:
diff --git a/freebsd/sys/netinet/in_pcb.c b/freebsd/sys/netinet/in_pcb.c
index 5100ac9..b93abad 100644
--- a/freebsd/sys/netinet/in_pcb.c
+++ b/freebsd/sys/netinet/in_pcb.c
@@ -559,7 +559,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
 			 * and a multicast address is bound on both
 			 * new and duplicated sockets.
 			 */
-			if (so->so_options & SO_REUSEADDR)
+			if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) != 0)
 				reuseport = SO_REUSEADDR|SO_REUSEPORT;
 		} else if (sin->sin_addr.s_addr != INADDR_ANY) {
 			sin->sin_port = 0;		/* yech... */
diff --git a/freebsd/sys/netinet/ip_icmp.c b/freebsd/sys/netinet/ip_icmp.c
index b003d03..b6876f7 100644
--- a/freebsd/sys/netinet/ip_icmp.c
+++ b/freebsd/sys/netinet/ip_icmp.c
@@ -345,6 +345,7 @@ stdreply:	icmpelen = max(8, min(V_icmp_quotelen, oip->ip_len - oiphlen));
 	nip->ip_hl = 5;
 	nip->ip_p = IPPROTO_ICMP;
 	nip->ip_tos = 0;
+	nip->ip_off = 0;
 	icmp_reflect(m);
 
 freeit:
diff --git a/freebsd/sys/netinet/ip_input.c b/freebsd/sys/netinet/ip_input.c
index 2dbb2a7..2247c1a 100644
--- a/freebsd/sys/netinet/ip_input.c
+++ b/freebsd/sys/netinet/ip_input.c
@@ -1110,8 +1110,9 @@ found:
 	 * (and not in for{} loop), though it implies we are not going to
 	 * reassemble more than 64k fragments.
 	 */
-	m->m_pkthdr.csum_data =
-	    (m->m_pkthdr.csum_data & 0xffff) + (m->m_pkthdr.csum_data >> 16);
+	while (m->m_pkthdr.csum_data & 0xffff0000)
+		m->m_pkthdr.csum_data = (m->m_pkthdr.csum_data & 0xffff) +
+		    (m->m_pkthdr.csum_data >> 16);
 #ifdef MAC
 	mac_ipq_reassemble(fp, m);
 	mac_ipq_destroy(fp);
diff --git a/freebsd/sys/netinet/ip_mroute.c b/freebsd/sys/netinet/ip_mroute.c
index 6fc5cc6..20daee5 100644
--- a/freebsd/sys/netinet/ip_mroute.c
+++ b/freebsd/sys/netinet/ip_mroute.c
@@ -610,7 +610,7 @@ static void
 if_detached_event(void *arg __unused, struct ifnet *ifp)
 {
     vifi_t vifi;
-    int i;
+    u_long i;
 
     MROUTER_LOCK();
 
@@ -705,10 +705,9 @@ ip_mrouter_init(struct socket *so, int version)
 static int
 X_ip_mrouter_done(void)
 {
-    vifi_t vifi;
-    int i;
     struct ifnet *ifp;
-    struct ifreq ifr;
+    u_long i;
+    vifi_t vifi;
 
     MROUTER_LOCK();
 
@@ -733,11 +732,6 @@ X_ip_mrouter_done(void)
     for (vifi = 0; vifi < V_numvifs; vifi++) {
 	if (!in_nullhost(V_viftable[vifi].v_lcl_addr) &&
 		!(V_viftable[vifi].v_flags & (VIFF_TUNNEL | VIFF_REGISTER))) {
-	    struct sockaddr_in *so = (struct sockaddr_in *)&(ifr.ifr_addr);
-
-	    so->sin_len = sizeof(struct sockaddr_in);
-	    so->sin_family = AF_INET;
-	    so->sin_addr.s_addr = INADDR_ANY;
 	    ifp = V_viftable[vifi].v_ifp;
 	    if_allmulti(ifp, 0);
 	}
@@ -804,7 +798,7 @@ set_assert(int i)
 int
 set_api_config(uint32_t *apival)
 {
-    int i;
+    u_long i;
 
     /*
      * We can set the API capabilities only if it is the first operation
@@ -826,6 +820,7 @@ set_api_config(uint32_t *apival)
 
     for (i = 0; i < mfchashsize; i++) {
 	if (LIST_FIRST(&V_mfchashtbl[i]) != NULL) {
+	    MFC_UNLOCK();
 	    *apival = 0;
 	    return EPERM;
 	}
@@ -1439,7 +1434,7 @@ non_fatal:
 static void
 expire_upcalls(void *arg)
 {
-    int i;
+    u_long i;
 
     CURVNET_SET((struct vnet *) arg);
 
@@ -2848,7 +2843,8 @@ ip_mroute_modevent(module_t mod, int type, void *unused)
 	if_detach_event_tag = EVENTHANDLER_REGISTER(ifnet_departure_event, 
 	    if_detached_event, NULL, EVENTHANDLER_PRI_ANY);
 	if (if_detach_event_tag == NULL) {
-		printf("ip_mroute: unable to ifnet_deperture_even handler\n");
+		printf("ip_mroute: unable to register "
+		    "ifnet_departure_event handler\n");
 		MROUTER_LOCK_DESTROY();
 		return (EINVAL);
 	}
diff --git a/freebsd/sys/netinet/ip_output.c b/freebsd/sys/netinet/ip_output.c
index a70d314..93ebf4d 100644
--- a/freebsd/sys/netinet/ip_output.c
+++ b/freebsd/sys/netinet/ip_output.c
@@ -869,17 +869,13 @@ in_delayed_cksum(struct mbuf *m)
 		csum = 0xffff;
 	offset += m->m_pkthdr.csum_data;	/* checksum offset */
 
-	if (offset + sizeof(u_short) > m->m_len) {
-		printf("delayed m_pullup, m->len: %d  off: %d  p: %d\n",
-		    m->m_len, offset, ip->ip_p);
-		/*
-		 * XXX
-		 * this shouldn't happen, but if it does, the
-		 * correct behavior may be to insert the checksum
-		 * in the appropriate next mbuf in the chain.
-		 */
-		return;
+	/* find the mbuf in the chain where the checksum starts*/
+	while ((m != NULL) && (offset >= m->m_len)) {
+		offset -= m->m_len;
+		m = m->m_next;
 	}
+	KASSERT(m != NULL, ("in_delayed_cksum: checksum outside mbuf chain."));
+	KASSERT(offset + sizeof(u_short) <= m->m_len, ("in_delayed_cksum: checksum split between mbufs."));
 	*(u_short *)(m->m_data + offset) = csum;
 }
 
diff --git a/freebsd/sys/netinet/sctp.h b/freebsd/sys/netinet/sctp.h
index 03cf86a..d0b90d3 100644
--- a/freebsd/sys/netinet/sctp.h
+++ b/freebsd/sys/netinet/sctp.h
@@ -43,13 +43,13 @@ __FBSDID("$FreeBSD$");
 #define SCTP_PACKED __attribute__((packed))
 
 /*
- * SCTP protocol - RFC2960.
+ * SCTP protocol - RFC4960.
  */
 struct sctphdr {
 	uint16_t src_port;	/* source port */
 	uint16_t dest_port;	/* destination port */
 	uint32_t v_tag;		/* verification tag of packet */
-	uint32_t checksum;	/* Adler32 C-Sum */
+	uint32_t checksum;	/* CRC32C checksum */
 	/* chunks follow... */
 }       SCTP_PACKED;
 
@@ -365,6 +365,12 @@ struct sctp_paramhdr {
 /*
  * error cause parameters (user visible)
  */
+struct sctp_gen_error_cause {
+	uint16_t code;
+	uint16_t length;
+	uint8_t info[];
+}                    SCTP_PACKED;
+
 struct sctp_error_cause {
 	uint16_t code;
 	uint16_t length;
@@ -402,6 +408,11 @@ struct sctp_error_unrecognized_chunk {
 	struct sctp_chunkhdr ch;/* header from chunk in error */
 }                             SCTP_PACKED;
 
+struct sctp_error_no_user_data {
+	struct sctp_error_cause cause;	/* code=SCTP_CAUSE_NO_USER_DATA */
+	uint32_t tsn;		/* TSN of the empty data chunk */
+}                       SCTP_PACKED;
+
 /*
  * Main SCTP chunk types we place these here so natd and f/w's in user land
  * can find them.
@@ -425,7 +436,7 @@ struct sctp_error_unrecognized_chunk {
 /* RFC4895 */
 #define SCTP_AUTHENTICATION     0x0f
 /* EY nr_sack chunk id*/
-#define SCTP_NR_SELECTIVE_ACK 0x10
+#define SCTP_NR_SELECTIVE_ACK	0x10
 /************0x40 series ***********/
 /************0x80 series ***********/
 /* RFC5061 */
@@ -509,38 +520,38 @@ struct sctp_error_unrecognized_chunk {
 /*
  * PCB Features (in sctp_features bitmask)
  */
-#define SCTP_PCB_FLAGS_DO_NOT_PMTUD      0x00000001
-#define SCTP_PCB_FLAGS_EXT_RCVINFO       0x00000002	/* deprecated */
-#define SCTP_PCB_FLAGS_DONOT_HEARTBEAT   0x00000004
-#define SCTP_PCB_FLAGS_FRAG_INTERLEAVE   0x00000008
-#define SCTP_PCB_FLAGS_INTERLEAVE_STRMS  0x00000010
-#define SCTP_PCB_FLAGS_DO_ASCONF         0x00000020
-#define SCTP_PCB_FLAGS_AUTO_ASCONF       0x00000040
-#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE  0x00000080
+#define SCTP_PCB_FLAGS_DO_NOT_PMTUD      0x0000000000000001
+#define SCTP_PCB_FLAGS_EXT_RCVINFO       0x0000000000000002	/* deprecated */
+#define SCTP_PCB_FLAGS_DONOT_HEARTBEAT   0x0000000000000004
+#define SCTP_PCB_FLAGS_FRAG_INTERLEAVE   0x0000000000000008
+#define SCTP_PCB_FLAGS_INTERLEAVE_STRMS  0x0000000000000010
+#define SCTP_PCB_FLAGS_DO_ASCONF         0x0000000000000020
+#define SCTP_PCB_FLAGS_AUTO_ASCONF       0x0000000000000040
+#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE  0x0000000000000080
 /* socket options */
-#define SCTP_PCB_FLAGS_NODELAY           0x00000100
-#define SCTP_PCB_FLAGS_AUTOCLOSE         0x00000200
-#define SCTP_PCB_FLAGS_RECVDATAIOEVNT    0x00000400	/* deprecated */
-#define SCTP_PCB_FLAGS_RECVASSOCEVNT     0x00000800
-#define SCTP_PCB_FLAGS_RECVPADDREVNT     0x00001000
-#define SCTP_PCB_FLAGS_RECVPEERERR       0x00002000
-#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT  0x00004000	/* deprecated */
-#define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT  0x00008000
-#define SCTP_PCB_FLAGS_ADAPTATIONEVNT    0x00010000
-#define SCTP_PCB_FLAGS_PDAPIEVNT         0x00020000
-#define SCTP_PCB_FLAGS_AUTHEVNT          0x00040000
-#define SCTP_PCB_FLAGS_STREAM_RESETEVNT  0x00080000
-#define SCTP_PCB_FLAGS_NO_FRAGMENT       0x00100000
-#define SCTP_PCB_FLAGS_EXPLICIT_EOR      0x00400000
-#define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4   0x00800000
-#define SCTP_PCB_FLAGS_MULTIPLE_ASCONFS  0x01000000
-#define SCTP_PCB_FLAGS_PORTREUSE         0x02000000
-#define SCTP_PCB_FLAGS_DRYEVNT           0x04000000
-#define SCTP_PCB_FLAGS_RECVRCVINFO       0x08000000
-#define SCTP_PCB_FLAGS_RECVNXTINFO       0x10000000
-#define SCTP_PCB_FLAGS_ASSOC_RESETEVNT   0x20000000
-#define SCTP_PCB_FLAGS_STREAM_CHANGEEVNT 0x40000000
-#define SCTP_PCB_FLAGS_RECVNSENDFAILEVNT 0x80000000
+#define SCTP_PCB_FLAGS_NODELAY           0x0000000000000100
+#define SCTP_PCB_FLAGS_AUTOCLOSE         0x0000000000000200
+#define SCTP_PCB_FLAGS_RECVDATAIOEVNT    0x0000000000000400	/* deprecated */
+#define SCTP_PCB_FLAGS_RECVASSOCEVNT     0x0000000000000800
+#define SCTP_PCB_FLAGS_RECVPADDREVNT     0x0000000000001000
+#define SCTP_PCB_FLAGS_RECVPEERERR       0x0000000000002000
+#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT  0x0000000000004000	/* deprecated */
+#define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT  0x0000000000008000
+#define SCTP_PCB_FLAGS_ADAPTATIONEVNT    0x0000000000010000
+#define SCTP_PCB_FLAGS_PDAPIEVNT         0x0000000000020000
+#define SCTP_PCB_FLAGS_AUTHEVNT          0x0000000000040000
+#define SCTP_PCB_FLAGS_STREAM_RESETEVNT  0x0000000000080000
+#define SCTP_PCB_FLAGS_NO_FRAGMENT       0x0000000000100000
+#define SCTP_PCB_FLAGS_EXPLICIT_EOR      0x0000000000400000
+#define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4   0x0000000000800000
+#define SCTP_PCB_FLAGS_MULTIPLE_ASCONFS  0x0000000001000000
+#define SCTP_PCB_FLAGS_PORTREUSE         0x0000000002000000
+#define SCTP_PCB_FLAGS_DRYEVNT           0x0000000004000000
+#define SCTP_PCB_FLAGS_RECVRCVINFO       0x0000000008000000
+#define SCTP_PCB_FLAGS_RECVNXTINFO       0x0000000010000000
+#define SCTP_PCB_FLAGS_ASSOC_RESETEVNT   0x0000000020000000
+#define SCTP_PCB_FLAGS_STREAM_CHANGEEVNT 0x0000000040000000
+#define SCTP_PCB_FLAGS_RECVNSENDFAILEVNT 0x0000000080000000
 
 /*-
  * mobility_features parameters (by micchie).Note
diff --git a/freebsd/sys/netinet/sctp_asconf.c b/freebsd/sys/netinet/sctp_asconf.c
index 71fa307..551f069 100644
--- a/freebsd/sys/netinet/sctp_asconf.c
+++ b/freebsd/sys/netinet/sctp_asconf.c
@@ -152,7 +152,12 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
 	struct mbuf *m_reply = NULL;
 	struct sockaddr_storage sa_store;
 	struct sctp_paramhdr *ph;
-	uint16_t param_type, param_length, aparam_length;
+	uint16_t param_type, aparam_length;
+
+#if defined(INET) || defined(INET6)
+	uint16_t param_length;
+
+#endif
 	struct sockaddr *sa;
 	int zero_address = 0;
 	int bad_address = 0;
@@ -171,8 +176,9 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
 	aparam_length = ntohs(aph->ph.param_length);
 	ph = (struct sctp_paramhdr *)(aph + 1);
 	param_type = ntohs(ph->param_type);
+#if defined(INET) || defined(INET6)
 	param_length = ntohs(ph->param_length);
-
+#endif
 	sa = (struct sockaddr *)&sa_store;
 	switch (param_type) {
 #ifdef INET
@@ -300,7 +306,12 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
 	struct mbuf *m_reply = NULL;
 	struct sockaddr_storage sa_store;
 	struct sctp_paramhdr *ph;
-	uint16_t param_type, param_length, aparam_length;
+	uint16_t param_type, aparam_length;
+
+#if defined(INET) || defined(INET6)
+	uint16_t param_length;
+
+#endif
 	struct sockaddr *sa;
 	int zero_address = 0;
 	int result;
@@ -319,8 +330,9 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
 	aparam_length = ntohs(aph->ph.param_length);
 	ph = (struct sctp_paramhdr *)(aph + 1);
 	param_type = ntohs(ph->param_type);
+#if defined(INET) || defined(INET6)
 	param_length = ntohs(ph->param_length);
-
+#endif
 	sa = (struct sockaddr *)&sa_store;
 	switch (param_type) {
 #ifdef INET
@@ -429,7 +441,12 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
 	struct mbuf *m_reply = NULL;
 	struct sockaddr_storage sa_store;
 	struct sctp_paramhdr *ph;
-	uint16_t param_type, param_length, aparam_length;
+	uint16_t param_type, aparam_length;
+
+#if defined(INET) || defined(INET6)
+	uint16_t param_length;
+
+#endif
 	struct sockaddr *sa;
 	int zero_address = 0;
 
@@ -447,8 +464,9 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
 	aparam_length = ntohs(aph->ph.param_length);
 	ph = (struct sctp_paramhdr *)(aph + 1);
 	param_type = ntohs(ph->param_type);
+#if defined(INET) || defined(INET6)
 	param_length = ntohs(ph->param_length);
-
+#endif
 	sa = (struct sockaddr *)&sa_store;
 	switch (param_type) {
 #ifdef INET
@@ -862,10 +880,12 @@ sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
 static uint32_t
 sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
 {
+#if defined(INET) || defined(INET6)
 	uint16_t param_type, param_length;
 
 	param_type = ntohs(ph->param_type);
 	param_length = ntohs(ph->param_length);
+#endif
 	switch (sa->sa_family) {
 #ifdef INET6
 	case AF_INET6:
@@ -876,7 +896,7 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
 
 			v6addr = (struct sctp_ipv6addr_param *)ph;
 			if ((param_type == SCTP_IPV6_ADDRESS) &&
-			    param_length == sizeof(struct sctp_ipv6addr_param) &&
+			    (param_length == sizeof(struct sctp_ipv6addr_param)) &&
 			    (memcmp(&v6addr->addr, &sin6->sin6_addr,
 			    sizeof(struct in6_addr)) == 0)) {
 				return (1);
@@ -892,7 +912,7 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
 
 			v4addr = (struct sctp_ipv4addr_param *)ph;
 			if ((param_type == SCTP_IPV4_ADDRESS) &&
-			    param_length == sizeof(struct sctp_ipv4addr_param) &&
+			    (param_length == sizeof(struct sctp_ipv4addr_param)) &&
 			    (memcmp(&v4addr->addr, &sin->sin_addr,
 			    sizeof(struct in_addr)) == 0)) {
 				return (1);
@@ -1193,7 +1213,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
     uint16_t type)
 {
 	struct sctp_asconf_addr *aa, *aa_next;
-	struct sockaddr *sa;
 
 	/* make sure the request isn't already in the queue */
 	TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
@@ -1257,7 +1276,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
 			struct sockaddr_in6 *sin6;
 
 			sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
-			sa = (struct sockaddr *)sin6;
 			aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
 			aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
 			aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
@@ -1273,7 +1291,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
 			struct sockaddr_in *sin;
 
 			sin = (struct sockaddr_in *)&ifa->address.sa;
-			sa = (struct sockaddr *)sin;
 			aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
 			aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
 			aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
@@ -1296,13 +1313,13 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
 	if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) {
 		if (type == SCTP_ADD_IP_ADDRESS) {
 			SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
-			SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
+			SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
 		} else if (type == SCTP_DEL_IP_ADDRESS) {
 			SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
-			SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
+			SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
 		} else {
 			SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
-			SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
+			SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
 		}
 	}
 #endif
@@ -1874,14 +1891,22 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 	 * this is boundall or subset bound w/ASCONF allowed
 	 */
 
-	/* first, make sure it's a good address family */
+	/* first, make sure that the address is IPv4 or IPv6 and not jailed */
 	switch (ifa->address.sa.sa_family) {
 #ifdef INET6
 	case AF_INET6:
+		if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+		    &ifa->address.sin6.sin6_addr) != 0) {
+			return;
+		}
 		break;
 #endif
 #ifdef INET
 	case AF_INET:
+		if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+		    &ifa->address.sin.sin_addr) != 0) {
+			return;
+		}
 		break;
 #endif
 	default:
@@ -2107,6 +2132,10 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 					/* we skip unspecifed addresses */
 					continue;
 				}
+				if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+				    &sin6->sin6_addr) != 0) {
+					continue;
+				}
 				if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
 					if (stcb->asoc.scope.local_scope == 0) {
 						continue;
@@ -2137,6 +2166,10 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 					/* we skip unspecifed addresses */
 					continue;
 				}
+				if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+				    &sin->sin_addr) != 0) {
+					continue;
+				}
 				if (stcb->asoc.scope.ipv4_local_scope == 0 &&
 				    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
 					continue;
@@ -2450,6 +2483,10 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
 						/* skip unspecifed addresses */
 						continue;
 					}
+					if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
+					    &sin->sin_addr) != 0) {
+						continue;
+					}
 					if (stcb->asoc.scope.ipv4_local_scope == 0 &&
 					    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
 						continue;
@@ -2483,6 +2520,10 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
 						 */
 						continue;
 					}
+					if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
+					    &sin6->sin6_addr) != 0) {
+						continue;
+					}
 					if (stcb->asoc.scope.local_scope == 0 &&
 					    IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
 						continue;
@@ -2601,7 +2642,8 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
 		/* get the parameter length */
 		p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
 		/* will it fit in current chunk? */
-		if (SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) {
+		if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) ||
+		    (SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) {
 			/* won't fit, so we're done with this chunk */
 			break;
 		}
@@ -2722,7 +2764,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
 	/* chain it all together */
 	SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
 	*retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf);
-	acp->ch.chunk_length = ntohs(*retlen);
+	acp->ch.chunk_length = htons(*retlen);
 
 	return (m_asconf_chk);
 }
@@ -3096,6 +3138,10 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
 #ifdef INET
 			case AF_INET:
 				sin = (struct sockaddr_in *)&sctp_ifa->address.sin;
+				if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
+				    &sin->sin_addr) != 0) {
+					continue;
+				}
 				if ((ipv4_scope == 0) &&
 				    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
 					/* private address not in scope */
@@ -3106,6 +3152,10 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
 #ifdef INET6
 			case AF_INET6:
 				sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sin6;
+				if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
+				    &sin6->sin6_addr) != 0) {
+					continue;
+				}
 				if ((local_scope == 0) &&
 				    (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
 					continue;
@@ -3391,6 +3441,10 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
 #ifdef INET
 				case AF_INET:
 					to = &sctp_ifap->address.sin;
+					if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
+					    &to->sin_addr) != 0) {
+						continue;
+					}
 					if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
 						continue;
 					}
@@ -3402,6 +3456,10 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
 #ifdef INET6
 				case AF_INET6:
 					to6 = &sctp_ifap->address.sin6;
+					if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
+					    &to6->sin6_addr) != 0) {
+						continue;
+					}
 					if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
 						continue;
 					}
diff --git a/freebsd/sys/netinet/sctp_auth.c b/freebsd/sys/netinet/sctp_auth.c
index ddb1256..fc64903 100644
--- a/freebsd/sys/netinet/sctp_auth.c
+++ b/freebsd/sys/netinet/sctp_auth.c
@@ -335,10 +335,6 @@ sctp_generate_random_key(uint32_t keylen)
 {
 	sctp_key_t *new_key;
 
-	/* validate keylen */
-	if (keylen > SCTP_AUTH_RANDOM_SIZE_MAX)
-		keylen = SCTP_AUTH_RANDOM_SIZE_MAX;
-
 	new_key = sctp_alloc_key(keylen);
 	if (new_key == NULL) {
 		/* out of memory */
@@ -376,7 +372,7 @@ sctp_compare_key(sctp_key_t * key1, sctp_key_t * key2)
 	uint32_t i;
 	uint32_t key1len, key2len;
 	uint8_t *key_1, *key_2;
-	uint8_t temp[SCTP_AUTH_RANDOM_SIZE_MAX];
+	uint8_t val1, val2;
 
 	/* sanity/length check */
 	key1len = sctp_get_keylen(key1);
@@ -388,38 +384,24 @@ sctp_compare_key(sctp_key_t * key1, sctp_key_t * key2)
 	else if (key2len == 0)
 		return (1);
 
-	if (key1len != key2len) {
-		if (key1len >= key2len)
-			maxlen = key1len;
-		else
-			maxlen = key2len;
-		bzero(temp, maxlen);
-		if (key1len < maxlen) {
-			/* prepend zeroes to key1 */
-			bcopy(key1->key, temp + (maxlen - key1len), key1len);
-			key_1 = temp;
-			key_2 = key2->key;
-		} else {
-			/* prepend zeroes to key2 */
-			bcopy(key2->key, temp + (maxlen - key2len), key2len);
-			key_1 = key1->key;
-			key_2 = temp;
-		}
+	if (key1len < key2len) {
+		maxlen = key2len;
 	} else {
 		maxlen = key1len;
-		key_1 = key1->key;
-		key_2 = key2->key;
 	}
-
+	key_1 = key1->key;
+	key_2 = key2->key;
+	/* check for numeric equality */
 	for (i = 0; i < maxlen; i++) {
-		if (*key_1 > *key_2)
+		/* left-pad with zeros */
+		val1 = (i < (maxlen - key1len)) ? 0 : *(key_1++);
+		val2 = (i < (maxlen - key2len)) ? 0 : *(key_2++);
+		if (val1 > val2) {
 			return (1);
-		else if (*key_1 < *key_2)
+		} else if (val1 < val2) {
 			return (-1);
-		key_1++;
-		key_2++;
+		}
 	}
-
 	/* keys are equal value, so check lengths */
 	if (key1len == key2len)
 		return (0);
@@ -705,15 +687,7 @@ sctp_auth_add_hmacid(sctp_hmaclist_t * list, uint16_t hmac_id)
 		return (-1);
 	}
 	if ((hmac_id != SCTP_AUTH_HMAC_ID_SHA1) &&
-#ifdef HAVE_SHA224
-	    (hmac_id != SCTP_AUTH_HMAC_ID_SHA224) &&
-#endif
-#ifdef HAVE_SHA2
-	    (hmac_id != SCTP_AUTH_HMAC_ID_SHA256) &&
-	    (hmac_id != SCTP_AUTH_HMAC_ID_SHA384) &&
-	    (hmac_id != SCTP_AUTH_HMAC_ID_SHA512) &&
-#endif
-	    1) {
+	    (hmac_id != SCTP_AUTH_HMAC_ID_SHA256)) {
 		return (-1);
 	}
 	/* Now is it already in the list */
@@ -756,8 +730,9 @@ sctp_default_supported_hmaclist(void)
 	new_list = sctp_alloc_hmaclist(2);
 	if (new_list == NULL)
 		return (NULL);
-	(void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1);
+	/* We prefer SHA256, so list it first */
 	(void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA256);
+	(void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1);
 	return (new_list);
 }
 
@@ -813,19 +788,13 @@ int
 sctp_verify_hmac_param(struct sctp_auth_hmac_algo *hmacs, uint32_t num_hmacs)
 {
 	uint32_t i;
-	uint16_t hmac_id;
-	uint32_t sha1_supported = 0;
 
 	for (i = 0; i < num_hmacs; i++) {
-		hmac_id = ntohs(hmacs->hmac_ids[i]);
-		if (hmac_id == SCTP_AUTH_HMAC_ID_SHA1)
-			sha1_supported = 1;
+		if (ntohs(hmacs->hmac_ids[i]) == SCTP_AUTH_HMAC_ID_SHA1) {
+			return (0);
+		}
 	}
-	/* all HMAC id's are supported */
-	if (sha1_supported == 0)
-		return (-1);
-	else
-		return (0);
+	return (-1);
 }
 
 sctp_authinfo_t *
@@ -879,18 +848,8 @@ sctp_get_hmac_digest_len(uint16_t hmac_algo)
 	switch (hmac_algo) {
 	case SCTP_AUTH_HMAC_ID_SHA1:
 		return (SCTP_AUTH_DIGEST_LEN_SHA1);
-#ifdef HAVE_SHA224
-	case SCTP_AUTH_HMAC_ID_SHA224:
-		return (SCTP_AUTH_DIGEST_LEN_SHA224);
-#endif
-#ifdef HAVE_SHA2
 	case SCTP_AUTH_HMAC_ID_SHA256:
 		return (SCTP_AUTH_DIGEST_LEN_SHA256);
-	case SCTP_AUTH_HMAC_ID_SHA384:
-		return (SCTP_AUTH_DIGEST_LEN_SHA384);
-	case SCTP_AUTH_HMAC_ID_SHA512:
-		return (SCTP_AUTH_DIGEST_LEN_SHA512);
-#endif
 	default:
 		/* unknown HMAC algorithm: can't do anything */
 		return (0);
@@ -902,17 +861,9 @@ sctp_get_hmac_block_len(uint16_t hmac_algo)
 {
 	switch (hmac_algo) {
 	case SCTP_AUTH_HMAC_ID_SHA1:
-#ifdef HAVE_SHA224
-	case SCTP_AUTH_HMAC_ID_SHA224:
-#endif
 		return (64);
-#ifdef HAVE_SHA2
 	case SCTP_AUTH_HMAC_ID_SHA256:
 		return (64);
-	case SCTP_AUTH_HMAC_ID_SHA384:
-	case SCTP_AUTH_HMAC_ID_SHA512:
-		return (128);
-#endif
 	case SCTP_AUTH_HMAC_ID_RSVD:
 	default:
 		/* unknown HMAC algorithm: can't do anything */
@@ -925,23 +876,11 @@ sctp_hmac_init(uint16_t hmac_algo, sctp_hash_context_t * ctx)
 {
 	switch (hmac_algo) {
 	case SCTP_AUTH_HMAC_ID_SHA1:
-		SHA1_Init(&ctx->sha1);
+		SCTP_SHA1_INIT(&ctx->sha1);
 		break;
-#ifdef HAVE_SHA224
-	case SCTP_AUTH_HMAC_ID_SHA224:
-		break;
-#endif
-#ifdef HAVE_SHA2
 	case SCTP_AUTH_HMAC_ID_SHA256:
-		SHA256_Init(&ctx->sha256);
+		SCTP_SHA256_INIT(&ctx->sha256);
 		break;
-	case SCTP_AUTH_HMAC_ID_SHA384:
-		SHA384_Init(&ctx->sha384);
-		break;
-	case SCTP_AUTH_HMAC_ID_SHA512:
-		SHA512_Init(&ctx->sha512);
-		break;
-#endif
 	case SCTP_AUTH_HMAC_ID_RSVD:
 	default:
 		/* unknown HMAC algorithm: can't do anything */
@@ -955,23 +894,11 @@ sctp_hmac_update(uint16_t hmac_algo, sctp_hash_context_t * ctx,
 {
 	switch (hmac_algo) {
 	case SCTP_AUTH_HMAC_ID_SHA1:
-		SHA1_Update(&ctx->sha1, text, textlen);
-		break;
-#ifdef HAVE_SHA224
-	case SCTP_AUTH_HMAC_ID_SHA224:
+		SCTP_SHA1_UPDATE(&ctx->sha1, text, textlen);
 		break;
-#endif
-#ifdef HAVE_SHA2
 	case SCTP_AUTH_HMAC_ID_SHA256:
-		SHA256_Update(&ctx->sha256, text, textlen);
-		break;
-	case SCTP_AUTH_HMAC_ID_SHA384:
-		SHA384_Update(&ctx->sha384, text, textlen);
-		break;
-	case SCTP_AUTH_HMAC_ID_SHA512:
-		SHA512_Update(&ctx->sha512, text, textlen);
+		SCTP_SHA256_UPDATE(&ctx->sha256, text, textlen);
 		break;
-#endif
 	case SCTP_AUTH_HMAC_ID_RSVD:
 	default:
 		/* unknown HMAC algorithm: can't do anything */
@@ -985,24 +912,11 @@ sctp_hmac_final(uint16_t hmac_algo, sctp_hash_context_t * ctx,
 {
 	switch (hmac_algo) {
 	case SCTP_AUTH_HMAC_ID_SHA1:
-		SHA1_Final(digest, &ctx->sha1);
-		break;
-#ifdef HAVE_SHA224
-	case SCTP_AUTH_HMAC_ID_SHA224:
+		SCTP_SHA1_FINAL(digest, &ctx->sha1);
 		break;
-#endif
-#ifdef HAVE_SHA2
 	case SCTP_AUTH_HMAC_ID_SHA256:
-		SHA256_Final(digest, &ctx->sha256);
-		break;
-	case SCTP_AUTH_HMAC_ID_SHA384:
-		/* SHA384 is truncated SHA512 */
-		SHA384_Final(digest, &ctx->sha384);
+		SCTP_SHA256_FINAL(digest, &ctx->sha256);
 		break;
-	case SCTP_AUTH_HMAC_ID_SHA512:
-		SHA512_Final(digest, &ctx->sha512);
-		break;
-#endif
 	case SCTP_AUTH_HMAC_ID_RSVD:
 	default:
 		/* unknown HMAC algorithm: can't do anything */
@@ -1878,6 +1792,7 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
 
 	SCTP_BUF_LEN(m_notify) = 0;
 	auth = mtod(m_notify, struct sctp_authkey_event *);
+	memset(auth, 0, sizeof(struct sctp_authkey_event));
 	auth->auth_type = SCTP_AUTHENTICATION_EVENT;
 	auth->auth_flags = 0;
 	auth->auth_length = sizeof(*auth);
diff --git a/freebsd/sys/netinet/sctp_auth.h b/freebsd/sys/netinet/sctp_auth.h
index eac89f6..535c0fc 100644
--- a/freebsd/sys/netinet/sctp_auth.h
+++ b/freebsd/sys/netinet/sctp_auth.h
@@ -36,28 +36,21 @@ __FBSDID("$FreeBSD$");
 #ifndef _NETINET_SCTP_AUTH_H_
 #define _NETINET_SCTP_AUTH_H_
 
+#include <netinet/sctp_os.h>
 
 /* digest lengths */
 #define SCTP_AUTH_DIGEST_LEN_SHA1	20
-#define SCTP_AUTH_DIGEST_LEN_SHA224	28
 #define SCTP_AUTH_DIGEST_LEN_SHA256	32
-#define SCTP_AUTH_DIGEST_LEN_SHA384	48
-#define SCTP_AUTH_DIGEST_LEN_SHA512	64
-#define SCTP_AUTH_DIGEST_LEN_MAX	64
+#define SCTP_AUTH_DIGEST_LEN_MAX	SCTP_AUTH_DIGEST_LEN_SHA256
 
 /* random sizes */
 #define SCTP_AUTH_RANDOM_SIZE_DEFAULT	32
 #define SCTP_AUTH_RANDOM_SIZE_REQUIRED	32
-#define SCTP_AUTH_RANDOM_SIZE_MAX	256
 
 /* union of all supported HMAC algorithm contexts */
 typedef union sctp_hash_context {
-	SHA1_CTX sha1;
-#ifdef HAVE_SHA2
-	SHA256_CTX sha256;
-	SHA384_CTX sha384;
-	SHA512_CTX sha512;
-#endif
+	SCTP_SHA1_CTX sha1;
+	SCTP_SHA256_CTX sha256;
 }                 sctp_hash_context_t;
 
 typedef struct sctp_key {
diff --git a/freebsd/sys/netinet/sctp_bsd_addr.c b/freebsd/sys/netinet/sctp_bsd_addr.c
index 4653b25..d558bd8 100644
--- a/freebsd/sys/netinet/sctp_bsd_addr.c
+++ b/freebsd/sys/netinet/sctp_bsd_addr.c
@@ -98,22 +98,15 @@ sctp_iterator_thread(void *v SCTP_UNUSED)
 void
 sctp_startup_iterator(void)
 {
-	static int called = 0;
-	int ret;
-
-	if (called) {
+	if (sctp_it_ctl.thread_proc) {
 		/* You only get one */
 		return;
 	}
-	/* init the iterator head */
-	called = 1;
-	sctp_it_ctl.iterator_running = 0;
-	sctp_it_ctl.iterator_flags = 0;
-	sctp_it_ctl.cur_it = NULL;
+	/* Initialize global locks here, thus only once. */
 	SCTP_ITERATOR_LOCK_INIT();
 	SCTP_IPI_ITERATOR_WQ_INIT();
 	TAILQ_INIT(&sctp_it_ctl.iteratorhead);
-	ret = kproc_create(sctp_iterator_thread,
+	kproc_create(sctp_iterator_thread,
 	    (void *)NULL,
 	    &sctp_it_ctl.thread_proc,
 	    RFPROC,
diff --git a/freebsd/sys/netinet/sctp_constants.h b/freebsd/sys/netinet/sctp_constants.h
index 58ca808..0ede04c 100644
--- a/freebsd/sys/netinet/sctp_constants.h
+++ b/freebsd/sys/netinet/sctp_constants.h
@@ -36,16 +36,10 @@ __FBSDID("$FreeBSD$");
 #ifndef _NETINET_SCTP_CONSTANTS_H_
 #define _NETINET_SCTP_CONSTANTS_H_
 
+
 /* IANA assigned port number for SCTP over UDP encapsulation */
-/* For freebsd we cannot bind the port at
- * startup. Otherwise what will happen is
- * we really won't be bound. The user must
- * put it into the sysctl... or we need
- * to build a special timer for this to allow
- * us to wait 1 second or so after the system
- * comes up.
- */
-#define SCTP_OVER_UDP_TUNNELING_PORT 0
+#define SCTP_OVER_UDP_TUNNELING_PORT 9899
+
 /* Number of packets to get before sack sent by default */
 #define SCTP_DEFAULT_SACK_FREQ 2
 
@@ -726,7 +720,6 @@ __FBSDID("$FreeBSD$");
 /* small chunk store for looking at chunk_list in auth */
 #define SCTP_SMALL_CHUNK_STORE 260
 
-#define SCTP_DEFAULT_MINSEGMENT 512	/* MTU size ... if no mtu disc */
 #define SCTP_HOW_MANY_SECRETS	2	/* how many secrets I keep */
 
 #define SCTP_NUMBER_OF_SECRETS	8	/* or 8 * 4 = 32 octets */
@@ -772,6 +765,9 @@ __FBSDID("$FreeBSD$");
  */
 #define SCTP_DEFAULT_SPLIT_POINT_MIN 2904
 
+/* Maximum length of diagnostic information in error causes */
+#define SCTP_DIAG_INFO_LEN 64
+
 /* ABORT CODES and other tell-tale location
  * codes are generated by adding the below
  * to the instance id.
diff --git a/freebsd/sys/netinet/sctp_dtrace_define.h b/freebsd/sys/netinet/sctp_dtrace_define.h
index 1eb28f6..0bfe18c 100644
--- a/freebsd/sys/netinet/sctp_dtrace_define.h
+++ b/freebsd/sys/netinet/sctp_dtrace_define.h
@@ -45,189 +45,132 @@ SDT_PROVIDER_DEFINE(sctp);
 /* Cwnd probe - tracks changes in the congestion window on a netp */
 /********************************************************/
 /* Initial */
-SDT_PROBE_DEFINE(sctp, cwnd, net, init, init);
-/* The Vtag for this end */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 0, "uint32_t");
-/* The port number of the local side << 16 | port number of remote
- * in network byte order.
- */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 1, "uint32_t");
-/* The pointer to the struct sctp_nets * changing */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 2, "uintptr_t");
-/* The old value of the cwnd  */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 3, "int");
-/* The new value of the cwnd */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 4, "int");
-
+SDT_PROBE_DEFINE5(sctp, cwnd, net, init,
+    "uint32_t",		/* The Vtag for this end */
+    "uint32_t",		/*
+			 * The port number of the local side << 16 | port number
+			 * of remote in network byte order.
+			 */
+    "uintptr_t",	/* The pointer to the struct sctp_nets * changing */
+    "int",		/* The old value of the cwnd */
+    "int");		/* The new value of the cwnd */
 
 /* ACK-INCREASE */
-SDT_PROBE_DEFINE(sctp, cwnd, net, ack, ack);
-/* The Vtag for this end */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 0, "uint32_t");
-/* The port number of the local side << 16 | port number of remote
- * in network byte order.
- */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 1, "uint32_t");
-/* The pointer to the struct sctp_nets * changing */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 2, "uintptr_t");
-/* The old value of the cwnd  */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 3, "int");
-/* The new value of the cwnd */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 4, "int");
-
+SDT_PROBE_DEFINE5(sctp, cwnd, net, ack,
+    "uint32_t",		/* The Vtag for this end */
+    "uint32_t",		/*
+			 * The port number of the local side << 16 | port number
+			 * of remote in network byte order.
+			 */
+    "uintptr_t",	/* The pointer to the struct sctp_nets * changing */
+    "int",		/* The old value of the cwnd */
+    "int");		/* The new value of the cwnd */
 
 /* ACK-INCREASE */
-SDT_PROBE_DEFINE(sctp, cwnd, net, rttvar, rttvar);
-/* The Vtag << 32 | localport << 16 | remoteport */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 0, "uint64_t");
-/* obw | nbw */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 1, "uint64_t");
-/* bwrtt | newrtt */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 2, "uint64_t");
-/* flight */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 3, "uint64_t");
-/* (cwnd << 32) | point << 16 | retval(0/1) */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 4, "uint64_t");
-
-
-SDT_PROBE_DEFINE(sctp, cwnd, net, rttstep, rttstep);
-/* The Vtag << 32 | localport << 16 | remoteport */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 0, "uint64_t");
-/* obw | nbw */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 1, "uint64_t");
-/* bwrtt | nrtt */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 2, "uint64_t");
-/* cwnd_saved | stepcnt << 16 | oldstep  */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 3, "uint64_t");
-/* (cwnd << 32) | point << 16 | retval(0/1) */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 4, "uint64_t");
-
+SDT_PROBE_DEFINE5(sctp, cwnd, net, rttvar,
+    "uint64_t",		/* The Vtag << 32 | localport << 16 | remoteport */
+    "uint64_t",		/* obw | nbw */
+    "uint64_t",		/* bwrtt | newrtt */
+    "uint64_t",		/* flight */
+    "uint64_t");	/* (cwnd << 32) | point << 16 | retval(0/1) */
+
+SDT_PROBE_DEFINE5(sctp, cwnd, net, rttstep,
+    "uint64_t",		/* The Vtag << 32 | localport << 16 | remoteport */
+    "uint64_t",		/* obw | nbw */
+    "uint64_t",		/* bwrtt | newrtt */
+    "uint64_t",		/* flight */
+    "uint64_t");	/* (cwnd << 32) | point << 16 | retval(0/1) */
 
 /* FastRetransmit-DECREASE */
-SDT_PROBE_DEFINE(sctp, cwnd, net, fr, fr);
-/* The Vtag for this end */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 0, "uint32_t");
-/* The port number of the local side << 16 | port number of remote
- * in network byte order.
- */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 1, "uint32_t");
-/* The pointer to the struct sctp_nets * changing */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 2, "uintptr_t");
-/* The old value of the cwnd  */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 3, "int");
-/* The new value of the cwnd */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 4, "int");
-
+SDT_PROBE_DEFINE5(sctp, cwnd, net, fr,
+    "uint32_t",		/* The Vtag for this end */
+    "uint32_t",		/*
+			 * The port number of the local side << 16 | port number
+			 * of remote in network byte order.
+			 */
+    "uintptr_t",	/* The pointer to the struct sctp_nets * changing */
+    "int",		/* The old value of the cwnd */
+    "int");		/* The new value of the cwnd */
 
 /* TimeOut-DECREASE */
-SDT_PROBE_DEFINE(sctp, cwnd, net, to, to);
-/* The Vtag for this end */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 0, "uint32_t");
-/* The port number of the local side << 16 | port number of remote
- * in network byte order.
- */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 1, "uint32_t");
-/* The pointer to the struct sctp_nets * changing */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 2, "uintptr_t");
-/* The old value of the cwnd  */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 3, "int");
-/* The new value of the cwnd */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 4, "int");
-
+SDT_PROBE_DEFINE5(sctp, cwnd, net, to,
+    "uint32_t",		/* The Vtag for this end */
+    "uint32_t",		/*
+			 * The port number of the local side << 16 | port number
+			 * of remote in network byte order.
+			 */
+    "uintptr_t",	/* The pointer to the struct sctp_nets * changing */
+    "int",		/* The old value of the cwnd */
+    "int");		/* The new value of the cwnd */
 
 /* BurstLimit-DECREASE */
-SDT_PROBE_DEFINE(sctp, cwnd, net, bl, bl);
-/* The Vtag for this end */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 0, "uint32_t");
-/* The port number of the local side << 16 | port number of remote
- * in network byte order.
- */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 1, "uint32_t");
-/* The pointer to the struct sctp_nets * changing */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 2, "uintptr_t");
-/* The old value of the cwnd  */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 3, "int");
-/* The new value of the cwnd */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 4, "int");
-
+SDT_PROBE_DEFINE5(sctp, cwnd, net, bl,
+    "uint32_t",		/* The Vtag for this end */
+    "uint32_t",		/*
+			 * The port number of the local side << 16 | port number
+			 * of remote in network byte order.
+			 */
+    "uintptr_t",	/* The pointer to the struct sctp_nets * changing */
+    "int",		/* The old value of the cwnd */
+    "int");		/* The new value of the cwnd */
 
 /* ECN-DECREASE */
-SDT_PROBE_DEFINE(sctp, cwnd, net, ecn, ecn);
-/* The Vtag for this end */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 0, "uint32_t");
-/* The port number of the local side << 16 | port number of remote
- * in network byte order.
- */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 1, "uint32_t");
-/* The pointer to the struct sctp_nets * changing */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 2, "uintptr_t");
-/* The old value of the cwnd  */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 3, "int");
-/* The new value of the cwnd */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 4, "int");
-
+SDT_PROBE_DEFINE5(sctp, cwnd, net, ecn,
+    "uint32_t",		/* The Vtag for this end */
+    "uint32_t",		/*
+			 * The port number of the local side << 16 | port number
+			 * of remote in network byte order.
+			 */
+    "uintptr_t",	/* The pointer to the struct sctp_nets * changing */
+    "int",		/* The old value of the cwnd */
+    "int");		/* The new value of the cwnd */
 
 /* PacketDrop-DECREASE */
-SDT_PROBE_DEFINE(sctp, cwnd, net, pd, pd);
-/* The Vtag for this end */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 0, "uint32_t");
-/* The port number of the local side << 16 | port number of remote
- * in network byte order.
- */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 1, "uint32_t");
-/* The pointer to the struct sctp_nets * changing */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 2, "uintptr_t");
-/* The old value of the cwnd  */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 3, "int");
-/* The new value of the cwnd */
-SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 4, "int");
-
-
+SDT_PROBE_DEFINE5(sctp, cwnd, net, pd,
+    "uint32_t",		/* The Vtag for this end */
+    "uint32_t",		/*
+			 * The port number of the local side << 16 | port number
+			 * of remote in network byte order.
+			 */
+    "uintptr_t",	/* The pointer to the struct sctp_nets * changing */
+    "int",		/* The old value of the cwnd */
+    "int");		/* The new value of the cwnd */
 
 /********************************************************/
 /* Rwnd probe - tracks changes in the receiver window for an assoc */
 /********************************************************/
-SDT_PROBE_DEFINE(sctp, rwnd, assoc, val, val);
-/* The Vtag for this end */
-SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 0, "uint32_t");
-/* The port number of the local side << 16 | port number of remote
- * in network byte order.
- */
-SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 1, "uint32_t");
-/* The up/down amount */
-SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 2, "int");
-/* The new value of the cwnd */
-SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 3, "int");
+SDT_PROBE_DEFINE4(sctp, rwnd, assoc, val,
+    "uint32_t",		/* The Vtag for this end */
+    "uint32_t",		/*
+			 * The port number of the local side << 16 | port number
+			 * of remote in network byte order.
+			 */
+    "int",		/* The up/down amount */
+    "int");		/* The new value of the cwnd */
 
 /********************************************************/
 /* flight probe - tracks changes in the flight size on a net or assoc */
 /********************************************************/
-SDT_PROBE_DEFINE(sctp, flightsize, net, val, val);
-/* The Vtag for this end */
-SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 0, "uint32_t");
-/* The port number of the local side << 16 | port number of remote
- * in network byte order.
- */
-SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 1, "uint32_t");
-/* The pointer to the struct sctp_nets * changing */
-SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 2, "uintptr_t");
-/* The up/down amount */
-SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 3, "int");
-/* The new value of the cwnd */
-SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 4, "int");
+SDT_PROBE_DEFINE5(sctp, flightsize, net, val,
+    "uint32_t",		/* The Vtag for this end */
+    "uint32_t",		/*
+			 * The port number of the local side << 16 | port number
+			 * of remote in network byte order.
+			 */
+    "uintptr_t",        /* The pointer to the struct sctp_nets * changing */
+    "int",		/* The up/down amount */
+    "int");		/* The new value of the cwnd */
+
 /********************************************************/
 /* The total flight version */
 /********************************************************/
-SDT_PROBE_DEFINE(sctp, flightsize, assoc, val, val);
-/* The Vtag for this end */
-SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 0, "uint32_t");
-/* The port number of the local side << 16 | port number of remote
- * in network byte order.
- */
-SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 1, "uint32_t");
-/* The up/down amount */
-SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 2, "int");
-/* The new value of the cwnd */
-SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 3, "int");
+SDT_PROBE_DEFINE4(sctp, flightsize, assoc, val,
+    "uint32_t",		/* The Vtag for this end */
+    "uint32_t",		/*
+			 * The port number of the local side << 16 | port number
+			 * of remote in network byte order.
+			 */
+    "int",		/* The up/down amount */
+    "int");		/* The new value of the cwnd */
 
 #endif
diff --git a/freebsd/sys/netinet/sctp_indata.c b/freebsd/sys/netinet/sctp_indata.c
index e00a470..07d8fd2 100644
--- a/freebsd/sys/netinet/sctp_indata.c
+++ b/freebsd/sys/netinet/sctp_indata.c
@@ -252,6 +252,11 @@ sctp_build_ctl_nchunk(struct sctp_inpcb *inp, struct sctp_sndrcvinfo *sinfo)
 
 	/* We need a CMSG header followed by the struct */
 	cmh = mtod(ret, struct cmsghdr *);
+	/*
+	 * Make sure that there is no un-initialized padding between the
+	 * cmsg header and cmsg data and after the cmsg data.
+	 */
+	memset(cmh, 0, len);
 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO)) {
 		cmh->cmsg_level = IPPROTO_SCTP;
 		cmh->cmsg_len = CMSG_LEN(sizeof(struct sctp_rcvinfo));
@@ -563,7 +568,8 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	struct sctp_queued_to_read *at;
 	int queue_needed;
 	uint16_t nxt_todel;
-	struct mbuf *oper;
+	struct mbuf *op_err;
+	char msg[SCTP_DIAG_INFO_LEN];
 
 	queue_needed = 1;
 	asoc->size_on_all_streams += control->length;
@@ -580,7 +586,7 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	    (uint32_t) nxt_todel);
 	if (SCTP_SSN_GE(strm->last_sequence_delivered, control->sinfo_ssn)) {
 		/* The incoming sseq is behind where we last delivered? */
-		SCTPDBG(SCTP_DEBUG_INDATA1, "Duplicate S-SEQ:%d delivered:%d from peer, Abort  association\n",
+		SCTPDBG(SCTP_DEBUG_INDATA1, "Duplicate S-SEQ:%d delivered:%d from peer, Abort association\n",
 		    control->sinfo_ssn, strm->last_sequence_delivered);
 protocol_error:
 		/*
@@ -588,26 +594,12 @@ protocol_error:
 		 * association destruction
 		 */
 		TAILQ_INSERT_HEAD(&strm->inqueue, control, next);
-		oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-		    0, M_DONTWAIT, 1, MT_DATA);
-		if (oper) {
-			struct sctp_paramhdr *ph;
-			uint32_t *ippp;
-
-			SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-			    (sizeof(uint32_t) * 3);
-			ph = mtod(oper, struct sctp_paramhdr *);
-			ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-			ph->param_length = htons(SCTP_BUF_LEN(oper));
-			ippp = (uint32_t *) (ph + 1);
-			*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_1);
-			ippp++;
-			*ippp = control->sinfo_tsn;
-			ippp++;
-			*ippp = ((control->sinfo_stream << 16) | control->sinfo_ssn);
-		}
+		snprintf(msg, sizeof(msg), "Delivered SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+		    strm->last_sequence_delivered, control->sinfo_tsn,
+		    control->sinfo_stream, control->sinfo_ssn);
+		op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 		stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_1;
-		sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 		*abort_flag = 1;
 		return;
 
@@ -791,13 +783,12 @@ doit_again:
 			 * but should we?
 			 */
 			if (stcb->sctp_socket) {
-				pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket),
+				pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
 				    stcb->sctp_ep->partial_delivery_point);
 			} else {
 				pd_point = stcb->sctp_ep->partial_delivery_point;
 			}
 			if (sctp_is_all_msg_on_reasm(asoc, &tsize) || (tsize >= pd_point)) {
-
 				/*
 				 * Yes, we setup to start reception, by
 				 * backing down the TSN just in case we
@@ -842,7 +833,8 @@ static void
 sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
     struct sctp_tmit_chunk *chk, int *abort_flag)
 {
-	struct mbuf *oper;
+	struct mbuf *op_err;
+	char msg[SCTP_DIAG_INFO_LEN];
 	uint32_t cum_ackp1, prev_tsn, post_tsn;
 	struct sctp_tmit_chunk *at, *prev, *next;
 
@@ -867,30 +859,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				 * a FIRST fragment mark.
 				 */
 				SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, its not first, no fragmented delivery in progress\n");
-				oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-				    0, M_DONTWAIT, 1, MT_DATA);
-
-				if (oper) {
-					struct sctp_paramhdr *ph;
-					uint32_t *ippp;
-
-					SCTP_BUF_LEN(oper) =
-					    sizeof(struct sctp_paramhdr) +
-					    (sizeof(uint32_t) * 3);
-					ph = mtod(oper, struct sctp_paramhdr *);
-					ph->param_type =
-					    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-					ph->param_length = htons(SCTP_BUF_LEN(oper));
-					ippp = (uint32_t *) (ph + 1);
-					*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_2);
-					ippp++;
-					*ippp = chk->rec.data.TSN_seq;
-					ippp++;
-					*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-				}
+				snprintf(msg, sizeof(msg),
+				    "Expected B-bit for TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+				    chk->rec.data.TSN_seq,
+				    chk->rec.data.stream_number,
+				    chk->rec.data.stream_seq);
+				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_2;
-				sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 				*abort_flag = 1;
 			} else if (asoc->fragmented_delivery_inprogress &&
 			    (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG) {
@@ -900,28 +876,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				 * MIDDLE fragment NOT a FIRST
 				 */
 				SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS a first and fragmented delivery in progress\n");
-				oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-				    0, M_DONTWAIT, 1, MT_DATA);
-				if (oper) {
-					struct sctp_paramhdr *ph;
-					uint32_t *ippp;
-
-					SCTP_BUF_LEN(oper) =
-					    sizeof(struct sctp_paramhdr) +
-					    (3 * sizeof(uint32_t));
-					ph = mtod(oper, struct sctp_paramhdr *);
-					ph->param_type =
-					    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-					ph->param_length = htons(SCTP_BUF_LEN(oper));
-					ippp = (uint32_t *) (ph + 1);
-					*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_3);
-					ippp++;
-					*ippp = chk->rec.data.TSN_seq;
-					ippp++;
-					*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-				}
+				snprintf(msg, sizeof(msg),
+				    "Didn't expect B-bit for TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+				    chk->rec.data.TSN_seq,
+				    chk->rec.data.stream_number,
+				    chk->rec.data.stream_seq);
+				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_3;
-				sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 				*abort_flag = 1;
 			} else if (asoc->fragmented_delivery_inprogress) {
 				/*
@@ -934,30 +896,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS not same stream number %d vs %d\n",
 					    chk->rec.data.stream_number,
 					    asoc->str_of_pdapi);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (sizeof(uint32_t) * 3);
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_4);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-					}
+					snprintf(msg, sizeof(msg),
+					    "Expected SID=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    asoc->str_of_pdapi,
+					    chk->rec.data.TSN_seq,
+					    chk->rec.data.stream_number,
+					    chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_4;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 				} else if ((asoc->fragment_flags & SCTP_DATA_UNORDERED) !=
 					    SCTP_DATA_UNORDERED &&
@@ -966,31 +913,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS not same stream seq %d vs %d\n",
 					    chk->rec.data.stream_seq,
 					    asoc->ssn_of_pdapi);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_5);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-					}
+					snprintf(msg, sizeof(msg),
+					    "Expected SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    asoc->ssn_of_pdapi,
+					    chk->rec.data.TSN_seq,
+					    chk->rec.data.stream_number,
+					    chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_5;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 				}
 			}
@@ -1060,31 +991,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				    SCTP_DATA_FIRST_FRAG) {
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - It can be a midlle or last but not a first\n");
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it's a FIRST!\n");
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_6);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-					}
+					snprintf(msg, sizeof(msg),
+					    "Can't handle B-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    chk->rec.data.TSN_seq,
+					    chk->rec.data.stream_number,
+					    chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_6;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1094,33 +1008,36 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 					 * Huh, need the correct STR here,
 					 * they must be the same.
 					 */
-					SCTP_PRINTF("Prev check - Gak, Evil plot, ssn:%d not the same as at:%d\n",
+					SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, Evil plot, sid:%d not the same as at:%d\n",
 					    chk->rec.data.stream_number,
 					    prev->rec.data.stream_number);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_7);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-					}
+					snprintf(msg, sizeof(msg),
+					    "Expect SID=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    prev->rec.data.stream_number,
+					    chk->rec.data.TSN_seq,
+					    chk->rec.data.stream_number,
+					    chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_7;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
+					*abort_flag = 1;
+					return;
+				}
+				if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) !=
+				    (prev->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) {
+					/*
+					 * Huh, need the same ordering here,
+					 * they must be the same.
+					 */
+					SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, Evil plot, U-bit not constant\n");
+					snprintf(msg, sizeof(msg),
+					    "Expect U-bit=%d for TSN=%8.8x, got U-bit=%d",
+					    (prev->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0,
+					    chk->rec.data.TSN_seq,
+					    (chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
+					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_7;
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1134,30 +1051,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, Evil plot, sseq:%d not the same as at:%d\n",
 					    chk->rec.data.stream_seq,
 					    prev->rec.data.stream_seq);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_8);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-					}
+					snprintf(msg, sizeof(msg),
+					    "Expect SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    prev->rec.data.stream_seq,
+					    chk->rec.data.TSN_seq,
+					    chk->rec.data.stream_number,
+					    chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_8;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1167,31 +1069,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				if ((chk->rec.data.rcv_flags & SCTP_DATA_FRAG_MASK) !=
 				    SCTP_DATA_FIRST_FRAG) {
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, evil plot, its not FIRST and it must be!\n");
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_9);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-					}
+					snprintf(msg, sizeof(msg),
+					    "Expect B-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    chk->rec.data.TSN_seq,
+					    chk->rec.data.stream_number,
+					    chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_9;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1211,30 +1096,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				    != SCTP_DATA_LAST_FRAG) {
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Next is FIRST, we must be LAST\n");
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, its not a last!\n");
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_10);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-					}
+					snprintf(msg, sizeof(msg),
+					    "Expect only E-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    chk->rec.data.TSN_seq,
+					    chk->rec.data.stream_number,
+					    chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_10;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1250,31 +1119,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				    SCTP_DATA_LAST_FRAG) {
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Next is a MIDDLE/LAST\n");
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, new prev chunk is a LAST\n");
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_11);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-					}
+					snprintf(msg, sizeof(msg),
+					    "Didn't expect E-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    chk->rec.data.TSN_seq,
+					    chk->rec.data.stream_number,
+					    chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_11;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1287,31 +1139,33 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Gak, Evil plot, ssn:%d not the same as at:%d\n",
 					    chk->rec.data.stream_number,
 					    next->rec.data.stream_number);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_12);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-					}
+					snprintf(msg, sizeof(msg),
+					    "Required SID %4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    next->rec.data.stream_number,
+					    chk->rec.data.TSN_seq,
+					    chk->rec.data.stream_number,
+					    chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_12;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
+					*abort_flag = 1;
+					return;
+				}
+				if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) !=
+				    (next->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) {
+					/*
+					 * Huh, need the same ordering here,
+					 * they must be the same.
+					 */
+					SCTPDBG(SCTP_DEBUG_INDATA1, "Next check - Gak, Evil plot, U-bit not constant\n");
+					snprintf(msg, sizeof(msg),
+					    "Expect U-bit=%d for TSN=%8.8x, got U-bit=%d",
+					    (next->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0,
+					    chk->rec.data.TSN_seq,
+					    (chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
+					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_12;
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1325,30 +1179,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Gak, Evil plot, sseq:%d not the same as at:%d\n",
 					    chk->rec.data.stream_seq,
 					    next->rec.data.stream_seq);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_13);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-					}
+					snprintf(msg, sizeof(msg),
+					    "Required SSN %4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    next->rec.data.stream_seq,
+					    chk->rec.data.TSN_seq,
+					    chk->rec.data.stream_number,
+					    chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_13;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1419,7 +1258,6 @@ sctp_does_tsn_belong_to_reasm(struct sctp_association *asoc,
 	return (0);
 }
 
-
 static int
 sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     struct mbuf **m, int offset, struct sctp_data_chunk *ch, int chk_length,
@@ -1434,7 +1272,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	int the_len;
 	int need_reasm_check = 0;
 	uint16_t strmno, strmseq;
-	struct mbuf *oper;
+	struct mbuf *op_err;
+	char msg[SCTP_DIAG_INFO_LEN];
 	struct sctp_queued_to_read *control;
 	int ordered;
 	uint32_t protocol_id;
@@ -1501,15 +1340,12 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	 */
 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
-	    (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET))
-	    ) {
+	    (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET))) {
 		/*
 		 * wait a minute, this guy is gone, there is no longer a
 		 * receiver. Send peer an ABORT!
 		 */
-		struct mbuf *op_err;
-
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+		op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 		*abort_flag = 1;
 		return (0);
@@ -1637,27 +1473,12 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		/* The incoming sseq is behind where we last delivered? */
 		SCTPDBG(SCTP_DEBUG_INDATA1, "EVIL/Broken-Dup S-SEQ:%d delivered:%d from peer, Abort!\n",
 		    strmseq, asoc->strmin[strmno].last_sequence_delivered);
-		oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-		    0, M_DONTWAIT, 1, MT_DATA);
-		if (oper) {
-			struct sctp_paramhdr *ph;
-			uint32_t *ippp;
-
-			SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-			    (3 * sizeof(uint32_t));
-			ph = mtod(oper, struct sctp_paramhdr *);
-			ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-			ph->param_length = htons(SCTP_BUF_LEN(oper));
-			ippp = (uint32_t *) (ph + 1);
-			*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_14);
-			ippp++;
-			*ippp = tsn;
-			ippp++;
-			*ippp = ((strmno << 16) | strmseq);
-
-		}
+		snprintf(msg, sizeof(msg), "Delivered SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+		    asoc->strmin[strmno].last_sequence_delivered,
+		    tsn, strmno, strmseq);
+		op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 		stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_14;
-		sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 		*abort_flag = 1;
 		return (0);
 	}
@@ -1791,7 +1612,6 @@ failed_express_del:
 				asoc->highest_tsn_inside_nr_map = tsn;
 			}
 			SCTP_STAT_INCR(sctps_recvexpressm);
-			control->sinfo_tsn = tsn;
 			asoc->tsn_last_delivered = tsn;
 			asoc->fragment_flags = chunk_flags;
 			asoc->tsn_of_pdapi_last_delivered = tsn;
@@ -1897,29 +1717,15 @@ failed_pdapi_express_del:
 					control->whoFrom = NULL;
 				}
 				sctp_free_a_readq(stcb, control);
-				oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-				    0, M_DONTWAIT, 1, MT_DATA);
-				if (oper) {
-					struct sctp_paramhdr *ph;
-					uint32_t *ippp;
-
-					SCTP_BUF_LEN(oper) =
-					    sizeof(struct sctp_paramhdr) +
-					    (3 * sizeof(uint32_t));
-					ph = mtod(oper, struct sctp_paramhdr *);
-					ph->param_type =
-					    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-					ph->param_length = htons(SCTP_BUF_LEN(oper));
-					ippp = (uint32_t *) (ph + 1);
-					*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_15);
-					ippp++;
-					*ippp = tsn;
-					ippp++;
-					*ippp = ((strmno << 16) | strmseq);
-				}
+				snprintf(msg, sizeof(msg), "Reas. queue emtpy, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+				    tsn, strmno, strmseq);
+				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_15;
-				sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 				*abort_flag = 1;
+				if (last_chunk) {
+					*m = NULL;
+				}
 				return (0);
 			} else {
 				if (sctp_does_tsn_belong_to_reasm(asoc, control->sinfo_tsn)) {
@@ -1930,32 +1736,15 @@ failed_pdapi_express_del:
 						control->whoFrom = NULL;
 					}
 					sctp_free_a_readq(stcb, control);
-
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_16);
-						ippp++;
-						*ippp = tsn;
-						ippp++;
-						*ippp = ((strmno << 16) | strmseq);
-					}
+					snprintf(msg, sizeof(msg), "PD ongoing, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    tsn, strmno, strmseq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_16;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
+					if (last_chunk) {
+						*m = NULL;
+					}
 					return (0);
 				}
 			}
@@ -1976,31 +1765,15 @@ failed_pdapi_express_del:
 						control->whoFrom = NULL;
 					}
 					sctp_free_a_readq(stcb, control);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_17);
-						ippp++;
-						*ippp = tsn;
-						ippp++;
-						*ippp = ((strmno << 16) | strmseq);
-					}
+					snprintf(msg, sizeof(msg), "No PD ongoing, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					    tsn, strmno, strmseq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_17;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
+					if (last_chunk) {
+						*m = NULL;
+					}
 					return (0);
 				}
 			}
@@ -2064,6 +1837,9 @@ failed_pdapi_express_del:
 			} else {
 				sctp_queue_data_to_stream(stcb, asoc, control, abort_flag);
 				if (*abort_flag) {
+					if (last_chunk) {
+						*m = NULL;
+					}
 					return (0);
 				}
 			}
@@ -2076,7 +1852,9 @@ failed_pdapi_express_del:
 			 * the assoc is now gone and chk was put onto the
 			 * reasm queue, which has all been freed.
 			 */
-			*m = NULL;
+			if (last_chunk) {
+				*m = NULL;
+			}
 			return (0);
 		}
 	}
@@ -2494,7 +2272,7 @@ doit_again:
 		 * delivery queue and something can be delivered.
 		 */
 		if (stcb->sctp_socket) {
-			pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket),
+			pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
 			    stcb->sctp_ep->partial_delivery_point);
 		} else {
 			pd_point = stcb->sctp_ep->partial_delivery_point;
@@ -2600,32 +2378,32 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
 			continue;
 		}
 		if (ch->ch.chunk_type == SCTP_DATA) {
-			if ((size_t)chk_length < sizeof(struct sctp_data_chunk) + 1) {
+			if ((size_t)chk_length < sizeof(struct sctp_data_chunk)) {
 				/*
 				 * Need to send an abort since we had a
 				 * invalid data chunk.
 				 */
 				struct mbuf *op_err;
+				char msg[SCTP_DIAG_INFO_LEN];
 
-				op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 2 * sizeof(uint32_t)),
-				    0, M_DONTWAIT, 1, MT_DATA);
-
-				if (op_err) {
-					struct sctp_paramhdr *ph;
-					uint32_t *ippp;
-
-					SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr) +
-					    (2 * sizeof(uint32_t));
-					ph = mtod(op_err, struct sctp_paramhdr *);
-					ph->param_type =
-					    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-					ph->param_length = htons(SCTP_BUF_LEN(op_err));
-					ippp = (uint32_t *) (ph + 1);
-					*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_19);
-					ippp++;
-					*ippp = asoc->cumulative_tsn;
+				snprintf(msg, sizeof(msg), "DATA chunk of length %d",
+				    chk_length);
+				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
+				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19;
+				sctp_abort_association(inp, stcb, m, iphlen,
+				    src, dst, sh, op_err,
+				    use_mflowid, mflowid,
+				    vrf_id, port);
+				return (2);
+			}
+			if ((size_t)chk_length == sizeof(struct sctp_data_chunk)) {
+				/*
+				 * Need to send an abort since we had an
+				 * empty data chunk.
+				 */
+				struct mbuf *op_err;
 
-				}
+				op_err = sctp_generate_no_user_data_cause(ch->dp.tsn);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19;
 				sctp_abort_association(inp, stcb, m, iphlen,
 				    src, dst, sh, op_err,
@@ -2693,7 +2471,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
 				if (SCTP_BASE_SYSCTL(sctp_strict_data_order)) {
 					struct mbuf *op_err;
 
-					op_err = sctp_generate_invmanparam(SCTP_CAUSE_PROTOCOL_VIOLATION);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, "");
 					sctp_abort_association(inp, stcb,
 					    m, iphlen,
 					    src, dst,
@@ -3842,7 +3620,8 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
 		}
 		if (SCTP_TSN_GE(cumack, send_s)) {
 #ifndef INVARIANTS
-			struct mbuf *oper;
+			struct mbuf *op_err;
+			char msg[SCTP_DIAG_INFO_LEN];
 
 #endif
 #ifdef INVARIANTS
@@ -3851,22 +3630,11 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
 
 			*abort_now = 1;
 			/* XXX */
-			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
-			    0, M_DONTWAIT, 1, MT_DATA);
-			if (oper) {
-				struct sctp_paramhdr *ph;
-				uint32_t *ippp;
-
-				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-				    sizeof(uint32_t);
-				ph = mtod(oper, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-				ph->param_length = htons(SCTP_BUF_LEN(oper));
-				ippp = (uint32_t *) (ph + 1);
-				*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
-			}
+			snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal then TSN %8.8x",
+			    cumack, send_s);
+			op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
-			sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+			sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 			return;
 #endif
 		}
@@ -4216,23 +3984,14 @@ again:
 		    (asoc->stream_queue_cnt == 0)) {
 			if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
 				/* Need to abort here */
-				struct mbuf *oper;
+				struct mbuf *op_err;
 
 		abort_out_now:
 				*abort_now = 1;
 				/* XXX */
-				oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-				    0, M_DONTWAIT, 1, MT_DATA);
-				if (oper) {
-					struct sctp_paramhdr *ph;
-
-					SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr);
-					ph = mtod(oper, struct sctp_paramhdr *);
-					ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-					ph->param_length = htons(SCTP_BUF_LEN(oper));
-				}
+				op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_24;
-				sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 			} else {
 				struct sctp_nets *netp;
 
@@ -4425,7 +4184,8 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
 			send_s = asoc->sending_seq;
 		}
 		if (SCTP_TSN_GE(cum_ack, send_s)) {
-			struct mbuf *oper;
+			struct mbuf *op_err;
+			char msg[SCTP_DIAG_INFO_LEN];
 
 			/*
 			 * no way, we have not even sent this TSN out yet.
@@ -4440,22 +4200,11 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
 	hopeless_peer:
 			*abort_now = 1;
 			/* XXX */
-			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
-			    0, M_DONTWAIT, 1, MT_DATA);
-			if (oper) {
-				struct sctp_paramhdr *ph;
-				uint32_t *ippp;
-
-				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-				    sizeof(uint32_t);
-				ph = mtod(oper, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-				ph->param_length = htons(SCTP_BUF_LEN(oper));
-				ippp = (uint32_t *) (ph + 1);
-				*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
-			}
+			snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal then TSN %8.8x",
+			    cum_ack, send_s);
+			op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
-			sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+			sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 			return;
 		}
 	}
@@ -4721,7 +4470,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
 			}
 		}
 		TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
-		if (tp1->pr_sctp_on) {
+		if (PR_SCTP_ENABLED(tp1->flags)) {
 			if (asoc->pr_sctp_cnt != 0)
 				asoc->pr_sctp_cnt--;
 		}
@@ -4944,23 +4693,14 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
 		    (asoc->stream_queue_cnt == 0)) {
 			if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
 				/* Need to abort here */
-				struct mbuf *oper;
+				struct mbuf *op_err;
 
 		abort_out_now:
 				*abort_now = 1;
 				/* XXX */
-				oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-				    0, M_DONTWAIT, 1, MT_DATA);
-				if (oper) {
-					struct sctp_paramhdr *ph;
-
-					SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr);
-					ph = mtod(oper, struct sctp_paramhdr *);
-					ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-					ph->param_length = htons(SCTP_BUF_LEN(oper));
-				}
+				op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_31;
-				sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 				return;
 			} else {
 				struct sctp_nets *netp;
@@ -5389,33 +5129,20 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
 	asoc->cumulative_tsn = new_cum_tsn;
 	if (gap >= m_size) {
 		if ((long)gap > sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv)) {
-			struct mbuf *oper;
+			struct mbuf *op_err;
+			char msg[SCTP_DIAG_INFO_LEN];
 
 			/*
 			 * out of range (of single byte chunks in the rwnd I
 			 * give out). This must be an attacker.
 			 */
 			*abort_flag = 1;
-			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-			    0, M_DONTWAIT, 1, MT_DATA);
-			if (oper) {
-				struct sctp_paramhdr *ph;
-				uint32_t *ippp;
-
-				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-				    (sizeof(uint32_t) * 3);
-				ph = mtod(oper, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-				ph->param_length = htons(SCTP_BUF_LEN(oper));
-				ippp = (uint32_t *) (ph + 1);
-				*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_33);
-				ippp++;
-				*ippp = asoc->highest_tsn_inside_map;
-				ippp++;
-				*ippp = new_cum_tsn;
-			}
+			snprintf(msg, sizeof(msg),
+			    "New cum ack %8.8x too high, highest TSN %8.8x",
+			    new_cum_tsn, asoc->highest_tsn_inside_map);
+			op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_33;
-			sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+			sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 			return;
 		}
 		SCTP_STAT_INCR(sctps_fwdtsn_map_over);
diff --git a/freebsd/sys/netinet/sctp_input.c b/freebsd/sys/netinet/sctp_input.c
index 7cdb5b0..baf25af 100644
--- a/freebsd/sys/netinet/sctp_input.c
+++ b/freebsd/sys/netinet/sctp_input.c
@@ -99,7 +99,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
 	}
 	/* validate length */
 	if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) {
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 		    use_mflowid, mflowid,
 		    vrf_id, port);
@@ -111,7 +111,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
 	init = &cp->init;
 	if (init->initiate_tag == 0) {
 		/* protocol error... send abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 		    use_mflowid, mflowid,
 		    vrf_id, port);
@@ -121,7 +121,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
 	}
 	if (ntohl(init->a_rwnd) < SCTP_MIN_RWND) {
 		/* invalid parameter... send abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 		    use_mflowid, mflowid,
 		    vrf_id, port);
@@ -131,7 +131,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
 	}
 	if (init->num_inbound_streams == 0) {
 		/* protocol error... send abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 		    use_mflowid, mflowid,
 		    vrf_id, port);
@@ -141,7 +141,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
 	}
 	if (init->num_outbound_streams == 0) {
 		/* protocol error... send abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 		    use_mflowid, mflowid,
 		    vrf_id, port);
@@ -152,7 +152,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
 	if (sctp_validate_init_auth_params(m, offset + sizeof(*cp),
 	    offset + ntohs(cp->ch.chunk_length))) {
 		/* auth parameter(s) error... send abort */
-		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, NULL,
+		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+		    "Problem with AUTH parameters");
+		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 		    use_mflowid, mflowid,
 		    vrf_id, port);
 		if (stcb)
@@ -181,7 +183,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
 		 * state :-)
 		 */
 		if (SCTP_BASE_SYSCTL(sctp_blackhole) == 0) {
-			sctp_send_abort(m, iphlen, src, dst, sh, 0, NULL,
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			    "No listener");
+			sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
 			    use_mflowid, mflowid,
 			    vrf_id, port);
 		}
@@ -441,7 +445,6 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
 
 	/* First verify that we have no illegal param's */
 	abort_flag = 0;
-	op_err = NULL;
 
 	op_err = sctp_arethere_unrecognized_parameters(m,
 	    (offset + sizeof(struct sctp_init_chunk)),
@@ -464,12 +467,13 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
 	if ((retval = sctp_load_addresses_from_init(stcb, m,
 	    (offset + sizeof(struct sctp_init_chunk)), initack_limit,
 	    src, dst, NULL))) {
-		/* Huh, we should abort */
+		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+		    "Problem with address parameters");
 		SCTPDBG(SCTP_DEBUG_INPUT1,
 		    "Load addresses from INIT causes an abort %d\n",
 		    retval);
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
-		    src, dst, sh, NULL,
+		    src, dst, sh, op_err,
 		    use_mflowid, mflowid,
 		    vrf_id, net->port);
 		*abort_no_unlock = 1;
@@ -524,8 +528,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
 		 */
 		if (retval == -3) {
 			/* We abort with an error of missing mandatory param */
-			op_err =
-			    sctp_generate_invmanparam(SCTP_CAUSE_MISSING_PARAM);
+			op_err = sctp_generate_cause(SCTP_CAUSE_MISSING_PARAM, "");
 			if (op_err) {
 				/*
 				 * Expand beyond to include the mandatory
@@ -1308,7 +1311,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
 	}
 	if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_ack_chunk)) {
 		/* Invalid length */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
 		    src, dst, sh, op_err,
 		    use_mflowid, mflowid,
@@ -1320,7 +1323,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
 	/* validate parameters */
 	if (init_ack->initiate_tag == 0) {
 		/* protocol error... send an abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
 		    src, dst, sh, op_err,
 		    use_mflowid, mflowid,
@@ -1330,7 +1333,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
 	}
 	if (ntohl(init_ack->a_rwnd) < SCTP_MIN_RWND) {
 		/* protocol error... send an abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
 		    src, dst, sh, op_err,
 		    use_mflowid, mflowid,
@@ -1340,7 +1343,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
 	}
 	if (init_ack->num_inbound_streams == 0) {
 		/* protocol error... send an abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
 		    src, dst, sh, op_err,
 		    use_mflowid, mflowid,
@@ -1350,7 +1353,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
 	}
 	if (init_ack->num_outbound_streams == 0) {
 		/* protocol error... send an abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
 		    src, dst, sh, op_err,
 		    use_mflowid, mflowid,
@@ -1460,7 +1463,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 	struct sctp_init_ack_chunk *initack_cp, initack_buf;
 	struct sctp_nets *net;
 	struct mbuf *op_err;
-	struct sctp_paramhdr *ph;
 	int init_offset, initack_offset, i;
 	int retval;
 	int spec_flag = 0;
@@ -1479,17 +1481,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 	if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
 		/* SHUTDOWN came in after sending INIT-ACK */
 		sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination);
-		op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-		    0, M_DONTWAIT, 1, MT_DATA);
-		if (op_err == NULL) {
-			/* FOOBAR */
-			return (NULL);
-		}
-		/* Set the len */
-		SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-		ph = mtod(op_err, struct sctp_paramhdr *);
-		ph->param_type = htons(SCTP_CAUSE_COOKIE_IN_SHUTDOWN);
-		ph->param_length = htons(sizeof(struct sctp_paramhdr));
+		op_err = sctp_generate_cause(SCTP_CAUSE_COOKIE_IN_SHUTDOWN, "");
 		sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
 		    use_mflowid, mflowid,
 		    vrf_id, net->port);
@@ -1555,8 +1547,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 			return (NULL);
 
 		}
-		switch SCTP_GET_STATE
-			(asoc) {
+		switch (SCTP_GET_STATE(asoc)) {
 		case SCTP_STATE_COOKIE_WAIT:
 		case SCTP_STATE_COOKIE_ECHOED:
 			/*
@@ -1646,7 +1637,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 			 * have simply lost the COOKIE-ACK
 			 */
 			break;
-			}	/* end switch */
+		}		/* end switch */
 		sctp_stop_all_cookie_timers(stcb);
 		/*
 		 * We ignore the return code here.. not sure if we should
@@ -1697,25 +1688,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 		 * Now we have colliding state. We must send an abort here
 		 * with colliding state indication.
 		 */
-		op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-		    0, M_DONTWAIT, 1, MT_DATA);
-		if (op_err == NULL) {
-			/* FOOBAR */
-			return (NULL);
-		}
-		/* pre-reserve some space */
-#ifdef INET6
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
-		/* Set the len */
-		SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-		ph = mtod(op_err, struct sctp_paramhdr *);
-		ph->param_type = htons(SCTP_CAUSE_NAT_COLLIDING_STATE);
-		ph->param_length = htons(sizeof(struct sctp_paramhdr));
+		op_err = sctp_generate_cause(SCTP_CAUSE_NAT_COLLIDING_STATE, "");
 		sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
 		    use_mflowid, mflowid,
 		    vrf_id, port);
@@ -2128,8 +2101,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
 		/* memory problem? */
 		SCTPDBG(SCTP_DEBUG_INPUT1,
 		    "process_cookie_new: no room for another TCB!\n");
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
-
+		op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 		sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
 		    src, dst, sh, op_err,
 		    use_mflowid, mflowid,
@@ -2157,7 +2129,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
 		 * association.
 		 */
 		atomic_add_int(&stcb->asoc.refcnt, 1);
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+		op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 		sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
 		    src, dst, sh, op_err,
 		    use_mflowid, mflowid,
@@ -2776,7 +2748,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
 #endif
 				/* Too many sockets */
 				SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another socket!\n");
-				op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+				op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 				sctp_abort_association(*inp_p, NULL, m, iphlen,
 				    src, dst, sh, op_err,
 				    use_mflowid, mflowid,
@@ -4398,6 +4370,8 @@ __attribute__((noinline))
              uint32_t vrf_id, uint16_t port)
 {
 	struct sctp_association *asoc;
+	struct mbuf *op_err;
+	char msg[SCTP_DIAG_INFO_LEN];
 	uint32_t vtag_in;
 	int num_chunks = 0;	/* number of control chunks processed */
 	uint32_t chk_length;
@@ -4551,8 +4525,11 @@ __attribute__((noinline))
 			}
 		}
 		if (stcb == NULL) {
+			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			    msg);
 			/* no association, so it's out of the blue... */
-			sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp,
+			sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, op_err,
 			    use_mflowid, mflowid,
 			    vrf_id, port);
 			*offset = length;
@@ -4592,8 +4569,11 @@ __attribute__((noinline))
 				if (locked_tcb) {
 					SCTP_TCB_UNLOCK(locked_tcb);
 				}
+				snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+				    msg);
 				sctp_handle_ootb(m, iphlen, *offset, src, dst,
-				    sh, inp,
+				    sh, inp, op_err,
 				    use_mflowid, mflowid,
 				    vrf_id, port);
 				return (NULL);
@@ -4735,8 +4715,10 @@ process_control_chunks:
 			/* The INIT chunk must be the only chunk. */
 			if ((num_chunks > 1) ||
 			    (length - *offset > (int)SCTP_SIZE32(chk_length))) {
+				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+				    "INIT not the only chunk");
 				sctp_abort_association(inp, stcb, m, iphlen,
-				    src, dst, sh, NULL,
+				    src, dst, sh, op_err,
 				    use_mflowid, mflowid,
 				    vrf_id, port);
 				*offset = length;
@@ -4744,9 +4726,7 @@ process_control_chunks:
 			}
 			/* Honor our resource limit. */
 			if (chk_length > SCTP_LARGEST_INIT_ACCEPTED) {
-				struct mbuf *op_err;
-
-				op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+				op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 				sctp_abort_association(inp, stcb, m, iphlen,
 				    src, dst, sh, op_err,
 				    use_mflowid, mflowid,
@@ -5114,9 +5094,7 @@ process_control_chunks:
 			if ((stcb == NULL) && (inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) {
 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
 				    (SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit))) {
-					struct mbuf *op_err;
-
-					op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+					op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 					sctp_abort_association(inp, stcb, m, iphlen,
 					    src, dst, sh, op_err,
 					    use_mflowid, mflowid,
@@ -5601,7 +5579,8 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
 {
 	uint32_t high_tsn;
 	int fwd_tsn_seen = 0, data_processed = 0;
-	struct mbuf *m = *mm;
+	struct mbuf *m = *mm, *op_err;
+	char msg[SCTP_DIAG_INFO_LEN];
 	int un_sent;
 	int cnt_ctrl_ready = 0;
 	struct sctp_inpcb *inp = NULL, *inp_decr = NULL;
@@ -5687,8 +5666,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
 			if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
 			    ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
 			    (ch->chunk_type != SCTP_INIT))) {
+				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+				    "Out of the blue");
 				sctp_send_abort(m, iphlen, src, dst,
-				    sh, 0, NULL,
+				    sh, 0, op_err,
 				    use_mflowid, mflowid,
 				    vrf_id, port);
 			}
@@ -5746,7 +5727,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
 			 */
 			SCTP_TCB_UNLOCK(stcb);
 			stcb = NULL;
-			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
+			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			    msg);
+			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
 			    use_mflowid, mflowid,
 			    vrf_id, port);
 			goto out;
@@ -5793,7 +5777,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
 		}
 		if (stcb == NULL) {
 			/* out of the blue DATA chunk */
-			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
+			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			    msg);
+			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
 			    use_mflowid, mflowid,
 			    vrf_id, port);
 			goto out;
@@ -5862,7 +5849,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
 			/*
 			 * We consider OOTB any data sent during asoc setup.
 			 */
-			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
+			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			    msg);
+			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
 			    use_mflowid, mflowid,
 			    vrf_id, port);
 			goto out;
diff --git a/freebsd/sys/netinet/sctp_os_bsd.h b/freebsd/sys/netinet/sctp_os_bsd.h
index ca4be70..d33d1fd 100644
--- a/freebsd/sys/netinet/sctp_os_bsd.h
+++ b/freebsd/sys/netinet/sctp_os_bsd.h
@@ -104,6 +104,9 @@ __FBSDID("$FreeBSD$");
 
 #include <netinet/ip_options.h>
 
+#include <crypto/sha1.h>
+#include <crypto/sha2/sha2.h>
+
 #ifndef in6pcb
 #define in6pcb		inpcb
 #endif
@@ -461,23 +464,18 @@ sctp_get_mbuf_for_msg(unsigned int space_needed,
 /*
  * SCTP AUTH
  */
-#define HAVE_SHA2
-
 #define SCTP_READ_RANDOM(buf, len)	read_random(buf, len)
 
-#ifdef USE_SCTP_SHA1
-#include <netinet/sctp_sha1.h>
-#else
-#include <crypto/sha1.h>
 /* map standard crypto API names */
-#define SHA1_Init	SHA1Init
-#define SHA1_Update	SHA1Update
-#define SHA1_Final(x,y)	SHA1Final((caddr_t)x, y)
-#endif
-
-#if defined(HAVE_SHA2)
-#include <crypto/sha2/sha2.h>
-#endif
+#define SCTP_SHA1_CTX		SHA1_CTX
+#define SCTP_SHA1_INIT		SHA1Init
+#define SCTP_SHA1_UPDATE	SHA1Update
+#define SCTP_SHA1_FINAL(x,y)	SHA1Final((caddr_t)x, y)
+
+#define SCTP_SHA256_CTX		SHA256_CTX
+#define SCTP_SHA256_INIT	SHA256_Init
+#define SCTP_SHA256_UPDATE	SHA256_Update
+#define SCTP_SHA256_FINAL(x,y)	SHA256_Final((caddr_t)x, y)
 
 #endif
 
diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c
index 61260fb..f3cb4b4 100644
--- a/freebsd/sys/netinet/sctp_output.c
+++ b/freebsd/sys/netinet/sctp_output.c
@@ -1939,10 +1939,13 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
 static struct mbuf *
 sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t * len)
 {
+#if defined(INET) || defined(INET6)
 	struct sctp_paramhdr *parmh;
 	struct mbuf *mret;
 	uint16_t plen;
 
+#endif
+
 	switch (ifa->address.sa.sa_family) {
 #ifdef INET
 	case AF_INET:
@@ -1957,6 +1960,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t * len)
 	default:
 		return (m);
 	}
+#if defined(INET) || defined(INET6)
 	if (M_TRAILINGSPACE(m) >= plen) {
 		/* easy side we just drop it on the end */
 		parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m)));
@@ -2017,6 +2021,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t * len)
 		*len += plen;
 	}
 	return (mret);
+#endif
 }
 
 
@@ -2057,6 +2062,20 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 				continue;
 			}
 			LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
+#ifdef INET
+				if ((sctp_ifap->address.sa.sa_family == AF_INET) &&
+				    (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+				    &sctp_ifap->address.sin.sin_addr) != 0)) {
+					continue;
+				}
+#endif
+#ifdef INET6
+				if ((sctp_ifap->address.sa.sa_family == AF_INET6) &&
+				    (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+				    &sctp_ifap->address.sin6.sin6_addr) != 0)) {
+					continue;
+				}
+#endif
 				if (sctp_is_addr_restricted(stcb, sctp_ifap)) {
 					continue;
 				}
@@ -2086,6 +2105,20 @@ skip_count:
 					continue;
 				}
 				LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
+#ifdef INET
+					if ((sctp_ifap->address.sa.sa_family == AF_INET) &&
+					    (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+					    &sctp_ifap->address.sin.sin_addr) != 0)) {
+						continue;
+					}
+#endif
+#ifdef INET6
+					if ((sctp_ifap->address.sa.sa_family == AF_INET6) &&
+					    (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+					    &sctp_ifap->address.sin6.sin6_addr) != 0)) {
+						continue;
+					}
+#endif
 					if (sctp_is_addr_restricted(stcb, sctp_ifap)) {
 						continue;
 					}
@@ -2450,6 +2483,20 @@ sctp_choose_boundspecific_inp(struct sctp_inpcb *inp,
 	if (sctp_ifn) {
 		/* is a preferred one on the interface we route out? */
 		LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
+#ifdef INET
+			if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+			    (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+			    &sctp_ifa->address.sin.sin_addr) != 0)) {
+				continue;
+			}
+#endif
+#ifdef INET6
+			if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+			    (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+			    &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+				continue;
+			}
+#endif
 			if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
 			    (non_asoc_addr_ok == 0))
 				continue;
@@ -2573,6 +2620,20 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
 	if (sctp_ifn) {
 		/* first try for a preferred address on the ep */
 		LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
+#ifdef INET
+			if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+			    (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+			    &sctp_ifa->address.sin.sin_addr) != 0)) {
+				continue;
+			}
+#endif
+#ifdef INET6
+			if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+			    (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+			    &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+				continue;
+			}
+#endif
 			if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
 				continue;
 			if (sctp_is_addr_in_ep(inp, sctp_ifa)) {
@@ -2593,6 +2654,20 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
 		}
 		/* next try for an acceptable address on the ep */
 		LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
+#ifdef INET
+			if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+			    (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+			    &sctp_ifa->address.sin.sin_addr) != 0)) {
+				continue;
+			}
+#endif
+#ifdef INET6
+			if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+			    (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+			    &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+				continue;
+			}
+#endif
 			if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
 				continue;
 			if (sctp_is_addr_in_ep(inp, sctp_ifa)) {
@@ -2697,6 +2772,7 @@ sctp_from_the_top2:
 
 static struct sctp_ifa *
 sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
+    struct sctp_inpcb *inp,
     struct sctp_tcb *stcb,
     int non_asoc_addr_ok,
     uint8_t dest_is_loop,
@@ -2718,6 +2794,20 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
 	}
 #endif				/* INET6 */
 	LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) {
+#ifdef INET
+		if ((ifa->address.sa.sa_family == AF_INET) &&
+		    (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+		    &ifa->address.sin.sin_addr) != 0)) {
+			continue;
+		}
+#endif
+#ifdef INET6
+		if ((ifa->address.sa.sa_family == AF_INET6) &&
+		    (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+		    &ifa->address.sin6.sin6_addr) != 0)) {
+			continue;
+		}
+#endif
 		if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
 		    (non_asoc_addr_ok == 0))
 			continue;
@@ -2803,6 +2893,7 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
 
 static int
 sctp_count_num_preferred_boundall(struct sctp_ifn *ifn,
+    struct sctp_inpcb *inp,
     struct sctp_tcb *stcb,
     int non_asoc_addr_ok,
     uint8_t dest_is_loop,
@@ -2813,6 +2904,21 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn,
 	int num_eligible_addr = 0;
 
 	LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) {
+#ifdef INET
+		if ((ifa->address.sa.sa_family == AF_INET) &&
+		    (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+		    &ifa->address.sin.sin_addr) != 0)) {
+			continue;
+		}
+#endif
+#ifdef INET6
+		if ((ifa->address.sa.sa_family == AF_INET6) &&
+		    (stcb != NULL) &&
+		    (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+		    &ifa->address.sin6.sin6_addr) != 0)) {
+			continue;
+		}
+#endif
 		if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
 		    (non_asoc_addr_ok == 0)) {
 			continue;
@@ -2844,7 +2950,8 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn,
 }
 
 static struct sctp_ifa *
-sctp_choose_boundall(struct sctp_tcb *stcb,
+sctp_choose_boundall(struct sctp_inpcb *inp,
+    struct sctp_tcb *stcb,
     struct sctp_nets *net,
     sctp_route_t * ro,
     uint32_t vrf_id,
@@ -2899,7 +3006,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb,
 		cur_addr_num = net->indx_of_eligible_next_to_use;
 	}
 	num_preferred = sctp_count_num_preferred_boundall(sctp_ifn,
-	    stcb,
+	    inp, stcb,
 	    non_asoc_addr_ok,
 	    dest_is_loop,
 	    dest_is_priv, fam);
@@ -2926,7 +3033,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb,
 	 */
 	SCTPDBG(SCTP_DEBUG_OUTPUT2, "cur_addr_num:%d\n", cur_addr_num);
 
-	sctp_ifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop,
+	sctp_ifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop,
 	    dest_is_priv, cur_addr_num, fam, ro);
 
 	/* if sctp_ifa is NULL something changed??, fall to plan b. */
@@ -2957,7 +3064,7 @@ bound_all_plan_b:
 			SCTPDBG(SCTP_DEBUG_OUTPUT2, "already seen\n");
 			continue;
 		}
-		num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, stcb, non_asoc_addr_ok,
+		num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok,
 		    dest_is_loop, dest_is_priv, fam);
 		SCTPDBG(SCTP_DEBUG_OUTPUT2,
 		    "Found ifn:%p %d preferred source addresses\n",
@@ -2979,7 +3086,7 @@ bound_all_plan_b:
 		if (cur_addr_num >= num_preferred) {
 			cur_addr_num = 0;
 		}
-		sifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop,
+		sifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop,
 		    dest_is_priv, cur_addr_num, fam, ro);
 		if (sifa == NULL)
 			continue;
@@ -3007,6 +3114,22 @@ again_with_private_addresses_allowed:
 	}
 	LIST_FOREACH(sctp_ifa, &emit_ifn->ifalist, next_ifa) {
 		SCTPDBG(SCTP_DEBUG_OUTPUT2, "ifa:%p\n", (void *)sctp_ifa);
+#ifdef INET
+		if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+		    (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+		    &sctp_ifa->address.sin.sin_addr) != 0)) {
+			SCTPDBG(SCTP_DEBUG_OUTPUT2, "Jailed\n");
+			continue;
+		}
+#endif
+#ifdef INET6
+		if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+		    (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+		    &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+			SCTPDBG(SCTP_DEBUG_OUTPUT2, "Jailed\n");
+			continue;
+		}
+#endif
 		if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
 		    (non_asoc_addr_ok == 0)) {
 			SCTPDBG(SCTP_DEBUG_OUTPUT2, "Defer\n");
@@ -3057,6 +3180,20 @@ plan_d:
 			continue;
 		}
 		LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
+#ifdef INET
+			if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+			    (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+			    &sctp_ifa->address.sin.sin_addr) != 0)) {
+				continue;
+			}
+#endif
+#ifdef INET6
+			if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+			    (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+			    &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+				continue;
+			}
+#endif
 			if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
 			    (non_asoc_addr_ok == 0))
 				continue;
@@ -3107,6 +3244,20 @@ out:
 				LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
 					struct sctp_ifa *tmp_sifa;
 
+#ifdef INET
+					if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
+					    (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+					    &sctp_ifa->address.sin.sin_addr) != 0)) {
+						continue;
+					}
+#endif
+#ifdef INET6
+					if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
+					    (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+					    &sctp_ifa->address.sin6.sin6_addr) != 0)) {
+						continue;
+					}
+#endif
 					if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) &&
 					    (non_asoc_addr_ok == 0))
 						continue;
@@ -3292,7 +3443,7 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
 		/*
 		 * Bound all case
 		 */
-		answer = sctp_choose_boundall(stcb, net, ro, vrf_id,
+		answer = sctp_choose_boundall(inp, stcb, net, ro, vrf_id,
 		    dest_is_priv, dest_is_loop,
 		    non_asoc_addr_ok, fam);
 		SCTP_IPI_ADDR_RUNLOCK();
@@ -3386,7 +3537,11 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
 						return (found);
 					}
 					m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_prinfo), (caddr_t)&prinfo);
-					sndrcvinfo->sinfo_timetolive = prinfo.pr_value;
+					if (prinfo.pr_policy != SCTP_PR_SCTP_NONE) {
+						sndrcvinfo->sinfo_timetolive = prinfo.pr_value;
+					} else {
+						sndrcvinfo->sinfo_timetolive = 0;
+					}
 					sndrcvinfo->sinfo_flags |= prinfo.pr_policy;
 					break;
 				case SCTP_AUTHINFO:
@@ -3563,7 +3718,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
 
 static struct sctp_tcb *
 sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
-    in_port_t port,
+    uint16_t port,
     struct mbuf *control,
     struct sctp_nets **net_p,
     int *error)
@@ -3664,7 +3819,6 @@ sctp_add_cookie(struct mbuf *init, int init_offset,
 	int sig_offset;
 	uint16_t cookie_sz;
 
-	mret = NULL;
 	mret = sctp_get_mbuf_for_msg((sizeof(struct sctp_state_cookie) +
 	    sizeof(struct sctp_paramhdr)), 0,
 	    M_DONTWAIT, 1, MT_DATA);
@@ -3857,8 +4011,11 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 	struct sctphdr *sctphdr;
 	int packet_length;
 	int ret;
+
+#if defined(INET) || defined(INET6)
 	uint32_t vrf_id;
 
+#endif
 #if defined(INET) || defined(INET6)
 	struct mbuf *o_pak;
 	sctp_route_t *ro = NULL;
@@ -3877,12 +4034,13 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 		sctp_m_freem(m);
 		return (EFAULT);
 	}
+#if defined(INET) || defined(INET6)
 	if (stcb) {
 		vrf_id = stcb->asoc.vrf_id;
 	} else {
 		vrf_id = inp->def_vrf_id;
 	}
-
+#endif
 	/* fill in the HMAC digest for any AUTH chunk in the packet */
 	if ((auth != NULL) && (stcb != NULL)) {
 		sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb, auth_keyid);
@@ -4098,7 +4256,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 				SCTP_STAT_INCR(sctps_sendnocrc);
 #else
 				m->m_pkthdr.csum_flags = CSUM_SCTP;
-				m->m_pkthdr.csum_data = 0;
+				m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
 				SCTP_STAT_INCR(sctps_sendhwcrc);
 #endif
 			}
@@ -4447,7 +4605,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 				SCTP_STAT_INCR(sctps_sendnocrc);
 #else
 				m->m_pkthdr.csum_flags = CSUM_SCTP_IPV6;
-				m->m_pkthdr.csum_data = 0;
+				m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
 				SCTP_STAT_INCR(sctps_sendhwcrc);
 #endif
 			}
@@ -4545,11 +4703,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
 	struct mbuf *m;
 	struct sctp_nets *net;
 	struct sctp_init_chunk *init;
-
-#if defined(INET) || defined(INET6)
 	struct sctp_supported_addr_param *sup_addr;
-
-#endif
 	struct sctp_adaptation_layer_indication *ali;
 	struct sctp_supported_chunk_types_param *pr_supported;
 	struct sctp_paramhdr *ph;
@@ -5386,7 +5540,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 		 * though we even set the T bit and copy in the 0 tag.. this
 		 * looks no different than if no listener was present.
 		 */
-		sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, NULL,
+		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+		    "Address added");
+		sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, op_err,
 		    use_mflowid, mflowid,
 		    vrf_id, port);
 		return;
@@ -5397,6 +5553,13 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 	    &abort_flag, (struct sctp_chunkhdr *)init_chk, &nat_friendly);
 	if (abort_flag) {
 do_a_abort:
+		if (op_err == NULL) {
+			char msg[SCTP_DIAG_INFO_LEN];
+
+			snprintf(msg, sizeof(msg), "%s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			    msg);
+		}
 		sctp_send_abort(init_pkt, iphlen, src, dst, sh,
 		    init_chk->init.initiate_tag, op_err,
 		    use_mflowid, mflowid,
@@ -6073,17 +6236,15 @@ sctp_get_frag_point(struct sctp_tcb *stcb,
 static void
 sctp_set_prsctp_policy(struct sctp_stream_queue_pending *sp)
 {
-	sp->pr_sctp_on = 0;
 	/*
 	 * We assume that the user wants PR_SCTP_TTL if the user provides a
-	 * positive lifetime but does not specify any PR_SCTP policy. This
-	 * is a BAD assumption and causes problems at least with the
-	 * U-Vancovers MPI folks. I will change this to be no policy means
-	 * NO PR-SCTP.
+	 * positive lifetime but does not specify any PR_SCTP policy.
 	 */
 	if (PR_SCTP_ENABLED(sp->sinfo_flags)) {
 		sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags);
-		sp->pr_sctp_on = 1;
+	} else if (sp->timetolive > 0) {
+		sp->sinfo_flags |= SCTP_PR_SCTP_TTL;
+		sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags);
 	} else {
 		return;
 	}
@@ -6420,7 +6581,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
 		/* TSNH */
 		return;
 	}
-	if ((ca->m) && ca->sndlen) {
+	if (ca->sndlen > 0) {
 		m = SCTP_M_COPYM(ca->m, 0, M_COPYALL, M_DONTWAIT);
 		if (m == NULL) {
 			/* can't copy so we are done */
@@ -6449,38 +6610,40 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
 	}
 	if (ca->sndrcv.sinfo_flags & SCTP_ABORT) {
 		/* Abort this assoc with m as the user defined reason */
-		if (m) {
+		if (m != NULL) {
+			SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT);
+		} else {
+			m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
+			    0, M_NOWAIT, 1, MT_DATA);
+			SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
+		}
+		if (m != NULL) {
 			struct sctp_paramhdr *ph;
 
-			SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_DONTWAIT);
-			if (m) {
-				ph = mtod(m, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-				ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen);
-			}
-			/*
-			 * We add one here to keep the assoc from
-			 * dis-appearing on us.
-			 */
-			atomic_add_int(&stcb->asoc.refcnt, 1);
-			sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED);
-			/*
-			 * sctp_abort_an_association calls sctp_free_asoc()
-			 * free association will NOT free it since we
-			 * incremented the refcnt .. we do this to prevent
-			 * it being freed and things getting tricky since we
-			 * could end up (from free_asoc) calling inpcb_free
-			 * which would get a recursive lock call to the
-			 * iterator lock.. But as a consequence of that the
-			 * stcb will return to us un-locked.. since
-			 * free_asoc returns with either no TCB or the TCB
-			 * unlocked, we must relock.. to unlock in the
-			 * iterator timer :-0
-			 */
-			SCTP_TCB_LOCK(stcb);
-			atomic_add_int(&stcb->asoc.refcnt, -1);
-			goto no_chunk_output;
+			ph = mtod(m, struct sctp_paramhdr *);
+			ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
+			ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen);
 		}
+		/*
+		 * We add one here to keep the assoc from dis-appearing on
+		 * us.
+		 */
+		atomic_add_int(&stcb->asoc.refcnt, 1);
+		sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED);
+		/*
+		 * sctp_abort_an_association calls sctp_free_asoc() free
+		 * association will NOT free it since we incremented the
+		 * refcnt .. we do this to prevent it being freed and things
+		 * getting tricky since we could end up (from free_asoc)
+		 * calling inpcb_free which would get a recursive lock call
+		 * to the iterator lock.. But as a consequence of that the
+		 * stcb will return to us un-locked.. since free_asoc
+		 * returns with either no TCB or the TCB unlocked, we must
+		 * relock.. to unlock in the iterator timer :-0
+		 */
+		SCTP_TCB_LOCK(stcb);
+		atomic_add_int(&stcb->asoc.refcnt, -1);
+		goto no_chunk_output;
 	} else {
 		if (m) {
 			ret = sctp_msg_append(stcb, net, m,
@@ -6574,8 +6737,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
 
 	if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) &&
 	    (stcb->asoc.total_flight > 0) &&
-	    (un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))
-	    ) {
+	    (un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))) {
 		do_chunk_output = 0;
 	}
 	if (do_chunk_output)
@@ -6704,13 +6866,10 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
 		/* Gather the length of the send */
 		struct mbuf *mat;
 
-		mat = m;
 		ca->sndlen = 0;
-		while (m) {
-			ca->sndlen += SCTP_BUF_LEN(m);
-			m = SCTP_BUF_NEXT(m);
+		for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
+			ca->sndlen += SCTP_BUF_LEN(mat);
 		}
-		ca->m = mat;
 	}
 	ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL,
 	    SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES,
@@ -7356,7 +7515,8 @@ dont_do_it:
 	chk->pad_inplace = 0;
 	chk->no_fr_allowed = 0;
 	chk->rec.data.stream_seq = strq->next_sequence_send;
-	if (rcv_flags & SCTP_DATA_LAST_FRAG) {
+	if ((rcv_flags & SCTP_DATA_LAST_FRAG) &&
+	    !(rcv_flags & SCTP_DATA_UNORDERED)) {
 		strq->next_sequence_send++;
 	}
 	chk->rec.data.stream_number = sp->stream;
@@ -7431,13 +7591,8 @@ dont_do_it:
 		}
 		chk->send_size += pads;
 	}
-	/* We only re-set the policy if it is on */
-	if (sp->pr_sctp_on) {
-		sctp_set_prsctp_policy(sp);
+	if (PR_SCTP_ENABLED(chk->flags)) {
 		asoc->pr_sctp_cnt++;
-		chk->pr_sctp_on = 1;
-	} else {
-		chk->pr_sctp_on = 0;
 	}
 	if (sp->msg_is_complete && (sp->length == 0) && (sp->sender_all_done)) {
 		/* All done pull and kill the message */
@@ -7627,7 +7782,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
 #endif
 )
 {
-	/*
+	/**
 	 * Ok this is the generic chunk service queue. we must do the
 	 * following: - Service the stream queue that is next, moving any
 	 * message (note I must get a complete message i.e. FIRST/MIDDLE and
@@ -8962,7 +9117,6 @@ sctp_send_cookie_ack(struct sctp_tcb *stcb)
 	struct sctp_chunkhdr *hdr;
 	struct sctp_tmit_chunk *chk;
 
-	cookie_ack = NULL;
 	SCTP_TCB_LOCK_ASSERT(stcb);
 
 	cookie_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_DONTWAIT, 1, MT_HEADER);
@@ -10813,8 +10967,12 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
 	struct sctphdr *shout;
 	struct sctp_chunkhdr *ch;
 	struct udphdr *udp;
-	int len, cause_len, padding_len, ret;
+	int len, cause_len, padding_len;
 
+#if defined(INET) || defined(INET6)
+	int ret;
+
+#endif
 #ifdef INET
 	struct sockaddr_in *src_sin, *dst_sin;
 	struct ip *ip;
@@ -11007,7 +11165,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
 			SCTP_STAT_INCR(sctps_sendnocrc);
 #else
 			mout->m_pkthdr.csum_flags = CSUM_SCTP;
-			mout->m_pkthdr.csum_data = 0;
+			mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
 			SCTP_STAT_INCR(sctps_sendhwcrc);
 #endif
 		}
@@ -11037,7 +11195,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
 			SCTP_STAT_INCR(sctps_sendnocrc);
 #else
 			mout->m_pkthdr.csum_flags = CSUM_SCTP_IPV6;
-			mout->m_pkthdr.csum_data = 0;
+			mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
 			SCTP_STAT_INCR(sctps_sendhwcrc);
 #endif
 		}
diff --git a/freebsd/sys/netinet/sctp_pcb.c b/freebsd/sys/netinet/sctp_pcb.c
index e21c2e0..16dc231 100644
--- a/freebsd/sys/netinet/sctp_pcb.c
+++ b/freebsd/sys/netinet/sctp_pcb.c
@@ -774,7 +774,14 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
 		}
 		SCTPDBG(SCTP_DEBUG_PCB4, "Deleting ifa %p\n", (void *)sctp_ifap);
 		sctp_ifap->localifa_flags &= SCTP_ADDR_VALID;
-		sctp_ifap->localifa_flags |= SCTP_BEING_DELETED;
+		/*
+		 * We don't set the flag. This means that the structure will
+		 * hang around in EP's that have bound specific to it until
+		 * they close. This gives us TCP like behavior if someone
+		 * removes an address (or for that matter adds it right
+		 * back).
+		 */
+		/* sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; */
 		vrf->total_ifa_count--;
 		LIST_REMOVE(sctp_ifap, next_bucket);
 		sctp_remove_ifa_from_ifn(sctp_ifap);
@@ -829,18 +836,30 @@ out_now:
 static int
 sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
 {
-	int loopback_scope, ipv4_local_scope, local_scope, site_scope;
-	int ipv4_addr_legal, ipv6_addr_legal;
+	int loopback_scope;
+
+#if defined(INET)
+	int ipv4_local_scope, ipv4_addr_legal;
+
+#endif
+#if defined(INET6)
+	int local_scope, site_scope, ipv6_addr_legal;
+
+#endif
 	struct sctp_vrf *vrf;
 	struct sctp_ifn *sctp_ifn;
 	struct sctp_ifa *sctp_ifa;
 
 	loopback_scope = stcb->asoc.scope.loopback_scope;
+#if defined(INET)
 	ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
+	ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
+#endif
+#if defined(INET6)
 	local_scope = stcb->asoc.scope.local_scope;
 	site_scope = stcb->asoc.scope.site_scope;
-	ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
 	ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
+#endif
 
 	SCTP_IPI_ADDR_RLOCK();
 	vrf = sctp_find_vrf(stcb->asoc.vrf_id);
@@ -865,6 +884,9 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
 					 */
 					continue;
 				}
+				if (sctp_ifa->address.sa.sa_family != to->sa_family) {
+					continue;
+				}
 				switch (sctp_ifa->address.sa.sa_family) {
 #ifdef INET
 				case AF_INET:
@@ -878,6 +900,10 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
 						    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
 							continue;
 						}
+						if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
+						    &sin->sin_addr) != 0) {
+							continue;
+						}
 						if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
 							SCTP_IPI_ADDR_RUNLOCK();
 							return (1);
@@ -893,6 +919,10 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
 
 						sin6 = &sctp_ifa->address.sin6;
 						rsin6 = (struct sockaddr_in6 *)to;
+						if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
+						    &sin6->sin6_addr) != 0) {
+							continue;
+						}
 						if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
 							if (local_scope == 0)
 								continue;
@@ -1040,6 +1070,39 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
 			SCTP_INP_RUNLOCK(inp);
 			continue;
 		}
+		switch (to->sa_family) {
+#ifdef INET
+		case AF_INET:
+			{
+				struct sockaddr_in *sin;
+
+				sin = (struct sockaddr_in *)to;
+				if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+				    &sin->sin_addr) != 0) {
+					SCTP_INP_RUNLOCK(inp);
+					continue;
+				}
+				break;
+			}
+#endif
+#ifdef INET6
+		case AF_INET6:
+			{
+				struct sockaddr_in6 *sin6;
+
+				sin6 = (struct sockaddr_in6 *)to;
+				if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+				    &sin6->sin6_addr) != 0) {
+					SCTP_INP_RUNLOCK(inp);
+					continue;
+				}
+				break;
+			}
+#endif
+		default:
+			SCTP_INP_RUNLOCK(inp);
+			continue;
+		}
 		if (inp->def_vrf_id != vrf_id) {
 			SCTP_INP_RUNLOCK(inp);
 			continue;
@@ -1608,23 +1671,45 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) &&
 		    (inp->sctp_lport == lport)) {
 			/* got it */
+			switch (nam->sa_family) {
 #ifdef INET
-			if ((nam->sa_family == AF_INET) &&
-			    (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
-			    SCTP_IPV6_V6ONLY(inp)) {
-				/* IPv4 on a IPv6 socket with ONLY IPv6 set */
-				SCTP_INP_RUNLOCK(inp);
-				continue;
-			}
+			case AF_INET:
+				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
+				    SCTP_IPV6_V6ONLY(inp)) {
+					/*
+					 * IPv4 on a IPv6 socket with ONLY
+					 * IPv6 set
+					 */
+					SCTP_INP_RUNLOCK(inp);
+					continue;
+				}
+				if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+				    &sin->sin_addr) != 0) {
+					SCTP_INP_RUNLOCK(inp);
+					continue;
+				}
+				break;
 #endif
 #ifdef INET6
-			/* A V6 address and the endpoint is NOT bound V6 */
-			if (nam->sa_family == AF_INET6 &&
-			    (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
-				SCTP_INP_RUNLOCK(inp);
-				continue;
-			}
+			case AF_INET6:
+				/*
+				 * A V6 address and the endpoint is NOT
+				 * bound V6
+				 */
+				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
+					SCTP_INP_RUNLOCK(inp);
+					continue;
+				}
+				if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+				    &sin6->sin6_addr) != 0) {
+					SCTP_INP_RUNLOCK(inp);
+					continue;
+				}
+				break;
 #endif
+			default:
+				break;
+			}
 			/* does a VRF id match? */
 			fnd = 0;
 			if (inp->def_vrf_id == vrf_id)
@@ -1973,8 +2058,13 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset,
     struct sockaddr *dst)
 {
 	struct sctp_paramhdr *phdr, parm_buf;
+
+#if defined(INET) || defined(INET6)
 	struct sctp_tcb *stcb;
-	uint32_t ptype, plen;
+	uint16_t ptype;
+
+#endif
+	uint16_t plen;
 
 #ifdef INET
 	struct sockaddr_in sin4;
@@ -1998,13 +2088,14 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset,
 	sin6.sin6_port = sh->src_port;
 #endif
 
-	stcb = NULL;
 	offset += sizeof(struct sctp_init_chunk);
 
 	phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
 	while (phdr != NULL) {
 		/* now we must see if we want the parameter */
+#if defined(INET) || defined(INET6)
 		ptype = ntohs(phdr->param_type);
+#endif
 		plen = ntohs(phdr->param_length);
 		if (plen == 0) {
 			break;
@@ -2377,6 +2468,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
 	/* setup socket pointers */
 	inp->sctp_socket = so;
 	inp->ip_inp.inp.inp_socket = so;
+	inp->ip_inp.inp.inp_cred = crhold(so->so_cred);
 #ifdef INET6
 	if (INP_SOCKAF(so) == AF_INET6) {
 		if (MODULE_GLOBAL(ip6_auto_flowlabel)) {
@@ -2395,6 +2487,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
 	/* init the small hash table we use to track asocid <-> tcb */
 	inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark);
 	if (inp->sctp_asocidhash == NULL) {
+		crfree(inp->ip_inp.inp.inp_cred);
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
 		SCTP_INP_INFO_WUNLOCK();
 		return (ENOBUFS);
@@ -2409,6 +2502,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
 		((struct in6pcb *)(&inp->ip_inp.inp))->in6p_sp = pcb_sp;
 	}
 	if (error != 0) {
+		crfree(inp->ip_inp.inp.inp_cred);
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
 		SCTP_INP_INFO_WUNLOCK();
 		return error;
@@ -2439,6 +2533,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
 		 */
 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EOPNOTSUPP);
 		so->so_pcb = NULL;
+		crfree(inp->ip_inp.inp.inp_cred);
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
 		return (EOPNOTSUPP);
 	}
@@ -2458,6 +2553,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
 		SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n");
 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
 		so->so_pcb = NULL;
+		crfree(inp->ip_inp.inp.inp_cred);
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
 		return (ENOBUFS);
 	}
@@ -2709,7 +2805,6 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
 	uint32_t vrf_id;
 
 	lport = 0;
-	error = 0;
 	bindall = 1;
 	inp = (struct sctp_inpcb *)so->so_pcb;
 	ip_inp = (struct inpcb *)so->so_pcb;
@@ -2830,13 +2925,6 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
 				return (error);
 			}
 		}
-		if (p == NULL) {
-			SCTP_INP_DECR_REF(inp);
-			SCTP_INP_WUNLOCK(inp);
-			SCTP_INP_INFO_WUNLOCK();
-			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
-			return (error);
-		}
 		SCTP_INP_WUNLOCK(inp);
 		if (bindall) {
 			vrf_id = inp->def_vrf_id;
@@ -3314,17 +3402,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
 				/* Left with Data unread */
 				struct mbuf *op_err;
 
-				op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-				    0, M_DONTWAIT, 1, MT_DATA);
-				if (op_err) {
-					/* Fill in the user initiated abort */
-					struct sctp_paramhdr *ph;
-
-					SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-					ph = mtod(op_err, struct sctp_paramhdr *);
-					ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-					ph->param_length = htons(SCTP_BUF_LEN(op_err));
-				}
+				op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 				asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_3;
 				sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
 				SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -3395,20 +3473,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
 					struct mbuf *op_err;
 
 			abort_anyway:
-					op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (op_err) {
-						/*
-						 * Fill in the user
-						 * initiated abort
-						 */
-						struct sctp_paramhdr *ph;
-
-						SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-						ph = mtod(op_err, struct sctp_paramhdr *);
-						ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-						ph->param_length = htons(SCTP_BUF_LEN(op_err));
-					}
+					op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 					asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_5;
 					sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
 					SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -3472,17 +3537,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
 		    ((asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) {
 			struct mbuf *op_err;
 
-			op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-			    0, M_DONTWAIT, 1, MT_DATA);
-			if (op_err) {
-				/* Fill in the user initiated abort */
-				struct sctp_paramhdr *ph;
-
-				SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-				ph = mtod(op_err, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-				ph->param_length = htons(SCTP_BUF_LEN(op_err));
-			}
+			op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 			asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_7;
 			sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
 			SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -3647,6 +3702,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
 		inp->sctp_tcbhash = NULL;
 	}
 	/* Now we must put the ep memory back into the zone pool */
+	crfree(inp->ip_inp.inp.inp_cred);
 	INP_LOCK_DESTROY(&inp->ip_inp.inp);
 	SCTP_INP_LOCK_DESTROY(inp);
 	SCTP_INP_READ_DESTROY(inp);
@@ -3744,7 +3800,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
 			sin->sin_len = sizeof(struct sockaddr_in);
 			if (set_scope) {
 #ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
-				stcb->ipv4_local_scope = 1;
+				stcb->asoc.scope.ipv4_local_scope = 1;
 #else
 				if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
 					stcb->asoc.scope.ipv4_local_scope = 1;
@@ -4318,6 +4374,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
 			asoc->nr_mapping_array = NULL;
 		}
 		SCTP_DECR_ASOC_COUNT();
+		SCTP_TCB_UNLOCK(stcb);
 		SCTP_TCB_LOCK_DESTROY(stcb);
 		SCTP_TCB_SEND_LOCK_DESTROY(stcb);
 		LIST_REMOVE(stcb, sctp_tcbasocidhash);
@@ -5120,6 +5177,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
 	/* Insert new items here :> */
 
 	/* Get rid of LOCK */
+	SCTP_TCB_UNLOCK(stcb);
 	SCTP_TCB_LOCK_DESTROY(stcb);
 	SCTP_TCB_SEND_LOCK_DESTROY(stcb);
 	if (from_inpcbfree == SCTP_NORMAL_PROC) {
@@ -5845,7 +5903,6 @@ sctp_pcb_init()
 	for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
 		LIST_INIT(&SCTP_BASE_INFO(vtag_timewait)[i]);
 	}
-
 	sctp_startup_iterator();
 
 #if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
@@ -5874,35 +5931,31 @@ sctp_pcb_finish(void)
 	struct sctp_tagblock *twait_block, *prev_twait_block;
 	struct sctp_laddr *wi, *nwi;
 	int i;
+	struct sctp_iterator *it, *nit;
 
 	/*
-	 * Free BSD the it thread never exits but we do clean up. The only
-	 * way freebsd reaches here if we have VRF's but we still add the
-	 * ifdef to make it compile on old versions.
+	 * In FreeBSD the iterator thread never exits but we do clean up.
+	 * The only way FreeBSD reaches here is if we have VRF's but we
+	 * still add the ifdef to make it compile on old versions.
 	 */
-	{
-		struct sctp_iterator *it, *nit;
-
-		SCTP_IPI_ITERATOR_WQ_LOCK();
-		TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
-			if (it->vn != curvnet) {
-				continue;
-			}
-			TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
-			if (it->function_atend != NULL) {
-				(*it->function_atend) (it->pointer, it->val);
-			}
-			SCTP_FREE(it, SCTP_M_ITER);
+	SCTP_IPI_ITERATOR_WQ_LOCK();
+	TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
+		if (it->vn != curvnet) {
+			continue;
 		}
-		SCTP_IPI_ITERATOR_WQ_UNLOCK();
-		SCTP_ITERATOR_LOCK();
-		if ((sctp_it_ctl.cur_it) &&
-		    (sctp_it_ctl.cur_it->vn == curvnet)) {
-			sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
+		TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
+		if (it->function_atend != NULL) {
+			(*it->function_atend) (it->pointer, it->val);
 		}
-		SCTP_ITERATOR_UNLOCK();
+		SCTP_FREE(it, SCTP_M_ITER);
 	}
-
+	SCTP_IPI_ITERATOR_WQ_UNLOCK();
+	SCTP_ITERATOR_LOCK();
+	if ((sctp_it_ctl.cur_it) &&
+	    (sctp_it_ctl.cur_it->vn == curvnet)) {
+		sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
+	}
+	SCTP_ITERATOR_UNLOCK();
 	SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer));
 	SCTP_WQ_ADDR_LOCK();
 	LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) {
diff --git a/freebsd/sys/netinet/sctp_pcb.h b/freebsd/sys/netinet/sctp_pcb.h
index 91807c7..8045765 100644
--- a/freebsd/sys/netinet/sctp_pcb.h
+++ b/freebsd/sys/netinet/sctp_pcb.h
@@ -388,8 +388,8 @@ struct sctp_inpcb {
 
 	/* back pointer to our socket */
 	struct socket *sctp_socket;
+	uint64_t sctp_features;	/* Feature flags */
 	uint32_t sctp_flags;	/* INP state flag set */
-	uint32_t sctp_features;	/* Feature flags */
 	uint32_t sctp_mobility_features;	/* Mobility  Feature flags */
 	struct sctp_pcb sctp_ep;/* SCTP ep data */
 	/* head of the hash of all associations */
diff --git a/freebsd/sys/netinet/sctp_structs.h b/freebsd/sys/netinet/sctp_structs.h
index bc18f0e..a8b86c6 100644
--- a/freebsd/sys/netinet/sctp_structs.h
+++ b/freebsd/sys/netinet/sctp_structs.h
@@ -446,7 +446,6 @@ struct sctp_tmit_chunk {
 	uint8_t do_rtt;
 	uint8_t book_size_scale;
 	uint8_t no_fr_allowed;
-	uint8_t pr_sctp_on;
 	uint8_t copy_by_ref;
 	uint8_t window_probe;
 };
@@ -522,7 +521,6 @@ struct sctp_stream_queue_pending {
 	uint8_t holds_key_ref;
 	uint8_t msg_is_complete;
 	uint8_t some_taken;
-	uint8_t pr_sctp_on;
 	uint8_t sender_all_done;
 	uint8_t put_last_out;
 	uint8_t discard_rest;
@@ -1205,7 +1203,7 @@ struct sctp_association {
 	/* JRS 5/21/07 - CMT PF variable */
 	uint8_t sctp_cmt_pf;
 	uint8_t use_precise_time;
-	uint32_t sctp_features;
+	uint64_t sctp_features;
 	uint16_t port;		/* remote UDP encapsulation port */
 	/*
 	 * The mapping array is used to track out of order sequences above
diff --git a/freebsd/sys/netinet/sctp_sysctl.c b/freebsd/sys/netinet/sctp_sysctl.c
index 95e3c58..ba7a00b 100644
--- a/freebsd/sys/netinet/sctp_sysctl.c
+++ b/freebsd/sys/netinet/sctp_sysctl.c
@@ -118,7 +118,7 @@ sctp_init_sysctls()
 	SCTP_BASE_SYSCTL(sctp_steady_step) = SCTPCTL_RTTVAR_STEADYS_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_use_dccc_ecn) = SCTPCTL_RTTVAR_DCCCECN_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_blackhole) = SCTPCTL_BLACKHOLE_DEFAULT;
-
+	SCTP_BASE_SYSCTL(sctp_diag_info_code) = SCTPCTL_DIAG_INFO_CODE_DEFAULT;
 #if defined(SCTP_LOCAL_TRACE_BUF)
 	memset(&SCTP_BASE_SYSCTL(sctp_log), 0, sizeof(struct sctp_log));
 #endif
@@ -254,6 +254,10 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
 						sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
 						if (sin->sin_addr.s_addr == 0)
 							continue;
+						if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+						    &sin->sin_addr) != 0) {
+							continue;
+						}
 						if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)))
 							continue;
 					} else {
@@ -269,6 +273,10 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
 						sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
 						if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
 							continue;
+						if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+						    &sin6->sin6_addr) != 0) {
+							continue;
+						}
 						if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
 							if (local_scope == 0)
 								continue;
@@ -404,7 +412,7 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
 		xinpcb.last = 0;
 		xinpcb.local_port = ntohs(inp->sctp_lport);
 		xinpcb.flags = inp->sctp_flags;
-		xinpcb.features = inp->sctp_features;
+		xinpcb.features = (uint32_t) inp->sctp_features;
 		xinpcb.total_sends = inp->total_sends;
 		xinpcb.total_recvs = inp->total_recvs;
 		xinpcb.total_nospaces = inp->total_nospaces;
@@ -661,6 +669,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_blackhole), SCTPCTL_BLACKHOLE_MIN, SCTPCTL_BLACKHOLE_MAX);
+		RANGECHK(SCTP_BASE_SYSCTL(sctp_diag_info_code), SCTPCTL_DIAG_INFO_CODE_MIN, SCTPCTL_DIAG_INFO_CODE_MAX);
 
 #ifdef SCTP_DEBUG
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_debug_on), SCTPCTL_DEBUG_MIN, SCTPCTL_DEBUG_MAX);
@@ -1119,6 +1128,10 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, blackhole, CTLTYPE_UINT | CTLFLAG_RW,
     &SCTP_BASE_SYSCTL(sctp_blackhole), 0, sysctl_sctp_check, "IU",
     SCTPCTL_BLACKHOLE_DESC);
 
+SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, diag_info_code, CTLTYPE_UINT | CTLFLAG_RW,
+    &SCTP_BASE_SYSCTL(sctp_diag_info_code), 0, sysctl_sctp_check, "IU",
+    SCTPCTL_DIAG_INFO_CODE_DESC);
+
 #ifdef SCTP_DEBUG
 SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, debug, CTLTYPE_UINT | CTLFLAG_RW,
     &SCTP_BASE_SYSCTL(sctp_debug_on), 0, sysctl_sctp_check, "IU",
diff --git a/freebsd/sys/netinet/sctp_sysctl.h b/freebsd/sys/netinet/sctp_sysctl.h
index 8090373..432d36a 100644
--- a/freebsd/sys/netinet/sctp_sysctl.h
+++ b/freebsd/sys/netinet/sctp_sysctl.h
@@ -104,6 +104,7 @@ struct sctp_sysctl {
 	uint32_t sctp_rttvar_eqret;
 	uint32_t sctp_steady_step;
 	uint32_t sctp_use_dccc_ecn;
+	uint32_t sctp_diag_info_code;
 #if defined(SCTP_LOCAL_TRACE_BUF)
 	struct sctp_log sctp_log;
 #endif
@@ -465,7 +466,7 @@ struct sctp_sysctl {
 #define SCTPCTL_UDP_TUNNELING_PORT_DESC		"Set the SCTP/UDP tunneling port"
 #define SCTPCTL_UDP_TUNNELING_PORT_MIN		0
 #define SCTPCTL_UDP_TUNNELING_PORT_MAX		65535
-#define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT	SCTP_OVER_UDP_TUNNELING_PORT
+#define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT	0
 
 /* Enable sending of the SACK-IMMEDIATELY bit */
 #define SCTPCTL_SACK_IMMEDIATELY_ENABLE_DESC	"Enable sending of the SACK-IMMEDIATELY-bit."
@@ -529,6 +530,11 @@ struct sctp_sysctl {
 #define SCTPCTL_BLACKHOLE_MAX		2
 #define SCTPCTL_BLACKHOLE_DEFAULT	SCTPCTL_BLACKHOLE_MIN
 
+#define SCTPCTL_DIAG_INFO_CODE_DESC	"Diagnostic information error cause code"
+#define SCTPCTL_DIAG_INFO_CODE_MIN	0
+#define SCTPCTL_DIAG_INFO_CODE_MAX	65535
+#define SCTPCTL_DIAG_INFO_CODE_DEFAULT	0
+
 #if defined(SCTP_DEBUG)
 /* debug: Configure debug output */
 #define SCTPCTL_DEBUG_DESC	"Configure debug output"
diff --git a/freebsd/sys/netinet/sctp_timer.c b/freebsd/sys/netinet/sctp_timer.c
index be60111..7d010c7 100644
--- a/freebsd/sys/netinet/sctp_timer.c
+++ b/freebsd/sys/netinet/sctp_timer.c
@@ -149,24 +149,12 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 	 */
 	if (stcb->asoc.overall_error_count > threshold) {
 		/* Abort notification sends a ULP notify */
-		struct mbuf *oper;
-
-		oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
-		    0, M_DONTWAIT, 1, MT_DATA);
-		if (oper) {
-			struct sctp_paramhdr *ph;
-			uint32_t *ippp;
-
-			SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-			    sizeof(uint32_t);
-			ph = mtod(oper, struct sctp_paramhdr *);
-			ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-			ph->param_length = htons(SCTP_BUF_LEN(oper));
-			ippp = (uint32_t *) (ph + 1);
-			*ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_1);
-		}
+		struct mbuf *op_err;
+
+		op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION,
+		    "Association error couter exceeded");
 		inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_1;
-		sctp_abort_an_association(inp, stcb, oper, SCTP_SO_NOT_LOCKED);
+		sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
 		return (1);
 	}
 	return (0);
@@ -448,7 +436,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
 				}
 			}
 			TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
-			if (chk->pr_sctp_on) {
+			if (PR_SCTP_ENABLED(chk->flags)) {
 				if (asoc->pr_sctp_cnt != 0)
 					asoc->pr_sctp_cnt--;
 			}
@@ -554,7 +542,7 @@ start_again:
 	TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) {
 		if (SCTP_TSN_GE(stcb->asoc.last_acked_seq, chk->rec.data.TSN_seq)) {
 			/* Strange case our list got out of order? */
-			SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x",
+			SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x\n",
 			    (unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.TSN_seq);
 			recovery_cnt++;
 #ifdef INVARIANTS
@@ -1053,24 +1041,12 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
 	if (cookie == NULL) {
 		if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
 			/* FOOBAR! */
-			struct mbuf *oper;
-
-			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
-			    0, M_DONTWAIT, 1, MT_DATA);
-			if (oper) {
-				struct sctp_paramhdr *ph;
-				uint32_t *ippp;
-
-				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-				    sizeof(uint32_t);
-				ph = mtod(oper, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-				ph->param_length = htons(SCTP_BUF_LEN(oper));
-				ippp = (uint32_t *) (ph + 1);
-				*ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
-			}
+			struct mbuf *op_err;
+
+			op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION,
+			    "Cookie timer expired, but no cookie");
 			inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_4;
-			sctp_abort_an_association(inp, stcb, oper, SCTP_SO_NOT_LOCKED);
+			sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
 		} else {
 #ifdef INVARIANTS
 			panic("Cookie timer expires in wrong state?");
diff --git a/freebsd/sys/netinet/sctp_uio.h b/freebsd/sys/netinet/sctp_uio.h
index 063fd9f..df9c2d2 100644
--- a/freebsd/sys/netinet/sctp_uio.h
+++ b/freebsd/sys/netinet/sctp_uio.h
@@ -662,10 +662,6 @@ struct sctp_hmacalgo {
 #define SCTP_AUTH_HMAC_ID_RSVD		0x0000
 #define SCTP_AUTH_HMAC_ID_SHA1		0x0001	/* default, mandatory */
 #define SCTP_AUTH_HMAC_ID_SHA256	0x0003
-#define SCTP_AUTH_HMAC_ID_SHA224	0x0004
-#define SCTP_AUTH_HMAC_ID_SHA384	0x0005
-#define SCTP_AUTH_HMAC_ID_SHA512	0x0006
-
 
 /* SCTP_AUTH_ACTIVE_KEY / SCTP_AUTH_DELETE_KEY */
 struct sctp_authkeyid {
diff --git a/freebsd/sys/netinet/sctp_usrreq.c b/freebsd/sys/netinet/sctp_usrreq.c
index 81db1dc..e2bbced 100644
--- a/freebsd/sys/netinet/sctp_usrreq.c
+++ b/freebsd/sys/netinet/sctp_usrreq.c
@@ -856,20 +856,7 @@ sctp_disconnect(struct socket *so)
 					struct mbuf *op_err;
 
 			abort_anyway:
-					op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-					    0, M_DONTWAIT, 1, MT_DATA);
-					if (op_err) {
-						/*
-						 * Fill in the user
-						 * initiated abort
-						 */
-						struct sctp_paramhdr *ph;
-
-						SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-						ph = mtod(op_err, struct sctp_paramhdr *);
-						ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-						ph->param_length = htons(SCTP_BUF_LEN(op_err));
-					}
+					op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4;
 					sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
 					SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -1065,17 +1052,7 @@ sctp_shutdown(struct socket *so)
 				struct mbuf *op_err;
 
 		abort_anyway:
-				op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-				    0, M_DONTWAIT, 1, MT_DATA);
-				if (op_err) {
-					/* Fill in the user initiated abort */
-					struct sctp_paramhdr *ph;
-
-					SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-					ph = mtod(op_err, struct sctp_paramhdr *);
-					ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-					ph->param_length = htons(SCTP_BUF_LEN(op_err));
-				}
+				op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6;
 				sctp_abort_an_association(stcb->sctp_ep, stcb,
 				    op_err, SCTP_SO_LOCKED);
@@ -1122,9 +1099,17 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
 {
 	struct sctp_ifn *sctp_ifn;
 	struct sctp_ifa *sctp_ifa;
-	int loopback_scope, ipv4_local_scope, local_scope, site_scope;
 	size_t actual;
-	int ipv4_addr_legal, ipv6_addr_legal;
+	int loopback_scope;
+
+#if defined(INET)
+	int ipv4_local_scope, ipv4_addr_legal;
+
+#endif
+#if defined(INET6)
+	int local_scope, site_scope, ipv6_addr_legal;
+
+#endif
 	struct sctp_vrf *vrf;
 
 	actual = 0;
@@ -1134,27 +1119,43 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
 	if (stcb) {
 		/* Turn on all the appropriate scope */
 		loopback_scope = stcb->asoc.scope.loopback_scope;
+#if defined(INET)
 		ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
+		ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
+#endif
+#if defined(INET6)
 		local_scope = stcb->asoc.scope.local_scope;
 		site_scope = stcb->asoc.scope.site_scope;
-		ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
 		ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
+#endif
 	} else {
 		/* Use generic values for endpoints. */
 		loopback_scope = 1;
+#if defined(INET)
 		ipv4_local_scope = 1;
+#endif
+#if defined(INET6)
 		local_scope = 1;
 		site_scope = 1;
+#endif
 		if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
+#if defined(INET6)
 			ipv6_addr_legal = 1;
+#endif
+#if defined(INET)
 			if (SCTP_IPV6_V6ONLY(inp)) {
 				ipv4_addr_legal = 0;
 			} else {
 				ipv4_addr_legal = 1;
 			}
+#endif
 		} else {
+#if defined(INET6)
 			ipv6_addr_legal = 0;
+#endif
+#if defined(INET)
 			ipv4_addr_legal = 1;
+#endif
 		}
 	}
 	vrf = sctp_find_vrf(vrf_id);
@@ -1198,6 +1199,10 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
 							 */
 							continue;
 						}
+						if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+						    &sin->sin_addr) != 0) {
+							continue;
+						}
 						if ((ipv4_local_scope == 0) &&
 						    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
 							continue;
@@ -1239,6 +1244,10 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
 							 */
 							continue;
 						}
+						if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+						    &sin6->sin6_addr) != 0) {
+							continue;
+						}
 						if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
 							if (local_scope == 0)
 								continue;
@@ -2766,7 +2775,7 @@ flags_out:
 
 			if (stcb) {
 				/* simply copy out the sockaddr_storage... */
-				int len;
+				size_t len;
 
 				len = *optsize;
 				if (len > stcb->asoc.primary_destination->ro._l_addr.sa.sa_len)
@@ -3283,7 +3292,7 @@ flags_out:
 				}
 			}
 			if (error == 0) {
-				*optsize = sizeof(struct sctp_paddrparams);
+				*optsize = sizeof(struct sctp_udpencaps);
 			}
 			break;
 		}
@@ -3944,7 +3953,6 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 			sctp_hmaclist_t *hmaclist;
 			uint16_t hmacid;
 			uint32_t i;
-			size_t found;
 
 			SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize);
 			if (optsize < sizeof(struct sctp_hmacalgo) + shmac->shmac_number_of_idents * sizeof(uint16_t)) {
@@ -3968,14 +3976,14 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 					goto sctp_set_hmac_done;
 				}
 			}
-			found = 0;
 			for (i = 0; i < hmaclist->num_algo; i++) {
 				if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) {
 					/* already in list */
-					found = 1;
+					break;
 				}
 			}
-			if (!found) {
+			if (i == hmaclist->num_algo) {
+				/* not found in list */
 				sctp_free_hmaclist(hmaclist);
 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 				error = EINVAL;
@@ -4799,11 +4807,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 							    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
 						}
 						net->dest_state |= SCTP_ADDR_NO_PMTUD;
-						if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
-							net->mtu = paddrp->spp_pathmtu + ovh;
-							if (net->mtu < stcb->asoc.smallest_mtu) {
-								sctp_pathmtu_adjustment(stcb, net->mtu);
-							}
+						net->mtu = paddrp->spp_pathmtu + ovh;
+						if (net->mtu < stcb->asoc.smallest_mtu) {
+							sctp_pathmtu_adjustment(stcb, net->mtu);
 						}
 					}
 					if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
@@ -4923,11 +4929,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 								    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
 							}
 							net->dest_state |= SCTP_ADDR_NO_PMTUD;
-							if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
-								net->mtu = paddrp->spp_pathmtu + ovh;
-								if (net->mtu < stcb->asoc.smallest_mtu) {
-									sctp_pathmtu_adjustment(stcb, net->mtu);
-								}
+							net->mtu = paddrp->spp_pathmtu + ovh;
+							if (net->mtu < stcb->asoc.smallest_mtu) {
+								sctp_pathmtu_adjustment(stcb, net->mtu);
 							}
 						}
 						sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
@@ -5245,6 +5249,43 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 						error = EINVAL;
 						goto out_of_it;
 					}
+				} else {
+					switch (sspp->sspp_addr.ss_family) {
+#ifdef INET
+					case AF_INET:
+						{
+							struct sockaddr_in *sin;
+
+							sin = (struct sockaddr_in *)&sspp->sspp_addr;
+							if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
+							    &sin->sin_addr) != 0) {
+								SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+								error = EINVAL;
+								goto out_of_it;
+							}
+							break;
+						}
+#endif
+#ifdef INET6
+					case AF_INET6:
+						{
+							struct sockaddr_in6 *sin6;
+
+							sin6 = (struct sockaddr_in6 *)&sspp->sspp_addr;
+							if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
+							    &sin6->sin6_addr) != 0) {
+								SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+								error = EINVAL;
+								goto out_of_it;
+							}
+							break;
+						}
+#endif
+					default:
+						SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+						error = EINVAL;
+						goto out_of_it;
+					}
 				}
 				if (sctp_set_primary_ip_address_sa(stcb,
 				    (struct sockaddr *)&sspp->sspp_addr) != 0) {
@@ -5603,7 +5644,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 			SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
 			net = NULL;
 			if (stcb) {
-				net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_assoc_id);
+				net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address);
 			} else {
 				/*
 				 * We increment here since
@@ -5614,7 +5655,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 				 */
 				SCTP_INP_INCR_REF(inp);
 				stcb = sctp_findassociation_ep_addr(&inp,
-				    (struct sockaddr *)&thlds->spt_assoc_id,
+				    (struct sockaddr *)&thlds->spt_address,
 				    &net, NULL, NULL);
 				if (stcb == NULL) {
 					SCTP_INP_DECR_REF(inp);
@@ -5623,7 +5664,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 			if (stcb && (net == NULL)) {
 				struct sockaddr *sa;
 
-				sa = (struct sockaddr *)&thlds->spt_assoc_id;
+				sa = (struct sockaddr *)&thlds->spt_address;
 #ifdef INET
 				if (sa->sa_family == AF_INET) {
 
@@ -6059,30 +6100,29 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) {
 		/* See if we have a listener */
 		struct sctp_inpcb *tinp;
-		union sctp_sockstore store, *sp;
+		union sctp_sockstore store;
 
-		sp = &store;
 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
 			/* not bound all */
 			struct sctp_laddr *laddr;
 
 			LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
 				memcpy(&store, &laddr->ifa->address, sizeof(store));
-				switch (sp->sa.sa_family) {
+				switch (store.sa.sa_family) {
 #ifdef INET
 				case AF_INET:
-					sp->sin.sin_port = inp->sctp_lport;
+					store.sin.sin_port = inp->sctp_lport;
 					break;
 #endif
 #ifdef INET6
 				case AF_INET6:
-					sp->sin6.sin6_port = inp->sctp_lport;
+					store.sin6.sin6_port = inp->sctp_lport;
 					break;
 #endif
 				default:
 					break;
 				}
-				tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id);
+				tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id);
 				if (tinp && (tinp != inp) &&
 				    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
 				    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
@@ -6100,20 +6140,6 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
 		} else {
 			/* Setup a local addr bound all */
 			memset(&store, 0, sizeof(store));
-			switch (sp->sa.sa_family) {
-#ifdef INET
-			case AF_INET:
-				store.sin.sin_port = inp->sctp_lport;
-				break;
-#endif
-#ifdef INET6
-			case AF_INET6:
-				sp->sin6.sin6_port = inp->sctp_lport;
-				break;
-#endif
-			default:
-				break;
-			}
 #ifdef INET6
 			if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
 				store.sa.sa_family = AF_INET6;
@@ -6126,7 +6152,21 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
 				store.sa.sa_len = sizeof(struct sockaddr_in);
 			}
 #endif
-			tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id);
+			switch (store.sa.sa_family) {
+#ifdef INET
+			case AF_INET:
+				store.sin.sin_port = inp->sctp_lport;
+				break;
+#endif
+#ifdef INET6
+			case AF_INET6:
+				store.sin6.sin6_port = inp->sctp_lport;
+				break;
+#endif
+			default:
+				break;
+			}
+			tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id);
 			if (tinp && (tinp != inp) &&
 			    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
 			    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
diff --git a/freebsd/sys/netinet/sctputil.c b/freebsd/sys/netinet/sctputil.c
index 15928d8..6cd8273 100644
--- a/freebsd/sys/netinet/sctputil.c
+++ b/freebsd/sys/netinet/sctputil.c
@@ -2604,7 +2604,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
 	if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
 		notif_len = sizeof(struct sctp_assoc_change);
 		if (abort != NULL) {
-			abort_len = htons(abort->ch.chunk_length);
+			abort_len = ntohs(abort->ch.chunk_length);
 		} else {
 			abort_len = 0;
 		}
@@ -2624,6 +2624,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
 		}
 		SCTP_BUF_NEXT(m_notify) = NULL;
 		sac = mtod(m_notify, struct sctp_assoc_change *);
+		memset(sac, 0, notif_len);
 		sac->sac_type = SCTP_ASSOC_CHANGE;
 		sac->sac_flags = 0;
 		sac->sac_length = sizeof(struct sctp_assoc_change);
@@ -2837,21 +2838,21 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
 	if (m_notify == NULL)
 		/* no space left */
 		return;
-	length += chk->send_size;
-	length -= sizeof(struct sctp_data_chunk);
 	SCTP_BUF_LEN(m_notify) = 0;
 	if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
 		ssfe = mtod(m_notify, struct sctp_send_failed_event *);
+		memset(ssfe, 0, length);
 		ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
 		if (sent) {
 			ssfe->ssfe_flags = SCTP_DATA_SENT;
 		} else {
 			ssfe->ssfe_flags = SCTP_DATA_UNSENT;
 		}
+		length += chk->send_size;
+		length -= sizeof(struct sctp_data_chunk);
 		ssfe->ssfe_length = length;
 		ssfe->ssfe_error = error;
 		/* not exactly what the user sent in, but should be close :) */
-		bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info));
 		ssfe->ssfe_info.snd_sid = chk->rec.data.stream_number;
 		ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags;
 		ssfe->ssfe_info.snd_ppid = chk->rec.data.payloadtype;
@@ -2861,12 +2862,15 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
 		SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event);
 	} else {
 		ssf = mtod(m_notify, struct sctp_send_failed *);
+		memset(ssf, 0, length);
 		ssf->ssf_type = SCTP_SEND_FAILED;
 		if (sent) {
 			ssf->ssf_flags = SCTP_DATA_SENT;
 		} else {
 			ssf->ssf_flags = SCTP_DATA_UNSENT;
 		}
+		length += chk->send_size;
+		length -= sizeof(struct sctp_data_chunk);
 		ssf->ssf_length = length;
 		ssf->ssf_error = error;
 		/* not exactly what the user sent in, but should be close :) */
@@ -2950,16 +2954,16 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
 		/* no space left */
 		return;
 	}
-	length += sp->length;
 	SCTP_BUF_LEN(m_notify) = 0;
 	if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
 		ssfe = mtod(m_notify, struct sctp_send_failed_event *);
+		memset(ssfe, 0, length);
 		ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
 		ssfe->ssfe_flags = SCTP_DATA_UNSENT;
+		length += sp->length;
 		ssfe->ssfe_length = length;
 		ssfe->ssfe_error = error;
 		/* not exactly what the user sent in, but should be close :) */
-		bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info));
 		ssfe->ssfe_info.snd_sid = sp->stream;
 		if (sp->some_taken) {
 			ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG;
@@ -2973,12 +2977,13 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
 		SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event);
 	} else {
 		ssf = mtod(m_notify, struct sctp_send_failed *);
+		memset(ssf, 0, length);
 		ssf->ssf_type = SCTP_SEND_FAILED;
 		ssf->ssf_flags = SCTP_DATA_UNSENT;
+		length += sp->length;
 		ssf->ssf_length = length;
 		ssf->ssf_error = error;
 		/* not exactly what the user sent in, but should be close :) */
-		bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
 		ssf->ssf_info.sinfo_stream = sp->stream;
 		ssf->ssf_info.sinfo_ssn = 0;
 		if (sp->some_taken) {
@@ -3040,6 +3045,7 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb)
 		return;
 	SCTP_BUF_LEN(m_notify) = 0;
 	sai = mtod(m_notify, struct sctp_adaptation_event *);
+	memset(sai, 0, sizeof(struct sctp_adaptation_event));
 	sai->sai_type = SCTP_ADAPTATION_INDICATION;
 	sai->sai_flags = 0;
 	sai->sai_length = sizeof(struct sctp_adaptation_event);
@@ -3095,6 +3101,7 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
 		return;
 	SCTP_BUF_LEN(m_notify) = 0;
 	pdapi = mtod(m_notify, struct sctp_pdapi_event *);
+	memset(pdapi, 0, sizeof(struct sctp_pdapi_event));
 	pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
 	pdapi->pdapi_flags = 0;
 	pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
@@ -3204,6 +3211,7 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb)
 		/* no space left */
 		return;
 	sse = mtod(m_notify, struct sctp_shutdown_event *);
+	memset(sse, 0, sizeof(struct sctp_shutdown_event));
 	sse->sse_type = SCTP_SHUTDOWN_EVENT;
 	sse->sse_flags = 0;
 	sse->sse_length = sizeof(struct sctp_shutdown_event);
@@ -3254,6 +3262,7 @@ sctp_notify_sender_dry_event(struct sctp_tcb *stcb,
 	}
 	SCTP_BUF_LEN(m_notify) = 0;
 	event = mtod(m_notify, struct sctp_sender_dry_event *);
+	memset(event, 0, sizeof(struct sctp_sender_dry_event));
 	event->sender_dry_type = SCTP_SENDER_DRY_EVENT;
 	event->sender_dry_flags = 0;
 	event->sender_dry_length = sizeof(struct sctp_sender_dry_event);
@@ -3286,7 +3295,6 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
 	struct mbuf *m_notify;
 	struct sctp_queued_to_read *control;
 	struct sctp_stream_change_event *stradd;
-	int len;
 
 	if ((stcb == NULL) ||
 	    (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT))) {
@@ -3299,25 +3307,20 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
 		return;
 	}
 	stcb->asoc.peer_req_out = 0;
-	m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
+	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_stream_change_event), 0, M_DONTWAIT, 1, MT_DATA);
 	if (m_notify == NULL)
 		/* no space left */
 		return;
 	SCTP_BUF_LEN(m_notify) = 0;
-	len = sizeof(struct sctp_stream_change_event);
-	if (len > M_TRAILINGSPACE(m_notify)) {
-		/* never enough room */
-		sctp_m_freem(m_notify);
-		return;
-	}
 	stradd = mtod(m_notify, struct sctp_stream_change_event *);
+	memset(stradd, 0, sizeof(struct sctp_stream_change_event));
 	stradd->strchange_type = SCTP_STREAM_CHANGE_EVENT;
 	stradd->strchange_flags = flag;
-	stradd->strchange_length = len;
+	stradd->strchange_length = sizeof(struct sctp_stream_change_event);
 	stradd->strchange_assoc_id = sctp_get_associd(stcb);
 	stradd->strchange_instrms = numberin;
 	stradd->strchange_outstrms = numberout;
-	SCTP_BUF_LEN(m_notify) = len;
+	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_stream_change_event);
 	SCTP_BUF_NEXT(m_notify) = NULL;
 	if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
 		/* no space */
@@ -3348,32 +3351,26 @@ sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32
 	struct mbuf *m_notify;
 	struct sctp_queued_to_read *control;
 	struct sctp_assoc_reset_event *strasoc;
-	int len;
 
 	if ((stcb == NULL) ||
 	    (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT))) {
 		/* event not enabled */
 		return;
 	}
-	m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
+	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_reset_event), 0, M_DONTWAIT, 1, MT_DATA);
 	if (m_notify == NULL)
 		/* no space left */
 		return;
 	SCTP_BUF_LEN(m_notify) = 0;
-	len = sizeof(struct sctp_assoc_reset_event);
-	if (len > M_TRAILINGSPACE(m_notify)) {
-		/* never enough room */
-		sctp_m_freem(m_notify);
-		return;
-	}
 	strasoc = mtod(m_notify, struct sctp_assoc_reset_event *);
+	memset(strasoc, 0, sizeof(struct sctp_assoc_reset_event));
 	strasoc->assocreset_type = SCTP_ASSOC_RESET_EVENT;
 	strasoc->assocreset_flags = flag;
-	strasoc->assocreset_length = len;
+	strasoc->assocreset_length = sizeof(struct sctp_assoc_reset_event);
 	strasoc->assocreset_assoc_id = sctp_get_associd(stcb);
 	strasoc->assocreset_local_tsn = sending_tsn;
 	strasoc->assocreset_remote_tsn = recv_tsn;
-	SCTP_BUF_LEN(m_notify) = len;
+	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_reset_event);
 	SCTP_BUF_NEXT(m_notify) = NULL;
 	if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
 		/* no space */
@@ -3426,6 +3423,7 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb,
 		return;
 	}
 	strreset = mtod(m_notify, struct sctp_stream_reset_event *);
+	memset(strreset, 0, len);
 	strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
 	strreset->strreset_flags = flag;
 	strreset->strreset_length = len;
@@ -3476,7 +3474,7 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro
 		return;
 	}
 	if (chunk != NULL) {
-		chunk_len = htons(chunk->ch.chunk_length);
+		chunk_len = ntohs(chunk->ch.chunk_length);
 	} else {
 		chunk_len = 0;
 	}
@@ -4020,6 +4018,7 @@ void
 sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
     struct sockaddr *src, struct sockaddr *dst,
     struct sctphdr *sh, struct sctp_inpcb *inp,
+    struct mbuf *cause,
     uint8_t use_mflowid, uint32_t mflowid,
     uint32_t vrf_id, uint16_t port)
 {
@@ -4048,9 +4047,6 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
 		case SCTP_INIT:
 			contains_init_chunk = 1;
 			break;
-		case SCTP_COOKIE_ECHO:
-			/* We hit here only if the assoc is being freed */
-			return;
 		case SCTP_PACKET_DROPPED:
 			/* we don't respond to pkt-dropped */
 			return;
@@ -4078,7 +4074,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
 	if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
 	    ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
 	    (contains_init_chunk == 0))) {
-		sctp_send_abort(m, iphlen, src, dst, sh, 0, NULL,
+		sctp_send_abort(m, iphlen, src, dst, sh, 0, cause,
 		    use_mflowid, mflowid,
 		    vrf_id, port);
 	}
@@ -4633,19 +4629,43 @@ get_out:
  */
 
 struct mbuf *
-sctp_generate_invmanparam(int err)
+sctp_generate_cause(uint16_t code, char *info)
 {
-	/* Return a MBUF with a invalid mandatory parameter */
 	struct mbuf *m;
+	struct sctp_gen_error_cause *cause;
+	size_t info_len, len;
 
-	m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_DONTWAIT, 1, MT_DATA);
-	if (m) {
-		struct sctp_paramhdr *ph;
+	if ((code == 0) || (info == NULL)) {
+		return (NULL);
+	}
+	info_len = strlen(info);
+	len = sizeof(struct sctp_paramhdr) + info_len;
+	m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
+	if (m != NULL) {
+		SCTP_BUF_LEN(m) = len;
+		cause = mtod(m, struct sctp_gen_error_cause *);
+		cause->code = htons(code);
+		cause->length = htons((uint16_t) len);
+		memcpy(cause->info, info, info_len);
+	}
+	return (m);
+}
 
-		SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
-		ph = mtod(m, struct sctp_paramhdr *);
-		ph->param_length = htons(sizeof(struct sctp_paramhdr));
-		ph->param_type = htons(err);
+struct mbuf *
+sctp_generate_no_user_data_cause(uint32_t tsn)
+{
+	struct mbuf *m;
+	struct sctp_error_no_user_data *no_user_data_cause;
+	size_t len;
+
+	len = sizeof(struct sctp_error_no_user_data);
+	m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
+	if (m != NULL) {
+		SCTP_BUF_LEN(m) = len;
+		no_user_data_cause = mtod(m, struct sctp_error_no_user_data *);
+		no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA);
+		no_user_data_cause->cause.length = htons((uint16_t) len);
+		no_user_data_cause->tsn = tsn;	/* tsn is passed in as NBO */
 	}
 	return (m);
 }
@@ -4835,7 +4855,6 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
 				atomic_add_int(&chk->whoTo->ref_count, 1);
 				chk->rec.data.TSN_seq = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1);
 				stcb->asoc.pr_sctp_cnt++;
-				chk->pr_sctp_on = 1;
 				TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next);
 				stcb->asoc.sent_queue_cnt++;
 				stcb->asoc.pr_sctp_cnt++;
@@ -5871,8 +5890,8 @@ get_more_data:
 			goto release;
 		}
 		if ((uio->uio_resid == 0) ||
-		    ((in_eeor_mode) && (copied_so_far >= max(so->so_rcv.sb_lowat, 1)))
-		    ) {
+		    ((in_eeor_mode) &&
+		    (copied_so_far >= (uint32_t) max(so->so_rcv.sb_lowat, 1)))) {
 			goto release;
 		}
 		/*
@@ -6217,9 +6236,12 @@ sctp_soreceive(struct socket *so,
 		fromlen = 0;
 	}
 
+	if (filling_sinfo) {
+		memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo));
+	}
 	error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, flagsp,
 	    (struct sctp_sndrcvinfo *)&sinfo, filling_sinfo);
-	if ((controlp) && (filling_sinfo)) {
+	if (controlp != NULL) {
 		/* copy back the sinfo in a CMSG format */
 		if (filling_sinfo)
 			*controlp = sctp_build_ctl_nchunk(inp,
@@ -6615,8 +6637,16 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
 int
 sctp_local_addr_count(struct sctp_tcb *stcb)
 {
-	int loopback_scope, ipv4_local_scope, local_scope, site_scope;
-	int ipv4_addr_legal, ipv6_addr_legal;
+	int loopback_scope;
+
+#if defined(INET)
+	int ipv4_local_scope, ipv4_addr_legal;
+
+#endif
+#if defined (INET6)
+	int local_scope, site_scope, ipv6_addr_legal;
+
+#endif
 	struct sctp_vrf *vrf;
 	struct sctp_ifn *sctp_ifn;
 	struct sctp_ifa *sctp_ifa;
@@ -6624,11 +6654,15 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
 
 	/* Turn on all the appropriate scopes */
 	loopback_scope = stcb->asoc.scope.loopback_scope;
+#if defined(INET)
 	ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
+	ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
+#endif
+#if defined(INET6)
 	local_scope = stcb->asoc.scope.local_scope;
 	site_scope = stcb->asoc.scope.site_scope;
-	ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
 	ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
+#endif
 	SCTP_IPI_ADDR_RLOCK();
 	vrf = sctp_find_vrf(stcb->asoc.vrf_id);
 	if (vrf == NULL) {
@@ -6662,6 +6696,10 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
 							 */
 							continue;
 						}
+						if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
+						    &sin->sin_addr) != 0) {
+							continue;
+						}
 						if ((ipv4_local_scope == 0) &&
 						    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
 							continue;
@@ -6682,6 +6720,10 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
 						if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
 							continue;
 						}
+						if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
+						    &sin6->sin6_addr) != 0) {
+							continue;
+						}
 						if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
 							if (local_scope == 0)
 								continue;
diff --git a/freebsd/sys/netinet/sctputil.h b/freebsd/sys/netinet/sctputil.h
index 411bfaf..af5a0f2 100644
--- a/freebsd/sys/netinet/sctputil.h
+++ b/freebsd/sys/netinet/sctputil.h
@@ -205,6 +205,7 @@ void
 sctp_handle_ootb(struct mbuf *, int, int,
     struct sockaddr *, struct sockaddr *,
     struct sctphdr *, struct sctp_inpcb *,
+    struct mbuf *,
     uint8_t, uint32_t,
     uint32_t, uint16_t);
 
@@ -252,7 +253,8 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *,
 #endif
 );
 
-struct mbuf *sctp_generate_invmanparam(int);
+struct mbuf *sctp_generate_cause(uint16_t, char *);
+struct mbuf *sctp_generate_no_user_data_cause(uint32_t);
 
 void 
 sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c
index 50dfc1c..20d645f 100644
--- a/freebsd/sys/netinet/tcp_input.c
+++ b/freebsd/sys/netinet/tcp_input.c
@@ -163,10 +163,10 @@ SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, rfc3390, CTLFLAG_RW,
 SYSCTL_NODE(_net_inet_tcp, OID_AUTO, experimental, CTLFLAG_RW, 0,
     "Experimental TCP extensions");
 
-VNET_DEFINE(int, tcp_do_initcwnd10) = 0;
+VNET_DEFINE(int, tcp_do_initcwnd10) = 1;
 SYSCTL_VNET_INT(_net_inet_tcp_experimental, OID_AUTO, initcwnd10, CTLFLAG_RW,
     &VNET_NAME(tcp_do_initcwnd10), 0,
-    "Enable draft-ietf-tcpm-initcwnd-05 (Increasing initial CWND to 10)");
+    "Enable RFC 6928 (Increasing initial CWND to 10)");
 
 VNET_DEFINE(int, tcp_do_rfc3465) = 1;
 SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, rfc3465, CTLFLAG_RW,
@@ -356,7 +356,7 @@ cc_conn_init(struct tcpcb *tp)
 	 *
 	 * RFC5681 Section 3.1 specifies the default conservative values.
 	 * RFC3390 specifies slightly more aggressive values.
-	 * Draft-ietf-tcpm-initcwnd-05 increases it to ten segments.
+	 * RFC6928 increases it to ten segments.
 	 *
 	 * If a SYN or SYN/ACK was lost and retransmitted, we have to
 	 * reduce the initial CWND to one segment as congestion is likely
diff --git a/freebsd/sys/netinet/tcp_reass.c b/freebsd/sys/netinet/tcp_reass.c
index aebda9d..d4f0bcd 100644
--- a/freebsd/sys/netinet/tcp_reass.c
+++ b/freebsd/sys/netinet/tcp_reass.c
@@ -207,7 +207,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
 	 * Investigate why and re-evaluate the below limit after the behaviour
 	 * is understood.
 	 */
-	if (th->th_seq != tp->rcv_nxt &&
+	if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) &&
 	    tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) {
 		V_tcp_reass_overflows++;
 		TCPSTAT_INC(tcps_rcvmemdrop);
@@ -230,7 +230,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
 	 */
 	te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT);
 	if (te == NULL) {
-		if (th->th_seq != tp->rcv_nxt) {
+		if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) {
 			TCPSTAT_INC(tcps_rcvmemdrop);
 			m_freem(m);
 			*tlenp = 0;
@@ -278,7 +278,8 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
 				TCPSTAT_INC(tcps_rcvduppack);
 				TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp);
 				m_freem(m);
-				uma_zfree(V_tcp_reass_zone, te);
+				if (te != &tqs)
+					uma_zfree(V_tcp_reass_zone, te);
 				tp->t_segqlen--;
 				/*
 				 * Try to present any queued data
diff --git a/freebsd/sys/netinet/tcp_subr.c b/freebsd/sys/netinet/tcp_subr.c
index 4c6d14e..d577f18 100644
--- a/freebsd/sys/netinet/tcp_subr.c
+++ b/freebsd/sys/netinet/tcp_subr.c
@@ -1747,9 +1747,10 @@ tcp_maxmtu(struct in_conninfo *inc, struct tcp_ifcap *cap)
 		/* Report additional interface capabilities. */
 		if (cap != NULL) {
 			if (ifp->if_capenable & IFCAP_TSO4 &&
-			    ifp->if_hwassist & CSUM_TSO)
+			    ifp->if_hwassist & CSUM_TSO) {
 				cap->ifcap |= CSUM_TSO;
 				cap->tsomax = ifp->if_hw_tsomax;
+			}
 		}
 		RTFREE(sro.ro_rt);
 	}
@@ -1785,9 +1786,10 @@ tcp_maxmtu6(struct in_conninfo *inc, struct tcp_ifcap *cap)
 		/* Report additional interface capabilities. */
 		if (cap != NULL) {
 			if (ifp->if_capenable & IFCAP_TSO6 &&
-			    ifp->if_hwassist & CSUM_TSO)
+			    ifp->if_hwassist & CSUM_TSO) {
 				cap->ifcap |= CSUM_TSO;
 				cap->tsomax = ifp->if_hw_tsomax;
+			}
 		}
 		RTFREE(sro6.ro_rt);
 	}
diff --git a/freebsd/sys/netinet6/frag6.c b/freebsd/sys/netinet6/frag6.c
index 8e6b068..28b2b46 100644
--- a/freebsd/sys/netinet6/frag6.c
+++ b/freebsd/sys/netinet6/frag6.c
@@ -224,9 +224,8 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 	offset += sizeof(struct ip6_frag);
 
 	/*
-	 * XXX-BZ RFC XXXX (draft-gont-6man-ipv6-atomic-fragments)
-	 * Handle "atomic" fragments (offset and m bit set to 0) upfront,
-	 * unrelated to any reassembly.  Just skip the fragment header.
+	 * RFC 6946: Handle "atomic" fragments (offset and m bit set to 0)
+	 * upfront, unrelated to any reassembly.  Just skip the fragment header.
 	 */
 	if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) {
 		/* XXX-BZ we want dedicated counters for this. */
diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c
index 32d50e9..20b03a2 100644
--- a/freebsd/sys/netinet6/icmp6.c
+++ b/freebsd/sys/netinet6/icmp6.c
@@ -1248,6 +1248,7 @@ icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated)
 		mtu = IPV6_MMTU - 8;
 
 	bzero(&inc, sizeof(inc));
+	inc.inc_fibnum = M_GETFIB(m);
 	inc.inc_flags |= INC_ISIPV6;
 	inc.inc6_faddr = *dst;
 	if (in6_setscope(&inc.inc6_faddr, m->m_pkthdr.rcvif, NULL))
diff --git a/freebsd/sys/netinet6/in6.c b/freebsd/sys/netinet6/in6.c
index eac5e11..f68f21f 100644
--- a/freebsd/sys/netinet6/in6.c
+++ b/freebsd/sys/netinet6/in6.c
@@ -2605,6 +2605,7 @@ in6_lltable_lookup(struct lltable *llt, u_int flags,
 	if (lle == NULL) {
 		if (!(flags & LLE_CREATE))
 			return (NULL);
+		IF_AFDATA_WLOCK_ASSERT(ifp);
 		/*
 		 * A route that covers the given address must have
 		 * been installed 1st because we are doing a resolution,
diff --git a/freebsd/sys/netinet6/in6_mcast.c b/freebsd/sys/netinet6/in6_mcast.c
index 55f2fab..e545770 100644
--- a/freebsd/sys/netinet6/in6_mcast.c
+++ b/freebsd/sys/netinet6/in6_mcast.c
@@ -133,7 +133,9 @@ static int	in6_mc_get(struct ifnet *, const struct in6_addr *,
 static int	in6m_get_source(struct in6_multi *inm,
 		    const struct in6_addr *addr, const int noalloc,
 		    struct ip6_msource **pims);
+#ifdef KTR
 static int	in6m_is_ifp_detached(const struct in6_multi *);
+#endif
 static int	in6m_merge(struct in6_multi *, /*const*/ struct in6_mfilter *);
 static void	in6m_purge(struct in6_multi *);
 static void	in6m_reap(struct in6_multi *);
@@ -177,6 +179,7 @@ static SYSCTL_NODE(_net_inet6_ip6_mcast, OID_AUTO, filters,
     CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_ip6_mcast_filters,
     "Per-interface stack-wide source filters");
 
+#ifdef KTR
 /*
  * Inline function which wraps assertions for a valid ifp.
  * The ifnet layer will set the ifma's ifp pointer to NULL if the ifp
@@ -199,6 +202,7 @@ in6m_is_ifp_detached(const struct in6_multi *inm)
 
 	return (ifp == NULL);
 }
+#endif
 
 /*
  * Initialize an in6_mfilter structure to a known state at t0, t1
@@ -1447,16 +1451,15 @@ in6p_block_unblock_source(struct inpcb *inp, struct sockopt *sopt)
 
 	CTR1(KTR_MLD, "%s: merge inm state", __func__);
 	error = in6m_merge(inm, imf);
-	if (error) {
+	if (error)
 		CTR1(KTR_MLD, "%s: failed to merge inm state", __func__);
-		goto out_im6f_rollback;
+	else {
+		CTR1(KTR_MLD, "%s: doing mld downcall", __func__);
+		error = mld_change_state(inm, 0);
+		if (error)
+			CTR1(KTR_MLD, "%s: failed mld downcall", __func__);
 	}
 
-	CTR1(KTR_MLD, "%s: doing mld downcall", __func__);
-	error = mld_change_state(inm, 0);
-	if (error)
-		CTR1(KTR_MLD, "%s: failed mld downcall", __func__);
-
 	IN6_MULTI_UNLOCK();
 
 out_im6f_rollback:
@@ -2044,29 +2047,27 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt)
 	if (is_new) {
 		error = in6_mc_join_locked(ifp, &gsa->sin6.sin6_addr, imf,
 		    &inm, 0);
-		if (error)
+		if (error) {
+			IN6_MULTI_UNLOCK();
 			goto out_im6o_free;
+		}
 		imo->im6o_membership[idx] = inm;
 	} else {
 		CTR1(KTR_MLD, "%s: merge inm state", __func__);
 		error = in6m_merge(inm, imf);
-		if (error) {
+		if (error)
 			CTR1(KTR_MLD, "%s: failed to merge inm state",
 			    __func__);
-			goto out_im6f_rollback;
-		}
-		CTR1(KTR_MLD, "%s: doing mld downcall", __func__);
-		error = mld_change_state(inm, 0);
-		if (error) {
-			CTR1(KTR_MLD, "%s: failed mld downcall",
-			    __func__);
-			goto out_im6f_rollback;
+		else {
+			CTR1(KTR_MLD, "%s: doing mld downcall", __func__);
+			error = mld_change_state(inm, 0);
+			if (error)
+				CTR1(KTR_MLD, "%s: failed mld downcall",
+				    __func__);
 		}
 	}
 
 	IN6_MULTI_UNLOCK();
-
-out_im6f_rollback:
 	INP_WLOCK_ASSERT(inp);
 	if (error) {
 		im6f_rollback(imf);
@@ -2293,23 +2294,20 @@ in6p_leave_group(struct inpcb *inp, struct sockopt *sopt)
 	} else {
 		CTR1(KTR_MLD, "%s: merge inm state", __func__);
 		error = in6m_merge(inm, imf);
-		if (error) {
+		if (error)
 			CTR1(KTR_MLD, "%s: failed to merge inm state",
 			    __func__);
-			goto out_im6f_rollback;
-		}
-
-		CTR1(KTR_MLD, "%s: doing mld downcall", __func__);
-		error = mld_change_state(inm, 0);
-		if (error) {
-			CTR1(KTR_MLD, "%s: failed mld downcall",
-			    __func__);
+		else {
+			CTR1(KTR_MLD, "%s: doing mld downcall", __func__);
+			error = mld_change_state(inm, 0);
+			if (error)
+				CTR1(KTR_MLD, "%s: failed mld downcall",
+				    __func__);
 		}
 	}
 
 	IN6_MULTI_UNLOCK();
 
-out_im6f_rollback:
 	if (error)
 		im6f_rollback(imf);
 	else
@@ -2518,16 +2516,15 @@ in6p_set_source_filters(struct inpcb *inp, struct sockopt *sopt)
 	 */
 	CTR1(KTR_MLD, "%s: merge inm state", __func__);
 	error = in6m_merge(inm, imf);
-	if (error) {
+	if (error)
 		CTR1(KTR_MLD, "%s: failed to merge inm state", __func__);
-		goto out_im6f_rollback;
+	else {
+		CTR1(KTR_MLD, "%s: doing mld downcall", __func__);
+		error = mld_change_state(inm, 0);
+		if (error)
+			CTR1(KTR_MLD, "%s: failed mld downcall", __func__);
 	}
 
-	CTR1(KTR_MLD, "%s: doing mld downcall", __func__);
-	error = mld_change_state(inm, 0);
-	if (error)
-		CTR1(KTR_MLD, "%s: failed mld downcall", __func__);
-
 	IN6_MULTI_UNLOCK();
 
 out_im6f_rollback:
diff --git a/freebsd/sys/netinet6/in6_pcb.c b/freebsd/sys/netinet6/in6_pcb.c
index 4d607f7..4b0b338 100644
--- a/freebsd/sys/netinet6/in6_pcb.c
+++ b/freebsd/sys/netinet6/in6_pcb.c
@@ -164,7 +164,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
 			 * and a multicast address is bound on both
 			 * new and duplicated sockets.
 			 */
-			if (so->so_options & SO_REUSEADDR)
+			if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) != 0)
 				reuseport = SO_REUSEADDR|SO_REUSEPORT;
 		} else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
 			struct ifaddr *ifa;
diff --git a/freebsd/sys/netinet6/ip6_forward.c b/freebsd/sys/netinet6/ip6_forward.c
index 2b45804..c45ab10 100644
--- a/freebsd/sys/netinet6/ip6_forward.c
+++ b/freebsd/sys/netinet6/ip6_forward.c
@@ -565,10 +565,8 @@ skip_routing:
 	odst = ip6->ip6_dst;
 	/* Run through list of hooks for output packets. */
 	error = pfil_run_hooks(&V_inet6_pfil_hook, &m, rt->rt_ifp, PFIL_OUT, NULL);
-	if (error != 0)
-		goto senderr;
-	if (m == NULL)
-		goto freecopy;
+	if (error != 0 || m == NULL)
+		goto freecopy;		/* consumed by filter */
 	ip6 = mtod(m, struct ip6_hdr *);
 
 	/* See if destination IP address was changed by packet filter. */
@@ -637,7 +635,6 @@ pass:
 		}
 	}
 
-senderr:
 	if (mcopy == NULL)
 		goto out;
 	switch (error) {
diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c
index aba38ec..0de64eb 100644
--- a/freebsd/sys/netinet6/ip6_input.c
+++ b/freebsd/sys/netinet6/ip6_input.c
@@ -560,7 +560,18 @@ ip6_input(struct mbuf *m)
 		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
 		goto bad;
 	}
-
+	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) &&
+	    IPV6_ADDR_MC_SCOPE(&ip6->ip6_dst) == 0) {
+		/*
+		 * RFC4291 2.7:
+		 * Nodes must not originate a packet to a multicast address
+		 * whose scop field contains the reserved value 0; if such
+		 * a packet is received, it must be silently dropped.
+		 */
+		IP6STAT_INC(ip6s_badscope);
+		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
+		goto bad;
+	}
 #ifdef ALTQ
 	if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) {
 		/* packet is dropped by traffic conditioner */
@@ -1076,7 +1087,6 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,
 	struct mbuf *m = *mp;
 	int off = *offp, hbhlen;
 	struct ip6_hbh *hbh;
-	u_int8_t *opt;
 
 	/* validation of the length of the header */
 #ifndef PULLDOWN_TEST
@@ -1103,8 +1113,6 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,
 #endif
 	off += hbhlen;
 	hbhlen -= sizeof(struct ip6_hbh);
-	opt = (u_int8_t *)hbh + sizeof(struct ip6_hbh);
-
 	if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
 				hbhlen, rtalertp, plenp) < 0)
 		return (-1);
diff --git a/freebsd/sys/netinet6/ip6_mroute.c b/freebsd/sys/netinet6/ip6_mroute.c
index 00eab8e..044b96b 100644
--- a/freebsd/sys/netinet6/ip6_mroute.c
+++ b/freebsd/sys/netinet6/ip6_mroute.c
@@ -220,6 +220,14 @@ static VNET_DEFINE(u_int, mrt6debug) = 0;	/* debug level */
 #define DEBUG_XMIT	0x10
 #define DEBUG_REG	0x20
 #define DEBUG_PIM	0x40
+#define	DEBUG_ERR	0x80
+#define	DEBUG_ANY	0x7f
+#define	MRT6_DLOG(m, fmt, ...)	\
+	if (V_mrt6debug & (m))	\
+		log(((m) & DEBUG_ERR) ? LOG_ERR: LOG_DEBUG, \
+		    "%s: " fmt "\n", __func__, ##__VA_ARGS__)
+#else
+#define	MRT6_DLOG(m, fmt, ...)
 #endif
 
 static void	expire_upcalls(void *);
@@ -274,7 +282,6 @@ static VNET_DEFINE(int, pim6);
 #define MF6CFIND(o, g, rt) do { \
 	struct mf6c *_rt = mf6ctable[MF6CHASH(o,g)]; \
 	rt = NULL; \
-	MRT6STAT_INC(mrt6s_mfc_lookups); \
 	while (_rt) { \
 		if (IN6_ARE_ADDR_EQUAL(&_rt->mf6c_origin.sin6_addr, &(o)) && \
 		    IN6_ARE_ADDR_EQUAL(&_rt->mf6c_mcastgrp.sin6_addr, &(g)) && \
@@ -525,12 +532,8 @@ static int
 ip6_mrouter_init(struct socket *so, int v, int cmd)
 {
 
-#ifdef MRT6DEBUG
-	if (V_mrt6debug)
-		log(LOG_DEBUG,
-		    "ip6_mrouter_init: so_type = %d, pr_protocol = %d\n",
-		    so->so_type, so->so_proto->pr_protocol);
-#endif
+	MRT6_DLOG(DEBUG_ANY, "so_type = %d, pr_protocol = %d",
+	    so->so_type, so->so_proto->pr_protocol);
 
 	if (so->so_type != SOCK_RAW ||
 	    so->so_proto->pr_protocol != IPPROTO_ICMPV6)
@@ -559,11 +562,7 @@ ip6_mrouter_init(struct socket *so, int v, int cmd)
 	    expire_upcalls, NULL);
 
 	MROUTER6_UNLOCK();
-
-#ifdef MRT6DEBUG
-	if (V_mrt6debug)
-		log(LOG_DEBUG, "ip6_mrouter_init\n");
-#endif
+	MRT6_DLOG(DEBUG_ANY, "finished");
 
 	return (0);
 }
@@ -575,7 +574,7 @@ int
 X_ip6_mrouter_done(void)
 {
 	mifi_t mifi;
-	int i;
+	u_long i;
 	struct mf6c *rt;
 	struct rtdetq *rte;
 
@@ -641,11 +640,7 @@ X_ip6_mrouter_done(void)
 	V_ip6_mrouter_ver = 0;
 
 	MROUTER6_UNLOCK();
-
-#ifdef MRT6DEBUG
-	if (V_mrt6debug)
-		log(LOG_DEBUG, "ip6_mrouter_done\n");
-#endif
+	MRT6_DLOG(DEBUG_ANY, "finished");
 
 	return (0);
 }
@@ -726,14 +721,8 @@ add_m6if(struct mif6ctl *mifcp)
 		nummifs = mifcp->mif6c_mifi + 1;
 
 	MIF6_UNLOCK();
-
-#ifdef MRT6DEBUG
-	if (V_mrt6debug)
-		log(LOG_DEBUG,
-		    "add_mif #%d, phyint %s\n",
-		    mifcp->mif6c_mifi,
-		    ifp->if_xname);
-#endif
+	MRT6_DLOG(DEBUG_ANY, "mif #%d, phyint %s", mifcp->mif6c_mifi,
+	    if_name(ifp));
 
 	return (0);
 }
@@ -776,11 +765,7 @@ del_m6if_locked(mifi_t *mifip)
 		if (mif6table[mifi - 1].m6_ifp)
 			break;
 	nummifs = mifi;
-
-#ifdef MRT6DEBUG
-	if (V_mrt6debug)
-		log(LOG_DEBUG, "del_m6if %d, nummifs %d\n", *mifip, nummifs);
-#endif
+	MRT6_DLOG(DEBUG_ANY, "mif %d, nummifs %d", *mifip, nummifs);
 
 	return (0);
 }
@@ -816,15 +801,10 @@ add_m6fc(struct mf6cctl *mfccp)
 
 	/* If an entry already exists, just update the fields */
 	if (rt) {
-#ifdef MRT6DEBUG
-		if (V_mrt6debug & DEBUG_MFC) {
-		    log(LOG_DEBUG,
-			"add_m6fc no upcall h %d o %s g %s p %x\n",
-			ip6_sprintf(ip6bufo, &mfccp->mf6cc_origin.sin6_addr),
-			ip6_sprintf(ip6bufg, &mfccp->mf6cc_mcastgrp.sin6_addr),
-			mfccp->mf6cc_parent);
-		}
-#endif
+		MRT6_DLOG(DEBUG_MFC, "no upcall o %s g %s p %x",
+		    ip6_sprintf(ip6bufo, &mfccp->mf6cc_origin.sin6_addr),
+		    ip6_sprintf(ip6bufg, &mfccp->mf6cc_mcastgrp.sin6_addr),
+		    mfccp->mf6cc_parent);
 
 		rt->mf6c_parent = mfccp->mf6cc_parent;
 		rt->mf6c_ifset = mfccp->mf6cc_ifset;
@@ -855,16 +835,12 @@ add_m6fc(struct mf6cctl *mfccp)
 					    &mfccp->mf6cc_mcastgrp.sin6_addr),
 				    mfccp->mf6cc_parent, rt->mf6c_stall);
 
-#ifdef MRT6DEBUG
-			if (V_mrt6debug & DEBUG_MFC)
-				log(LOG_DEBUG,
-				    "add_m6fc o %s g %s p %x dbg %x\n",
-				    ip6_sprintf(ip6bufo,
-					    &mfccp->mf6cc_origin.sin6_addr),
-				    ip6_sprintf(ip6bufg,
-					    &mfccp->mf6cc_mcastgrp.sin6_addr),
-				    mfccp->mf6cc_parent, rt->mf6c_stall);
-#endif
+			MRT6_DLOG(DEBUG_MFC, "o %s g %s p %x dbg %p",
+			    ip6_sprintf(ip6bufo,
+			    &mfccp->mf6cc_origin.sin6_addr),
+			    ip6_sprintf(ip6bufg,
+				&mfccp->mf6cc_mcastgrp.sin6_addr),
+			    mfccp->mf6cc_parent, rt->mf6c_stall);
 
 			rt->mf6c_origin     = mfccp->mf6cc_origin;
 			rt->mf6c_mcastgrp   = mfccp->mf6cc_mcastgrp;
@@ -897,15 +873,10 @@ add_m6fc(struct mf6cctl *mfccp)
 	 * It is possible that an entry is being inserted without an upcall
 	 */
 	if (nstl == 0) {
-#ifdef MRT6DEBUG
-		if (V_mrt6debug & DEBUG_MFC)
-		    log(LOG_DEBUG,
-			"add_mfc no upcall h %d o %s g %s p %x\n",
-			hash,
-			ip6_sprintf(ip6bufo, &mfccp->mf6cc_origin.sin6_addr),
-			ip6_sprintf(ip6bufg, &mfccp->mf6cc_mcastgrp.sin6_addr),
-			mfccp->mf6cc_parent);
-#endif
+		MRT6_DLOG(DEBUG_MFC, "no upcall h %lu o %s g %s p %x", hash,
+		    ip6_sprintf(ip6bufo, &mfccp->mf6cc_origin.sin6_addr),
+		    ip6_sprintf(ip6bufg, &mfccp->mf6cc_mcastgrp.sin6_addr),
+		    mfccp->mf6cc_parent);
 
 		for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) {
 
@@ -991,6 +962,9 @@ collate(struct timeval *t)
 static int
 del_m6fc(struct mf6cctl *mfccp)
 {
+#ifdef MRT6DEBUG
+	char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
+#endif
 	struct sockaddr_in6	origin;
 	struct sockaddr_in6	mcastgrp;
 	struct mf6c		*rt;
@@ -1001,14 +975,9 @@ del_m6fc(struct mf6cctl *mfccp)
 	mcastgrp = mfccp->mf6cc_mcastgrp;
 	hash = MF6CHASH(origin.sin6_addr, mcastgrp.sin6_addr);
 
-#ifdef MRT6DEBUG
-	if (V_mrt6debug & DEBUG_MFC) {
-		char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
-		log(LOG_DEBUG,"del_m6fc orig %s mcastgrp %s\n",
-		    ip6_sprintf(ip6bufo, &origin.sin6_addr),
-		    ip6_sprintf(ip6bufg, &mcastgrp.sin6_addr));
-	}
-#endif
+	MRT6_DLOG(DEBUG_MFC, "orig %s mcastgrp %s",
+	    ip6_sprintf(ip6bufo, &origin.sin6_addr),
+	    ip6_sprintf(ip6bufg, &mcastgrp.sin6_addr));
 
 	MFC6_LOCK();
 
@@ -1073,19 +1042,23 @@ socket_send(struct socket *s, struct mbuf *mm, struct sockaddr_in6 *src)
 int
 X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m)
 {
+	struct rtdetq *rte;
+	struct mbuf *mb0;
 	struct mf6c *rt;
 	struct mif6 *mifp;
 	struct mbuf *mm;
+	u_long hash;
 	mifi_t mifi;
 	char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+#ifdef UPCALL_TIMING
+	struct timeval tp;
 
-#ifdef MRT6DEBUG
-	if (V_mrt6debug & DEBUG_FORWARD)
-		log(LOG_DEBUG, "ip6_mforward: src %s, dst %s, ifindex %d\n",
-		    ip6_sprintf(ip6bufs, &ip6->ip6_src),
-		    ip6_sprintf(ip6bufd, &ip6->ip6_dst),
-		    ifp->if_index);
-#endif
+	GET_TIME(tp);
+#endif /* UPCALL_TIMING */
+
+	MRT6_DLOG(DEBUG_FORWARD, "src %s, dst %s, ifindex %d",
+	    ip6_sprintf(ip6bufs, &ip6->ip6_src),
+	    ip6_sprintf(ip6bufd, &ip6->ip6_dst), ifp->if_index);
 
 	/*
 	 * Don't forward a packet with Hop limit of zero or one,
@@ -1124,211 +1097,184 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m)
 	 * Determine forwarding mifs from the forwarding cache table
 	 */
 	MF6CFIND(ip6->ip6_src, ip6->ip6_dst, rt);
+	MRT6STAT_INC(mrt6s_mfc_lookups);
 
 	/* Entry exists, so forward if necessary */
 	if (rt) {
 		MFC6_UNLOCK();
 		return (ip6_mdq(m, ifp, rt));
-	} else {
-		/*
-		 * If we don't have a route for packet's origin,
-		 * Make a copy of the packet &
-		 * send message to routing daemon
-		 */
+	}
 
-		struct mbuf *mb0;
-		struct rtdetq *rte;
-		u_long hash;
-/*		int i, npkts;*/
-#ifdef UPCALL_TIMING
-		struct timeval tp;
+	/*
+	 * If we don't have a route for packet's origin,
+	 * Make a copy of the packet & send message to routing daemon.
+	 */
+	MRT6STAT_INC(mrt6s_no_route);
+	MRT6_DLOG(DEBUG_FORWARD | DEBUG_MFC, "no rte s %s g %s",
+	    ip6_sprintf(ip6bufs, &ip6->ip6_src),
+	    ip6_sprintf(ip6bufd, &ip6->ip6_dst));
 
-		GET_TIME(tp);
-#endif /* UPCALL_TIMING */
+	/*
+	 * Allocate mbufs early so that we don't do extra work if we
+	 * are just going to fail anyway.
+	 */
+	rte = (struct rtdetq *)malloc(sizeof(*rte), M_MRTABLE6, M_NOWAIT);
+	if (rte == NULL) {
+		MFC6_UNLOCK();
+		return (ENOBUFS);
+	}
+	mb0 = m_copy(m, 0, M_COPYALL);
+	/*
+	 * Pullup packet header if needed before storing it,
+	 * as other references may modify it in the meantime.
+	 */
+	if (mb0 && (M_HASCL(mb0) || mb0->m_len < sizeof(struct ip6_hdr)))
+		mb0 = m_pullup(mb0, sizeof(struct ip6_hdr));
+	if (mb0 == NULL) {
+		free(rte, M_MRTABLE6);
+		MFC6_UNLOCK();
+		return (ENOBUFS);
+	}
 
-		MRT6STAT_INC(mrt6s_no_route);
-#ifdef MRT6DEBUG
-		if (V_mrt6debug & (DEBUG_FORWARD | DEBUG_MFC))
-			log(LOG_DEBUG, "ip6_mforward: no rte s %s g %s\n",
-			    ip6_sprintf(ip6bufs, &ip6->ip6_src),
-			    ip6_sprintf(ip6bufd, &ip6->ip6_dst));
-#endif
+	/* is there an upcall waiting for this packet? */
+	hash = MF6CHASH(ip6->ip6_src, ip6->ip6_dst);
+	for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) {
+		if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_src,
+		    &rt->mf6c_origin.sin6_addr) &&
+		    IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
+		    &rt->mf6c_mcastgrp.sin6_addr) && (rt->mf6c_stall != NULL))
+			break;
+	}
 
-		/*
-		 * Allocate mbufs early so that we don't do extra work if we
-		 * are just going to fail anyway.
-		 */
-		rte = (struct rtdetq *)malloc(sizeof(*rte), M_MRTABLE6,
-					      M_NOWAIT);
-		if (rte == NULL) {
+	if (rt == NULL) {
+		struct mrt6msg *im;
+#ifdef MRT6_OINIT
+		struct omrt6msg *oim;
+#endif
+		/* no upcall, so make a new entry */
+		rt = (struct mf6c *)malloc(sizeof(*rt), M_MRTABLE6, M_NOWAIT);
+		if (rt == NULL) {
+			free(rte, M_MRTABLE6);
+			m_freem(mb0);
 			MFC6_UNLOCK();
 			return (ENOBUFS);
 		}
-		mb0 = m_copy(m, 0, M_COPYALL);
 		/*
-		 * Pullup packet header if needed before storing it,
-		 * as other references may modify it in the meantime.
+		 * Make a copy of the header to send to the user
+		 * level process
 		 */
-		if (mb0 &&
-		    (M_HASCL(mb0) || mb0->m_len < sizeof(struct ip6_hdr)))
-			mb0 = m_pullup(mb0, sizeof(struct ip6_hdr));
-		if (mb0 == NULL) {
+		mm = m_copy(mb0, 0, sizeof(struct ip6_hdr));
+		if (mm == NULL) {
 			free(rte, M_MRTABLE6);
+			m_freem(mb0);
+			free(rt, M_MRTABLE6);
 			MFC6_UNLOCK();
 			return (ENOBUFS);
 		}
 
-		/* is there an upcall waiting for this packet? */
-		hash = MF6CHASH(ip6->ip6_src, ip6->ip6_dst);
-		for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) {
-			if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_src,
-					       &rt->mf6c_origin.sin6_addr) &&
-			    IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
-					       &rt->mf6c_mcastgrp.sin6_addr) &&
-			    (rt->mf6c_stall != NULL))
-				break;
-		}
-
-		if (rt == NULL) {
-			struct mrt6msg *im;
-#ifdef MRT6_OINIT
-			struct omrt6msg *oim;
-#endif
-
-			/* no upcall, so make a new entry */
-			rt = (struct mf6c *)malloc(sizeof(*rt), M_MRTABLE6,
-						  M_NOWAIT);
-			if (rt == NULL) {
-				free(rte, M_MRTABLE6);
-				m_freem(mb0);
-				MFC6_UNLOCK();
-				return (ENOBUFS);
-			}
-			/*
-			 * Make a copy of the header to send to the user
-			 * level process
-			 */
-			mm = m_copy(mb0, 0, sizeof(struct ip6_hdr));
-
-			if (mm == NULL) {
-				free(rte, M_MRTABLE6);
-				m_freem(mb0);
-				free(rt, M_MRTABLE6);
-				MFC6_UNLOCK();
-				return (ENOBUFS);
-			}
-
-			/*
-			 * Send message to routing daemon
-			 */
-			sin6.sin6_addr = ip6->ip6_src;
-
-			im = NULL;
+		/*
+		 * Send message to routing daemon
+		 */
+		sin6.sin6_addr = ip6->ip6_src;
+		im = NULL;
 #ifdef MRT6_OINIT
-			oim = NULL;
+		oim = NULL;
 #endif
-			switch (V_ip6_mrouter_ver) {
+		switch (V_ip6_mrouter_ver) {
 #ifdef MRT6_OINIT
-			case MRT6_OINIT:
-				oim = mtod(mm, struct omrt6msg *);
-				oim->im6_msgtype = MRT6MSG_NOCACHE;
-				oim->im6_mbz = 0;
-				break;
-#endif
-			case MRT6_INIT:
-				im = mtod(mm, struct mrt6msg *);
-				im->im6_msgtype = MRT6MSG_NOCACHE;
-				im->im6_mbz = 0;
-				break;
-			default:
-				free(rte, M_MRTABLE6);
-				m_freem(mb0);
-				free(rt, M_MRTABLE6);
-				MFC6_UNLOCK();
-				return (EINVAL);
-			}
-
-#ifdef MRT6DEBUG
-			if (V_mrt6debug & DEBUG_FORWARD)
-				log(LOG_DEBUG,
-				    "getting the iif info in the kernel\n");
+		case MRT6_OINIT:
+			oim = mtod(mm, struct omrt6msg *);
+			oim->im6_msgtype = MRT6MSG_NOCACHE;
+			oim->im6_mbz = 0;
+			break;
 #endif
+		case MRT6_INIT:
+			im = mtod(mm, struct mrt6msg *);
+			im->im6_msgtype = MRT6MSG_NOCACHE;
+			im->im6_mbz = 0;
+			break;
+		default:
+			free(rte, M_MRTABLE6);
+			m_freem(mb0);
+			free(rt, M_MRTABLE6);
+			MFC6_UNLOCK();
+			return (EINVAL);
+		}
 
-			for (mifp = mif6table, mifi = 0;
-			     mifi < nummifs && mifp->m6_ifp != ifp;
-			     mifp++, mifi++)
+		MRT6_DLOG(DEBUG_FORWARD, "getting the iif info in the kernel");
+		for (mifp = mif6table, mifi = 0;
+		    mifi < nummifs && mifp->m6_ifp != ifp; mifp++, mifi++)
 				;
 
-			switch (V_ip6_mrouter_ver) {
+		switch (V_ip6_mrouter_ver) {
 #ifdef MRT6_OINIT
-			case MRT6_OINIT:
-				oim->im6_mif = mifi;
-				break;
+		case MRT6_OINIT:
+			oim->im6_mif = mifi;
+			break;
 #endif
-			case MRT6_INIT:
-				im->im6_mif = mifi;
-				break;
-			}
+		case MRT6_INIT:
+			im->im6_mif = mifi;
+			break;
+		}
+
+		if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) {
+			log(LOG_WARNING, "ip6_mforward: ip6_mrouter "
+			    "socket queue full\n");
+			MRT6STAT_INC(mrt6s_upq_sockfull);
+			free(rte, M_MRTABLE6);
+			m_freem(mb0);
+			free(rt, M_MRTABLE6);
+			MFC6_UNLOCK();
+			return (ENOBUFS);
+		}
+
+		MRT6STAT_INC(mrt6s_upcalls);
+
+		/* insert new entry at head of hash chain */
+		bzero(rt, sizeof(*rt));
+		rt->mf6c_origin.sin6_family = AF_INET6;
+		rt->mf6c_origin.sin6_len = sizeof(struct sockaddr_in6);
+		rt->mf6c_origin.sin6_addr = ip6->ip6_src;
+		rt->mf6c_mcastgrp.sin6_family = AF_INET6;
+		rt->mf6c_mcastgrp.sin6_len = sizeof(struct sockaddr_in6);
+		rt->mf6c_mcastgrp.sin6_addr = ip6->ip6_dst;
+		rt->mf6c_expire = UPCALL_EXPIRE;
+		n6expire[hash]++;
+		rt->mf6c_parent = MF6C_INCOMPLETE_PARENT;
+
+		/* link into table */
+		rt->mf6c_next  = mf6ctable[hash];
+		mf6ctable[hash] = rt;
+		/* Add this entry to the end of the queue */
+		rt->mf6c_stall = rte;
+	} else {
+		/* determine if q has overflowed */
+		struct rtdetq **p;
+		int npkts = 0;
 
-			if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) {
-				log(LOG_WARNING, "ip6_mforward: ip6_mrouter "
-				    "socket queue full\n");
-				MRT6STAT_INC(mrt6s_upq_sockfull);
+		for (p = &rt->mf6c_stall; *p != NULL; p = &(*p)->next)
+			if (++npkts > MAX_UPQ6) {
+				MRT6STAT_INC(mrt6s_upq_ovflw);
 				free(rte, M_MRTABLE6);
 				m_freem(mb0);
-				free(rt, M_MRTABLE6);
 				MFC6_UNLOCK();
-				return (ENOBUFS);
+				return (0);
 			}
 
-			MRT6STAT_INC(mrt6s_upcalls);
-
-			/* insert new entry at head of hash chain */
-			bzero(rt, sizeof(*rt));
-			rt->mf6c_origin.sin6_family = AF_INET6;
-			rt->mf6c_origin.sin6_len = sizeof(struct sockaddr_in6);
-			rt->mf6c_origin.sin6_addr = ip6->ip6_src;
-			rt->mf6c_mcastgrp.sin6_family = AF_INET6;
-			rt->mf6c_mcastgrp.sin6_len = sizeof(struct sockaddr_in6);
-			rt->mf6c_mcastgrp.sin6_addr = ip6->ip6_dst;
-			rt->mf6c_expire = UPCALL_EXPIRE;
-			n6expire[hash]++;
-			rt->mf6c_parent = MF6C_INCOMPLETE_PARENT;
-
-			/* link into table */
-			rt->mf6c_next  = mf6ctable[hash];
-			mf6ctable[hash] = rt;
-			/* Add this entry to the end of the queue */
-			rt->mf6c_stall = rte;
-		} else {
-			/* determine if q has overflowed */
-			struct rtdetq **p;
-			int npkts = 0;
-
-			for (p = &rt->mf6c_stall; *p != NULL; p = &(*p)->next)
-				if (++npkts > MAX_UPQ6) {
-					MRT6STAT_INC(mrt6s_upq_ovflw);
-					free(rte, M_MRTABLE6);
-					m_freem(mb0);
-					MFC6_UNLOCK();
-					return (0);
-				}
-
-			/* Add this entry to the end of the queue */
-			*p = rte;
-		}
+		/* Add this entry to the end of the queue */
+		*p = rte;
+	}
 
-		rte->next = NULL;
-		rte->m = mb0;
-		rte->ifp = ifp;
+	rte->next = NULL;
+	rte->m = mb0;
+	rte->ifp = ifp;
 #ifdef UPCALL_TIMING
-		rte->t = tp;
+	rte->t = tp;
 #endif /* UPCALL_TIMING */
 
-		MFC6_UNLOCK();
+	MFC6_UNLOCK();
 
-		return (0);
-	}
+	return (0);
 }
 
 /*
@@ -1338,9 +1284,12 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m)
 static void
 expire_upcalls(void *unused)
 {
+#ifdef MRT6DEBUG
+	char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
+#endif
 	struct rtdetq *rte;
 	struct mf6c *mfc, **nptr;
-	int i;
+	u_long i;
 
 	MFC6_LOCK();
 	for (i = 0; i < MF6CTBLSIZ; i++) {
@@ -1357,15 +1306,9 @@ expire_upcalls(void *unused)
 			if (rte != NULL &&
 			    mfc->mf6c_expire != 0 &&
 			    --mfc->mf6c_expire == 0) {
-#ifdef MRT6DEBUG
-				if (V_mrt6debug & DEBUG_EXPIRE) {
-					char ip6bufo[INET6_ADDRSTRLEN];
-					char ip6bufg[INET6_ADDRSTRLEN];
-					log(LOG_DEBUG, "expire_upcalls: expiring (%s %s)\n",
-					    ip6_sprintf(ip6bufo, &mfc->mf6c_origin.sin6_addr),
-					    ip6_sprintf(ip6bufg, &mfc->mf6c_mcastgrp.sin6_addr));
-				}
-#endif
+				MRT6_DLOG(DEBUG_EXPIRE, "expiring (%s %s)",
+				    ip6_sprintf(ip6bufo, &mfc->mf6c_origin.sin6_addr),
+				    ip6_sprintf(ip6bufg, &mfc->mf6c_mcastgrp.sin6_addr));
 				/*
 				 * drop all the packets
 				 * free the mbuf with the pkt, if, timing info
@@ -1425,13 +1368,9 @@ ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct mf6c *rt)
 	mifi = rt->mf6c_parent;
 	if ((mifi >= nummifs) || (mif6table[mifi].m6_ifp != ifp)) {
 		/* came in the wrong interface */
-#ifdef MRT6DEBUG
-		if (V_mrt6debug & DEBUG_FORWARD)
-			log(LOG_DEBUG,
-			    "wrong if: ifid %d mifi %d mififid %x\n",
-			    ifp->if_index, mifi,
-			    mif6table[mifi].m6_ifp->if_index);
-#endif
+		MRT6_DLOG(DEBUG_FORWARD,
+		    "wrong if: ifid %d mifi %d mififid %x", ifp->if_index,
+		    mifi, mif6table[mifi].m6_ifp->if_index);
 		MRT6STAT_INC(mrt6s_wrong_if);
 		rt->mf6c_wrong_if++;
 		/*
@@ -1508,10 +1447,8 @@ ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct mf6c *rt)
 				MRT6STAT_INC(mrt6s_upcalls);
 
 				if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) {
-#ifdef MRT6DEBUG
-					if (V_mrt6debug)
-						log(LOG_WARNING, "mdq, ip6_mrouter socket queue full\n");
-#endif
+					MRT6_DLOG(DEBUG_ANY,
+					    "ip6_mrouter socket queue full");
 					MRT6STAT_INC(mrt6s_upq_sockfull);
 					return (ENOBUFS);
 				}	/* if socket Q full */
@@ -1575,6 +1512,9 @@ ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct mf6c *rt)
 static void
 phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
 {
+#ifdef MRT6DEBUG
+	char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+#endif
 	struct mbuf *mb_copy;
 	struct ifnet *ifp = mifp->m6_ifp;
 	int error = 0;
@@ -1612,11 +1552,8 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
 		error = ip6_output(mb_copy, NULL, NULL, IPV6_FORWARDING, &im6o,
 		    NULL, NULL);
 
-#ifdef MRT6DEBUG
-		if (V_mrt6debug & DEBUG_XMIT)
-			log(LOG_DEBUG, "phyint_send on mif %d err %d\n",
-			    mifp - mif6table, error);
-#endif
+		MRT6_DLOG(DEBUG_XMIT, "mif %u err %d",
+		    (uint16_t)(mifp - mif6table), error);
 		return;
 	}
 
@@ -1652,11 +1589,8 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
 		 */
 		error = (*ifp->if_output)(ifp, mb_copy,
 		    (struct sockaddr *)&dst6, NULL);
-#ifdef MRT6DEBUG
-		if (V_mrt6debug & DEBUG_XMIT)
-			log(LOG_DEBUG, "phyint_send on mif %d err %d\n",
-			    mifp - mif6table, error);
-#endif
+		MRT6_DLOG(DEBUG_XMIT, "mif %u err %d",
+		    (uint16_t)(mifp - mif6table), error);
 	} else {
 		/*
 		 * pMTU discovery is intentionally disabled by default, since
@@ -1666,19 +1600,11 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
 		if (V_ip6_mcast_pmtu)
 			icmp6_error(mb_copy, ICMP6_PACKET_TOO_BIG, 0, linkmtu);
 		else {
-#ifdef MRT6DEBUG
-			if (V_mrt6debug & DEBUG_XMIT) {
-				char ip6bufs[INET6_ADDRSTRLEN];
-				char ip6bufd[INET6_ADDRSTRLEN];
-				log(LOG_DEBUG,
-				    "phyint_send: packet too big on %s o %s "
-				    "g %s size %d(discarded)\n",
-				    if_name(ifp),
-				    ip6_sprintf(ip6bufs, &ip6->ip6_src),
-				    ip6_sprintf(ip6bufd, &ip6->ip6_dst),
-				    mb_copy->m_pkthdr.len);
-			}
-#endif /* MRT6DEBUG */
+			MRT6_DLOG(DEBUG_XMIT, " packet too big on %s o %s "
+			    "g %s size %d (discarded)", if_name(ifp),
+			    ip6_sprintf(ip6bufs, &ip6->ip6_src),
+			    ip6_sprintf(ip6bufd, &ip6->ip6_dst),
+			    mb_copy->m_pkthdr.len);
 			m_freem(mb_copy); /* simply discard the packet */
 		}
 	}
@@ -1687,19 +1613,17 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
 static int
 register_send(struct ip6_hdr *ip6, struct mif6 *mif, struct mbuf *m)
 {
+#ifdef MRT6DEBUG
+	char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+#endif
 	struct mbuf *mm;
 	int i, len = m->m_pkthdr.len;
 	static struct sockaddr_in6 sin6 = { sizeof(sin6), AF_INET6 };
 	struct mrt6msg *im6;
 
-#ifdef MRT6DEBUG
-	if (V_mrt6debug) {
-		char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
-		log(LOG_DEBUG, "** IPv6 register_send **\n src %s dst %s\n",
-		    ip6_sprintf(ip6bufs, &ip6->ip6_src),
-		    ip6_sprintf(ip6bufd, &ip6->ip6_dst));
-	}
-#endif
+	MRT6_DLOG(DEBUG_ANY, "src %s dst %s",
+	    ip6_sprintf(ip6bufs, &ip6->ip6_src),
+	    ip6_sprintf(ip6bufd, &ip6->ip6_dst));
 	PIM6STAT_INC(pim6s_snd_registers);
 
 	/* Make a copy of the packet to send to the user level process */
@@ -1738,11 +1662,7 @@ register_send(struct ip6_hdr *ip6, struct mif6 *mif, struct mbuf *m)
 	MRT6STAT_INC(mrt6s_upcalls);
 
 	if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) {
-#ifdef MRT6DEBUG
-		if (V_mrt6debug)
-			log(LOG_WARNING,
-			    "register_send: ip6_mrouter socket queue full\n");
-#endif
+		MRT6_DLOG(DEBUG_ANY, "ip6_mrouter socket queue full");
 		MRT6STAT_INC(mrt6s_upq_sockfull);
 		return (ENOBUFS);
 	}
@@ -1794,10 +1714,7 @@ pim6_input(struct mbuf **mp, int *offp, int proto)
 	 */
 	if (pimlen < PIM_MINLEN) {
 		PIM6STAT_INC(pim6s_rcv_tooshort);
-#ifdef MRT6DEBUG
-		if (V_mrt6debug & DEBUG_PIM)
-			log(LOG_DEBUG,"pim6_input: PIM packet too short\n");
-#endif
+		MRT6_DLOG(DEBUG_PIM, "PIM packet too short");
 		m_freem(m);
 		return (IPPROTO_DONE);
 	}
@@ -1847,11 +1764,7 @@ pim6_input(struct mbuf **mp, int *offp, int proto)
 
 		if (in6_cksum(m, IPPROTO_PIM, off, cksumlen)) {
 			PIM6STAT_INC(pim6s_rcv_badsum);
-#ifdef MRT6DEBUG
-			if (V_mrt6debug & DEBUG_PIM)
-				log(LOG_DEBUG,
-				    "pim6_input: invalid checksum\n");
-#endif
+			MRT6_DLOG(DEBUG_PIM, "invalid checksum");
 			m_freem(m);
 			return (IPPROTO_DONE);
 		}
@@ -1861,11 +1774,9 @@ pim6_input(struct mbuf **mp, int *offp, int proto)
 	/* PIM version check */
 	if (pim->pim_ver != PIM_VERSION) {
 		PIM6STAT_INC(pim6s_rcv_badversion);
-#ifdef MRT6DEBUG
-		log(LOG_ERR,
-		    "pim6_input: incorrect version %d, expecting %d\n",
+		MRT6_DLOG(DEBUG_ANY | DEBUG_ERR,
+		    "incorrect version %d, expecting %d",
 		    pim->pim_ver, PIM_VERSION);
-#endif
 		m_freem(m);
 		return (IPPROTO_DONE);
 	}
@@ -1889,12 +1800,8 @@ pim6_input(struct mbuf **mp, int *offp, int proto)
 		PIM6STAT_INC(pim6s_rcv_registers);
 
 		if ((reg_mif_num >= nummifs) || (reg_mif_num == (mifi_t) -1)) {
-#ifdef MRT6DEBUG
-			if (V_mrt6debug & DEBUG_PIM)
-				log(LOG_DEBUG,
-				    "pim6_input: register mif not set: %d\n",
-				    reg_mif_num);
-#endif
+			MRT6_DLOG(DEBUG_PIM, "register mif not set: %d",
+			    reg_mif_num);
 			m_freem(m);
 			return (IPPROTO_DONE);
 		}
@@ -1910,35 +1817,25 @@ pim6_input(struct mbuf **mp, int *offp, int proto)
 		if (pimlen < PIM6_REG_MINLEN) {
 			PIM6STAT_INC(pim6s_rcv_tooshort);
 			PIM6STAT_INC(pim6s_rcv_badregisters);
-#ifdef MRT6DEBUG
-			log(LOG_ERR,
-			    "pim6_input: register packet size too "
-			    "small %d from %s\n",
+			MRT6_DLOG(DEBUG_ANY | DEBUG_ERR, "register packet "
+			    "size too small %d from %s",
 			    pimlen, ip6_sprintf(ip6bufs, &ip6->ip6_src));
-#endif
 			m_freem(m);
 			return (IPPROTO_DONE);
 		}
 
 		eip6 = (struct ip6_hdr *) (reghdr + 1);
-#ifdef MRT6DEBUG
-		if (V_mrt6debug & DEBUG_PIM)
-			log(LOG_DEBUG,
-			    "pim6_input[register], eip6: %s -> %s, "
-			    "eip6 plen %d\n",
-			    ip6_sprintf(ip6bufs, &eip6->ip6_src),
-			    ip6_sprintf(ip6bufd, &eip6->ip6_dst),
-			    ntohs(eip6->ip6_plen));
-#endif
+		MRT6_DLOG(DEBUG_PIM, "eip6: %s -> %s, eip6 plen %d",
+		    ip6_sprintf(ip6bufs, &eip6->ip6_src),
+		    ip6_sprintf(ip6bufd, &eip6->ip6_dst),
+		    ntohs(eip6->ip6_plen));
 
 		/* verify the version number of the inner packet */
 		if ((eip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
 			PIM6STAT_INC(pim6s_rcv_badregisters);
-#ifdef MRT6DEBUG
-			log(LOG_DEBUG, "pim6_input: invalid IP version (%d) "
-			    "of the inner packet\n",
+			MRT6_DLOG(DEBUG_ANY, "invalid IP version (%d) "
+			    "of the inner packet",
 			    (eip6->ip6_vfc & IPV6_VERSION));
-#endif
 			m_freem(m);
 			return (IPPROTO_NONE);
 		}
@@ -1946,13 +1843,9 @@ pim6_input(struct mbuf **mp, int *offp, int proto)
 		/* verify the inner packet is destined to a mcast group */
 		if (!IN6_IS_ADDR_MULTICAST(&eip6->ip6_dst)) {
 			PIM6STAT_INC(pim6s_rcv_badregisters);
-#ifdef MRT6DEBUG
-			if (V_mrt6debug & DEBUG_PIM)
-				log(LOG_DEBUG,
-				    "pim6_input: inner packet of register "
-				    "is not multicast %s\n",
-				    ip6_sprintf(ip6bufd, &eip6->ip6_dst));
-#endif
+			MRT6_DLOG(DEBUG_PIM, "inner packet of register "
+			    "is not multicast %s",
+			    ip6_sprintf(ip6bufd, &eip6->ip6_dst));
 			m_freem(m);
 			return (IPPROTO_DONE);
 		}
@@ -1962,11 +1855,8 @@ pim6_input(struct mbuf **mp, int *offp, int proto)
 		 */
 		mcp = m_copy(m, 0, off + PIM6_REG_MINLEN);
 		if (mcp == NULL) {
-#ifdef MRT6DEBUG
-			log(LOG_ERR,
-			    "pim6_input: pim register: "
-			    "could not copy register head\n");
-#endif
+			MRT6_DLOG(DEBUG_ANY | DEBUG_ERR, "pim register: "
+			    "could not copy register head");
 			m_freem(m);
 			return (IPPROTO_DONE);
 		}
@@ -1975,16 +1865,10 @@ pim6_input(struct mbuf **mp, int *offp, int proto)
 		 * forward the inner ip6 packet; point m_data at the inner ip6.
 		 */
 		m_adj(m, off + PIM_MINLEN);
-#ifdef MRT6DEBUG
-		if (V_mrt6debug & DEBUG_PIM) {
-			log(LOG_DEBUG,
-			    "pim6_input: forwarding decapsulated register: "
-			    "src %s, dst %s, mif %d\n",
-			    ip6_sprintf(ip6bufs, &eip6->ip6_src),
-			    ip6_sprintf(ip6bufd, &eip6->ip6_dst),
-			    reg_mif_num);
-		}
-#endif
+		MRT6_DLOG(DEBUG_PIM, "forwarding decapsulated register: "
+		    "src %s, dst %s, mif %d",
+		    ip6_sprintf(ip6bufs, &eip6->ip6_src),
+		    ip6_sprintf(ip6bufd, &eip6->ip6_dst), reg_mif_num);
 
 		rc = if_simloop(mif6table[reg_mif_num].m6_ifp, m,
 				dst.sin6_family, 0);
diff --git a/freebsd/sys/netinet6/ip6_mroute.h b/freebsd/sys/netinet6/ip6_mroute.h
index d2df0db..33b4131 100644
--- a/freebsd/sys/netinet6/ip6_mroute.h
+++ b/freebsd/sys/netinet6/ip6_mroute.h
@@ -145,11 +145,6 @@ struct mrt6stat {
 struct omrt6msg {
 	u_long	    unused1;
 	u_char	    im6_msgtype;		/* what type of message	    */
-#if 0
-#define MRT6MSG_NOCACHE	1
-#define MRT6MSG_WRONGMIF	2
-#define MRT6MSG_WHOLEPKT	3		/* used for user level encap*/
-#endif
 	u_char	    im6_mbz;			/* must be zero		    */
 	u_char	    im6_mif;			/* mif rec'd on		    */
 	u_char	    unused2;
diff --git a/freebsd/sys/netinet6/nd6.c b/freebsd/sys/netinet6/nd6.c
index b84baf1..9233bef 100644
--- a/freebsd/sys/netinet6/nd6.c
+++ b/freebsd/sys/netinet6/nd6.c
@@ -1156,9 +1156,9 @@ nd6_nud_hint(struct rtentry *rt, struct in6_addr *dst6, int force)
 		return;
 
 	ifp = rt->rt_ifp;
-	IF_AFDATA_LOCK(ifp);
+	IF_AFDATA_RLOCK(ifp);
 	ln = nd6_lookup(dst6, ND6_EXCLUSIVE, NULL);
-	IF_AFDATA_UNLOCK(ifp);
+	IF_AFDATA_RUNLOCK(ifp);
 	if (ln == NULL)
 		return;
 
@@ -1585,16 +1585,16 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
 	 * description on it in NS section (RFC 2461 7.2.3).
 	 */
 	flags = lladdr ? ND6_EXCLUSIVE : 0;
-	IF_AFDATA_LOCK(ifp);
+	IF_AFDATA_RLOCK(ifp);
 	ln = nd6_lookup(from, flags, ifp);
-
+	IF_AFDATA_RUNLOCK(ifp);
 	if (ln == NULL) {
 		flags |= ND6_EXCLUSIVE;
+		IF_AFDATA_LOCK(ifp);
 		ln = nd6_lookup(from, flags | ND6_CREATE, ifp);
 		IF_AFDATA_UNLOCK(ifp);
 		is_newentry = 1;
 	} else {
-		IF_AFDATA_UNLOCK(ifp);		
 		/* do nothing if static ndp is set */
 		if (ln->la_flags & LLE_STATIC) {
 			static_route = 1;
@@ -1897,12 +1897,12 @@ nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0,
 	 * or an anycast address(i.e. not a multicast).
 	 */
 
-	flags = ((m != NULL) || (lle != NULL)) ? LLE_EXCLUSIVE : 0;
+	flags = (lle != NULL) ? LLE_EXCLUSIVE : 0;
 	if (ln == NULL) {
 	retry:
-		IF_AFDATA_LOCK(ifp);
+		IF_AFDATA_RLOCK(ifp);
 		ln = lla_lookup(LLTABLE6(ifp), flags, (struct sockaddr *)dst);
-		IF_AFDATA_UNLOCK(ifp);
+		IF_AFDATA_RUNLOCK(ifp);
 		if ((ln == NULL) && nd6_is_addr_neighbor(dst, ifp))  {
 			/*
 			 * Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
@@ -1933,6 +1933,7 @@ nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0,
 	    ln->ln_state < ND6_LLINFO_REACHABLE) {
 		if ((flags & LLE_EXCLUSIVE) == 0) {
 			flags |= LLE_EXCLUSIVE;
+			LLE_RUNLOCK(ln);
 			goto retry;
 		}
 		ln->ln_state = ND6_LLINFO_STALE;
diff --git a/freebsd/sys/netinet6/nd6_nbr.c b/freebsd/sys/netinet6/nd6_nbr.c
index 4574145..09011b7 100644
--- a/freebsd/sys/netinet6/nd6_nbr.c
+++ b/freebsd/sys/netinet6/nd6_nbr.c
@@ -736,9 +736,9 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
 	 * If no neighbor cache entry is found, NA SHOULD silently be
 	 * discarded.
 	 */
-	IF_AFDATA_LOCK(ifp);
+	IF_AFDATA_RLOCK(ifp);
 	ln = nd6_lookup(&taddr6, LLE_EXCLUSIVE, ifp);
-	IF_AFDATA_UNLOCK(ifp);
+	IF_AFDATA_RUNLOCK(ifp);
 	if (ln == NULL) {
 		goto freeit;
 	}
diff --git a/freebsd/sys/netinet6/sctp6_usrreq.c b/freebsd/sys/netinet6/sctp6_usrreq.c
index f4dfe81..c8bc662 100644
--- a/freebsd/sys/netinet6/sctp6_usrreq.c
+++ b/freebsd/sys/netinet6/sctp6_usrreq.c
@@ -843,16 +843,18 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
 	uint32_t vrf_id;
 	int error = 0;
 	struct sctp_inpcb *inp;
-	struct in6pcb *inp6;
 	struct sctp_tcb *stcb;
 
 #ifdef INET
+	struct in6pcb *inp6;
 	struct sockaddr_in6 *sin6;
 	struct sockaddr_storage ss;
 
 #endif
 
+#ifdef INET
 	inp6 = (struct in6pcb *)so->so_pcb;
+#endif
 	inp = (struct sctp_inpcb *)so->so_pcb;
 	if (inp == NULL) {
 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
diff --git a/freebsd/sys/netpfil/ipfw/ip_dummynet.c b/freebsd/sys/netpfil/ipfw/ip_dummynet.c
index bd7e3c0..bb9a673 100644
--- a/freebsd/sys/netpfil/ipfw/ip_dummynet.c
+++ b/freebsd/sys/netpfil/ipfw/ip_dummynet.c
@@ -619,7 +619,7 @@ fsk_detach(struct dn_fsk *fs, int flags)
 		fs->sched->fp->free_fsk(fs);
 	fs->sched = NULL;
 	if (flags & DN_DELETE_FS) {
-		bzero(fs, sizeof(fs));	/* safety */
+		bzero(fs, sizeof(*fs));	/* safety */
 		free(fs, M_DUMMYNET);
 		dn_cfg.fsk_count--;
 	} else {
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw2.c b/freebsd/sys/netpfil/ipfw/ip_fw2.c
index 1bd1b6f..224ba93 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw2.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw2.c
@@ -144,6 +144,8 @@ VNET_DEFINE(int, verbose_limit);
 /* layer3_chain contains the list of rules for layer 3 */
 VNET_DEFINE(struct ip_fw_chain, layer3_chain);
 
+VNET_DEFINE(int, ipfw_nat_ready) = 0;
+
 ipfw_nat_t *ipfw_nat_ptr = NULL;
 struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
 ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
@@ -2411,38 +2413,35 @@ do {								\
 			}
 
 			case O_NAT:
+				l = 0;          /* exit inner loop */
+				done = 1;       /* exit outer loop */
  				if (!IPFW_NAT_LOADED) {
 				    retval = IP_FW_DENY;
-				} else {
-				    struct cfg_nat *t;
-				    int nat_id;
+				    break;
+				}
 
-				    set_match(args, f_pos, chain);
-				    /* Check if this is 'global' nat rule */
-				    if (cmd->arg1 == 0) {
-					    retval = ipfw_nat_ptr(args, NULL, m);
-					    l = 0;
-					    done = 1;
-					    break;
-				    }
-				    t = ((ipfw_insn_nat *)cmd)->nat;
-				    if (t == NULL) {
+				struct cfg_nat *t;
+				int nat_id;
+
+				set_match(args, f_pos, chain);
+				/* Check if this is 'global' nat rule */
+				if (cmd->arg1 == 0) {
+					retval = ipfw_nat_ptr(args, NULL, m);
+					break;
+				}
+				t = ((ipfw_insn_nat *)cmd)->nat;
+				if (t == NULL) {
 					nat_id = IP_FW_ARG_TABLEARG(cmd->arg1);
 					t = (*lookup_nat_ptr)(&chain->nat, nat_id);
 
 					if (t == NULL) {
 					    retval = IP_FW_DENY;
-					    l = 0;	/* exit inner loop */
-					    done = 1;	/* exit outer loop */
 					    break;
 					}
 					if (cmd->arg1 != IP_FW_TABLEARG)
 					    ((ipfw_insn_nat *)cmd)->nat = t;
-				    }
-				    retval = ipfw_nat_ptr(args, t, m);
 				}
-				l = 0;          /* exit inner loop */
-				done = 1;       /* exit outer loop */
+				retval = ipfw_nat_ptr(args, t, m);
 				break;
 
 			case O_REASS: {
@@ -2675,7 +2674,7 @@ vnet_ipfw_init(const void *unused)
 	rule->set = RESVD_SET;
 	rule->cmd[0].len = 1;
 	rule->cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY;
-	chain->rules = chain->default_rule = chain->map[0] = rule;
+	chain->default_rule = chain->map[0] = rule;
 	chain->id = rule->id = 1;
 
 	IPFW_LOCK_INIT(chain);
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_log.c b/freebsd/sys/netpfil/ipfw/ip_fw_log.c
index 9713225..60b0df7 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_log.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_log.c
@@ -175,11 +175,18 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
 
 		if (args->eh) /* layer2, use orig hdr */
 			BPF_MTAP2(log_if, args->eh, ETHER_HDR_LEN, m);
-		else
+		else {
 			/* Add fake header. Later we will store
 			 * more info in the header.
 			 */
-			BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m);
+			if (ip->ip_v == 4)
+				BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m);
+			else if  (ip->ip_v == 6)
+				BPF_MTAP2(log_if, "DDDDDDSSSSSS\x86\xdd", ETHER_HDR_LEN, m);
+			else
+				/* Obviously bogus EtherType. */
+				BPF_MTAP2(log_if, "DDDDDDSSSSSS\xff\xff", ETHER_HDR_LEN, m);
+		}
 #endif /* !WITHOUT_BPF */
 		return;
 	}
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_nat.c b/freebsd/sys/netpfil/ipfw/ip_fw_nat.c
index 142c46c..5d4dcc9 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_nat.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_nat.c
@@ -55,8 +55,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/in_cksum.h>	/* XXX for in_cksum */
 
-static VNET_DEFINE(eventhandler_tag, ifaddr_event_tag);
-#define	V_ifaddr_event_tag	VNET(ifaddr_event_tag)
+static eventhandler_tag ifaddr_event_tag;
 
 static void
 ifaddr_change(void *arg __unused, struct ifnet *ifp)
@@ -65,6 +64,8 @@ ifaddr_change(void *arg __unused, struct ifnet *ifp)
 	struct ifaddr *ifa;
 	struct ip_fw_chain *chain;
 
+	KASSERT(curvnet == ifp->if_vnet,
+	    ("curvnet(%p) differs from iface vnet(%p)", curvnet, ifp->if_vnet));
 	chain = &V_layer3_chain;
 	IPFW_WLOCK(chain);
 	/* Check every nat entry... */
@@ -443,7 +444,7 @@ ipfw_nat_cfg(struct sockopt *sopt)
 	ptr->ip = cfg->ip;
 	ptr->redir_cnt = cfg->redir_cnt;
 	ptr->mode = cfg->mode;
-	LibAliasSetMode(ptr->lib, cfg->mode, cfg->mode);
+	LibAliasSetMode(ptr->lib, cfg->mode, ~0);
 	LibAliasSetAddress(ptr->lib, ptr->ip);
 	memcpy(ptr->if_name, cfg->if_name, IF_NAMESIZE);
 
@@ -592,11 +593,38 @@ ipfw_nat_get_log(struct sockopt *sopt)
 	return(0);
 }
 
+static int
+vnet_ipfw_nat_init(const void *arg __unused)
+{
+
+	V_ipfw_nat_ready = 1;
+	return (0);
+}
+
+static int
+vnet_ipfw_nat_uninit(const void *arg __unused)
+{
+	struct cfg_nat *ptr, *ptr_temp;
+	struct ip_fw_chain *chain;
+
+	chain = &V_layer3_chain;
+	IPFW_WLOCK(chain);
+	LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) {
+		LIST_REMOVE(ptr, _next);
+		del_redir_spool_cfg(ptr, &ptr->redir_chain);
+		LibAliasUninit(ptr->lib);
+		free(ptr, M_IPFW);
+	}
+	flush_nat_ptrs(chain, -1 /* flush all */);
+	V_ipfw_nat_ready = 0;
+	IPFW_WUNLOCK(chain);
+	return (0);
+}
+
 static void
 ipfw_nat_init(void)
 {
 
-	IPFW_WLOCK(&V_layer3_chain);
 	/* init ipfw hooks */
 	ipfw_nat_ptr = ipfw_nat;
 	lookup_nat_ptr = lookup_nat;
@@ -604,28 +632,16 @@ ipfw_nat_init(void)
 	ipfw_nat_del_ptr = ipfw_nat_del;
 	ipfw_nat_get_cfg_ptr = ipfw_nat_get_cfg;
 	ipfw_nat_get_log_ptr = ipfw_nat_get_log;
-	IPFW_WUNLOCK(&V_layer3_chain);
-	V_ifaddr_event_tag = EVENTHANDLER_REGISTER(
-	    ifaddr_event, ifaddr_change,
+
+	ifaddr_event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_change,
 	    NULL, EVENTHANDLER_PRI_ANY);
 }
 
 static void
 ipfw_nat_destroy(void)
 {
-	struct cfg_nat *ptr, *ptr_temp;
-	struct ip_fw_chain *chain;
 
-	chain = &V_layer3_chain;
-	IPFW_WLOCK(chain);
-	LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) {
-		LIST_REMOVE(ptr, _next);
-		del_redir_spool_cfg(ptr, &ptr->redir_chain);
-		LibAliasUninit(ptr->lib);
-		free(ptr, M_IPFW);
-	}
-	EVENTHANDLER_DEREGISTER(ifaddr_event, V_ifaddr_event_tag);
-	flush_nat_ptrs(chain, -1 /* flush all */);
+	EVENTHANDLER_DEREGISTER(ifaddr_event, ifaddr_event_tag);
 	/* deregister ipfw_nat */
 	ipfw_nat_ptr = NULL;
 	lookup_nat_ptr = NULL;
@@ -633,7 +649,6 @@ ipfw_nat_destroy(void)
 	ipfw_nat_del_ptr = NULL;
 	ipfw_nat_get_cfg_ptr = NULL;
 	ipfw_nat_get_log_ptr = NULL;
-	IPFW_WUNLOCK(chain);
 }
 
 static int
@@ -643,11 +658,9 @@ ipfw_nat_modevent(module_t mod, int type, void *unused)
 
 	switch (type) {
 	case MOD_LOAD:
-		ipfw_nat_init();
 		break;
 
 	case MOD_UNLOAD:
-		ipfw_nat_destroy();
 		break;
 
 	default:
@@ -663,8 +676,25 @@ static moduledata_t ipfw_nat_mod = {
 	0
 };
 
-DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
+/* Define startup order. */
+#define	IPFW_NAT_SI_SUB_FIREWALL	SI_SUB_PROTO_IFATTACHDOMAIN
+#define	IPFW_NAT_MODEVENT_ORDER		(SI_ORDER_ANY - 128)
+#define	IPFW_NAT_MODULE_ORDER		(IPFW_NAT_MODEVENT_ORDER + 1)
+#define	IPFW_NAT_VNET_ORDER		(IPFW_NAT_MODEVENT_ORDER + 2)
+
+DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, IPFW_NAT_SI_SUB_FIREWALL, SI_ORDER_ANY);
 MODULE_DEPEND(ipfw_nat, libalias, 1, 1, 1);
 MODULE_DEPEND(ipfw_nat, ipfw, 2, 2, 2);
 MODULE_VERSION(ipfw_nat, 1);
+
+SYSINIT(ipfw_nat_init, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_MODULE_ORDER,
+    ipfw_nat_init, NULL);
+VNET_SYSINIT(vnet_ipfw_nat_init, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_VNET_ORDER,
+    vnet_ipfw_nat_init, NULL);
+
+SYSUNINIT(ipfw_nat_destroy, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_MODULE_ORDER,
+    ipfw_nat_destroy, NULL);
+VNET_SYSUNINIT(vnet_ipfw_nat_uninit, IPFW_NAT_SI_SUB_FIREWALL,
+    IPFW_NAT_VNET_ORDER, vnet_ipfw_nat_uninit, NULL);
+
 /* end of file */
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_private.h b/freebsd/sys/netpfil/ipfw/ip_fw_private.h
index 869d972..ceabf88 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_private.h
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_private.h
@@ -213,25 +213,27 @@ VNET_DECLARE(unsigned int, fw_tables_max);
 #define V_fw_tables_max		VNET(fw_tables_max)
 
 struct ip_fw_chain {
-	struct ip_fw	*rules;		/* list of rules */
-	struct ip_fw	*reap;		/* list of rules to reap */
-	struct ip_fw	*default_rule;
-	int		n_rules;	/* number of static rules */
-	int		static_len;	/* total len of static rules */
 	struct ip_fw	**map;		/* array of rule ptrs to ease lookup */
+	uint32_t	id;		/* ruleset id */
+	int		n_rules;	/* number of static rules */
 	LIST_HEAD(nat_list, cfg_nat) nat;       /* list of nat entries */
 	struct radix_node_head **tables;	/* IPv4 tables */
 	struct radix_node_head **xtables;	/* extended tables */
 	uint8_t		*tabletype;	/* Array of table types */
 #if defined( __linux__ ) || defined( _WIN32 )
 	spinlock_t rwmtx;
-	spinlock_t uh_lock;
 #else
 	struct rwlock	rwmtx;
+#endif
+	int		static_len;	/* total len of static rules */
+	uint32_t	gencnt;		/* NAT generation count */
+	struct ip_fw	*reap;		/* list of rules to reap */
+	struct ip_fw	*default_rule;
+#if defined( __linux__ ) || defined( _WIN32 )
+	spinlock_t uh_lock;
+#else
 	struct rwlock	uh_lock;	/* lock for upper half */
 #endif
-	uint32_t	id;		/* ruleset id */
-	uint32_t	gencnt;		/* generation count */
 };
 
 struct sockopt;	/* used by tcp_var.h */
@@ -329,9 +331,11 @@ extern struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
 typedef int ipfw_nat_t(struct ip_fw_args *, struct cfg_nat *, struct mbuf *);
 typedef int ipfw_nat_cfg_t(struct sockopt *);
 
-extern ipfw_nat_t *ipfw_nat_ptr;
-#define IPFW_NAT_LOADED (ipfw_nat_ptr != NULL)
+VNET_DECLARE(int, ipfw_nat_ready);
+#define	V_ipfw_nat_ready	VNET(ipfw_nat_ready)
+#define	IPFW_NAT_LOADED	(V_ipfw_nat_ready)
 
+extern ipfw_nat_t *ipfw_nat_ptr;
 extern ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
 extern ipfw_nat_cfg_t *ipfw_nat_del_ptr;
 extern ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c b/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c
index 40448a8..95cd8c8 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c
@@ -161,7 +161,7 @@ ipfw_add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule)
 	int i, l, insert_before;
 	struct ip_fw **map;	/* the new array of pointers */
 
-	if (chain->rules == NULL || input_rule->rulenum > IPFW_DEFAULT_RULE-1)
+	if (chain->map == NULL || input_rule->rulenum > IPFW_DEFAULT_RULE - 1)
 		return (EINVAL);
 
 	l = RULESIZE(input_rule);
@@ -657,7 +657,7 @@ check_ipfw_struct(struct ip_fw *rule, int size)
 
 		case O_IP_SRC_LOOKUP:
 		case O_IP_DST_LOOKUP:
-			if (cmd->arg1 >= IPFW_TABLES_MAX) {
+			if (cmd->arg1 >= V_fw_tables_max) {
 				printf("ipfw: invalid table number %d\n",
 				    cmd->arg1);
 				return (EINVAL);
@@ -1045,8 +1045,10 @@ ipfw_ctl(struct sockopt *sopt)
 		if (sopt->sopt_valsize == RULESIZE7(rule)) {
 		    is7 = 1;
 		    error = convert_rule_to_8(rule);
-		    if (error)
+		    if (error) {
+			free(rule, M_TEMP);
 			return error;
+		    }
 		    if (error == 0)
 			error = check_ipfw_struct(rule, RULESIZE(rule));
 		} else {
@@ -1062,11 +1064,13 @@ ipfw_ctl(struct sockopt *sopt)
 				if (is7) {
 					error = convert_rule_to_7(rule);
 					size = RULESIZE7(rule);
-					if (error)
+					if (error) {
+						free(rule, M_TEMP);
 						return error;
+					}
 				}
 				error = sooptcopyout(sopt, rule, size);
-		}
+			}
 		}
 		free(rule, M_TEMP);
 		break;
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_table.c b/freebsd/sys/netpfil/ipfw/ip_fw_table.c
index 58ee16e..7157979 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_table.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_table.c
@@ -125,6 +125,7 @@ struct table_xentry {
 #define OFF_LEN_IFACE	(8 * offsetof(struct xaddr_iface, ifname))
 
 
+#ifdef INET6
 static inline void
 ipv6_writemask(struct in6_addr *addr6, uint8_t mask)
 {
@@ -134,6 +135,7 @@ ipv6_writemask(struct in6_addr *addr6, uint8_t mask)
 		*cp++ = 0xFFFFFFFF;
 	*cp = htonl(mask ? ~((1 << (32 - mask)) - 1) : 0);
 }
+#endif
 
 int
 ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
@@ -544,7 +546,7 @@ ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
 		return (0);
 	KEY_LEN(sa) = KEY_LEN_INET;
 	sa.sin_addr.s_addr = addr;
-	ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh));
+	ent = (struct table_entry *)(rnh->rnh_matchaddr(&sa, rnh));
 	if (ent != NULL) {
 		*val = ent->value;
 		return (1);
@@ -570,7 +572,7 @@ ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
 	case IPFW_TABLE_CIDR:
 		KEY_LEN(sa6) = KEY_LEN_INET6;
 		memcpy(&sa6.sin6_addr, paddr, sizeof(struct in6_addr));
-		xent = (struct table_xentry *)(rnh->rnh_lookup(&sa6, NULL, rnh));
+		xent = (struct table_xentry *)(rnh->rnh_matchaddr(&sa6, rnh));
 		break;
 
 	case IPFW_TABLE_INTERFACE:
@@ -578,7 +580,7 @@ ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
 		    strlcpy(iface.ifname, (char *)paddr, IF_NAMESIZE) + 1;
 		/* Assume direct match */
 		/* FIXME: Add interface pattern matching */
-		xent = (struct table_xentry *)(rnh->rnh_lookup(&iface, NULL, rnh));
+		xent = (struct table_xentry *)(rnh->rnh_matchaddr(&iface, rnh));
 		break;
 
 	default:
diff --git a/freebsd/sys/opencrypto/deflate.c b/freebsd/sys/opencrypto/deflate.c
index f8a4640..f29dfb4 100644
--- a/freebsd/sys/opencrypto/deflate.c
+++ b/freebsd/sys/opencrypto/deflate.c
@@ -52,13 +52,13 @@ __FBSDID("$FreeBSD$");
 #include <opencrypto/deflate.h>
 
 SDT_PROVIDER_DECLARE(opencrypto);
-SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, entry, entry,
+SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, entry,
     "int", "u_int32_t");
-SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, bad, bad,
+SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, bad,
     "int", "int", "int", "int", "int");
-SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, iter, iter,
+SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, iter,
     "int", "int", "int", "int", "int");
-SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, return, return,
+SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, return,
     "int", "u_int32_t");
 
 int window_inflate = -1 * MAX_WBITS;
diff --git a/freebsd/sys/pci/if_rlreg.h b/freebsd/sys/pci/if_rlreg.h
index be89c4f..b0de60f 100644
--- a/freebsd/sys/pci/if_rlreg.h
+++ b/freebsd/sys/pci/if_rlreg.h
@@ -145,6 +145,7 @@
 #define	RL_PMCH			0x006F	/* 8 bits */
 #define	RL_MAXRXPKTLEN		0x00DA	/* 16 bits, chip multiplies by 8 */
 #define	RL_INTRMOD		0x00E2	/* 16 bits */
+#define	RL_MISC			0x00F0
 
 /*
  * TX config register bits
@@ -163,7 +164,6 @@
 #define	RL_LOOPTEST_ON_CPLUS	0x00060000
 
 /* Known revision codes. */
-
 #define	RL_HWREV_8169		0x00000000
 #define	RL_HWREV_8169S		0x00800000
 #define	RL_HWREV_8110S		0x04000000
@@ -189,8 +189,13 @@
 #define	RL_HWREV_8105E		0x40800000
 #define	RL_HWREV_8105E_SPIN1	0x40C00000
 #define	RL_HWREV_8402		0x44000000
+#define	RL_HWREV_8106E		0x44800000
 #define	RL_HWREV_8168F		0x48000000
 #define	RL_HWREV_8411		0x48800000
+#define	RL_HWREV_8168G		0x4C000000
+#define	RL_HWREV_8168EP		0x50000000
+#define	RL_HWREV_8168GU		0x50800000
+#define	RL_HWREV_8411B		0x5C800000
 #define	RL_HWREV_8139		0x60000000
 #define	RL_HWREV_8139A		0x70000000
 #define	RL_HWREV_8139AG		0x70800000
@@ -282,8 +287,10 @@
 #define	RL_RXCFG_RX_RUNT	0x00000010
 #define	RL_RXCFG_RX_ERRPKT	0x00000020
 #define	RL_RXCFG_WRAP		0x00000080
+#define	RL_RXCFG_EARLYOFFV2	0x00000800
 #define	RL_RXCFG_MAXDMA		0x00000700
 #define	RL_RXCFG_BUFSZ		0x00001800
+#define	RL_RXCFG_EARLYOFF	0x00003800
 #define	RL_RXCFG_FIFOTHRESH	0x0000E000
 #define	RL_RXCFG_EARLYTHRESH	0x07000000
 
@@ -324,8 +331,8 @@
 #define	RL_RXSTAT_INDIV		0x00004000
 #define	RL_RXSTAT_MULTI		0x00008000
 #define	RL_RXSTAT_LENMASK	0xFFFF0000
+#define	RL_RXSTAT_UNFINISHED	0x0000FFF0	/* DMA still in progress */
 
-#define	RL_RXSTAT_UNFINISHED	0xFFF0		/* DMA still in progress */
 /*
  * Command register.
  */
@@ -356,6 +363,7 @@
 #define	RL_PARA7C		0x7C
 #define	RL_PARA7C_DEF		0xcb38de43
 #define	RL_PARA7C_RETUNE	0xfb38de03
+
 /*
  * EEPROM control register
  */
@@ -468,11 +476,9 @@
  */
 
 /* RL_DUMPSTATS_LO register */
-
 #define	RL_DUMPSTATS_START	0x00000008
 
 /* Transmit start register */
-
 #define	RL_TXSTART_SWI		0x01	/* generate TX interrupt */
 #define	RL_TXSTART_START	0x40	/* start normal queue transmit */
 #define	RL_TXSTART_HPRIO_START	0x80	/* start hi prio queue transmit */
@@ -491,7 +497,6 @@
 #define	RL_BUSWIDTH_64BITS	0x08
 
 /* C+ mode command register */
-
 #define	RL_CPLUSCMD_TXENB	0x0001	/* enable C+ transmit mode */
 #define	RL_CPLUSCMD_RXENB	0x0002	/* enable C+ receive mode */
 #define	RL_CPLUSCMD_PCI_MRW	0x0008	/* enable PCI multi-read/write */
@@ -509,7 +514,6 @@
 #define	RL_CPLUSCMD_BIST_ENB	0x8000	/* 8168C/CP */
 
 /* C+ early transmit threshold */
-
 #define	RL_EARLYTXTHRESH_CNT	0x003F	/* byte count times 8 */
 
 /* Timer interrupt register */
@@ -523,7 +527,6 @@
 /*
  * Gigabit PHY access register (8169 only)
  */
-
 #define	RL_PHYAR_PHYDATA	0x0000FFFF
 #define	RL_PHYAR_PHYREG		0x001F0000
 #define	RL_PHYAR_BUSY		0x80000000
@@ -554,7 +557,6 @@
  * For reception, there's just one large buffer where the chip stores
  * all received packets.
  */
-
 #define	RL_RX_BUF_SZ		RL_RXBUF_64
 #define	RL_RXBUFLEN		(1 << ((RL_RX_BUF_SZ >> 11) + 13))
 #define	RL_TX_LIST_CNT		4
@@ -637,11 +639,10 @@ struct rl_hwrev {
 
 /*
  * RX/TX descriptor definition. When large send mode is enabled, the
- * lower 11 bits of the TX rl_cmd word are used to hold the MSS, and
+ * lower 11 bits of the TX rl_cmdstat word are used to hold the MSS, and
  * the checksum offload bits are disabled. The structure layout is
  * the same for RX and TX descriptors
  */
-
 struct rl_desc {
 	uint32_t		rl_cmdstat;
 	uint32_t		rl_vlanctl;
@@ -674,7 +675,6 @@ struct rl_desc {
  * Error bits are valid only on the last descriptor of a frame
  * (i.e. RL_TDESC_CMD_EOF == 1)
  */
-
 #define	RL_TDESC_STAT_COLCNT	0x000F0000	/* collision count */
 #define	RL_TDESC_STAT_EXCESSCOL	0x00100000	/* excessive collisions */
 #define	RL_TDESC_STAT_LINKFAIL	0x00200000	/* link faulure */
@@ -686,7 +686,6 @@ struct rl_desc {
 /*
  * RX descriptor cmd/vlan definitions
  */
-
 #define	RL_RDESC_CMD_EOR	0x40000000
 #define	RL_RDESC_CMD_OWN	0x80000000
 #define	RL_RDESC_CMD_BUFLEN	0x00001FFF
@@ -777,7 +776,7 @@ struct rl_stats {
 #define	RL_TX_DESC_CNT		RL_8169_TX_DESC_CNT
 #define	RL_RX_DESC_CNT		RL_8169_RX_DESC_CNT
 #define	RL_RX_JUMBO_DESC_CNT	RL_RX_DESC_CNT
-#define	RL_NTXSEGS		32
+#define	RL_NTXSEGS		35
 
 #define	RL_RING_ALIGN		256
 #define	RL_DUMP_ALIGN		64
@@ -877,6 +876,7 @@ struct rl_softc {
 	bus_dma_tag_t		rl_parent_tag;
 	uint8_t			rl_type;
 	const struct rl_hwrev	*rl_hwrev;
+	uint32_t		rl_macrev;
 	int			rl_eecmd_read;
 	int			rl_eewidth;
 	int			rl_expcap;
@@ -929,6 +929,9 @@ struct rl_softc {
 #define	RL_FLAG_WAIT_TXPOLL	0x00004000
 #define	RL_FLAG_CMDSTOP_WAIT_TXQ	0x00008000
 #define	RL_FLAG_WOL_MANLINK	0x00010000
+#define	RL_FLAG_EARLYOFF	0x00020000
+#define	RL_FLAG_EARLYOFFV2	0x00040000
+#define	RL_FLAG_RXDV_GATED	0x00080000
 #define	RL_FLAG_PCIE		0x40000000
 #define	RL_FLAG_LINK		0x80000000
 };
diff --git a/freebsd/sys/rpc/types.h b/freebsd/sys/rpc/types.h
index 5634c4d..754d627 100644
--- a/freebsd/sys/rpc/types.h
+++ b/freebsd/sys/rpc/types.h
@@ -1,32 +1,31 @@
 /*	$NetBSD: types.h,v 1.13 2000/06/13 01:02:44 thorpej Exp $	*/
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice, 
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its 
+ *   contributors may be used to endorse or promote products derived 
+ *   from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+ * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: @(#)types.h 1.18 87/07/24 SMI
  *	from: @(#)types.h	2.3 88/08/15 4.0 RPCSRC
diff --git a/freebsd/sys/sys/_rmlock.h b/freebsd/sys/sys/_rmlock.h
index 283ea37..46672bb 100644
--- a/freebsd/sys/sys/_rmlock.h
+++ b/freebsd/sys/sys/_rmlock.h
@@ -45,14 +45,17 @@ LIST_HEAD(rmpriolist,rm_priotracker);
 
 #ifndef __rtems__
 struct rmlock {
-	struct lock_object lock_object; 
+	struct lock_object lock_object;
 	volatile cpuset_t rm_writecpus;
 	LIST_HEAD(,rm_priotracker) rm_activeReaders;
 	union {
+		struct lock_object _rm_wlock_object;
 		struct mtx _rm_lock_mtx;
 		struct sx _rm_lock_sx;
 	} _rm_lock;
 };
+
+#define	rm_wlock_object	_rm_lock._rm_wlock_object
 #define	rm_lock_mtx	_rm_lock._rm_lock_mtx
 #define	rm_lock_sx	_rm_lock._rm_lock_sx
 #else /* __rtems__ */
diff --git a/freebsd/sys/sys/_rwlock.h b/freebsd/sys/sys/_rwlock.h
index 25eb55e..95b2128 100644
--- a/freebsd/sys/sys/_rwlock.h
+++ b/freebsd/sys/sys/_rwlock.h
@@ -10,9 +10,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/freebsd/sys/sys/ata.h b/freebsd/sys/sys/ata.h
index 76d8f64..f46dd50 100644
--- a/freebsd/sys/sys/ata.h
+++ b/freebsd/sys/sys/ata.h
@@ -130,6 +130,7 @@ struct ata_params {
 #define ATA_SATA_CURR_GEN_MASK          0x0006
 #define ATA_SUPPORT_NCQ_STREAM          0x0010
 #define ATA_SUPPORT_NCQ_QMANAGEMENT     0x0020
+#define ATA_SUPPORT_RCVSND_FPDMA_QUEUED 0x0040
 /*78*/  u_int16_t       satasupport;
 #define ATA_SUPPORT_NONZERO             0x0002
 #define ATA_SUPPORT_AUTOACTIVATE        0x0004
@@ -214,6 +215,8 @@ struct ata_params {
 #define ATA_PSS_LSPPS			0x000F
 #define ATA_PSS_LSSABOVE512		0x1000
 #define ATA_PSS_MULTLS			0x2000
+#define ATA_PSS_VALID_MASK		0xC000
+#define ATA_PSS_VALID_VALUE		0x4000
 /*107*/ u_int16_t       isd;
 /*108*/ u_int16_t       wwn[4];
 	u_int16_t       reserved112[5];
@@ -347,6 +350,7 @@ struct ata_params {
 #define ATA_READ_NATIVE_MAX_ADDRESS48   0x27    /* read native max addr 48bit */
 #define ATA_READ_MUL48                  0x29    /* read multi 48bit LBA */
 #define ATA_READ_STREAM_DMA48           0x2a    /* read DMA stream 48bit LBA */
+#define ATA_READ_LOG_EXT                0x2f    /* read log ext - PIO Data-In */
 #define ATA_READ_STREAM48               0x2b    /* read stream 48bit LBA */
 #define ATA_WRITE                       0x30    /* write */
 #define ATA_WRITE48                     0x34    /* write 48bit LBA */
@@ -361,8 +365,11 @@ struct ata_params {
 #define ATA_WRITE_LOG_EXT               0x3f
 #define ATA_READ_VERIFY                 0x40
 #define ATA_READ_VERIFY48               0x42
+#define ATA_READ_LOG_DMA_EXT            0x47    /* read log DMA ext - PIO Data-In */
 #define ATA_READ_FPDMA_QUEUED           0x60    /* read DMA NCQ */
 #define ATA_WRITE_FPDMA_QUEUED          0x61    /* write DMA NCQ */
+#define ATA_SEND_FPDMA_QUEUED           0x64    /* send DMA NCQ */
+#define ATA_RECV_FPDMA_QUEUED           0x65    /* recieve DMA NCQ */
 #define ATA_SEP_ATTN                    0x67    /* SEP request */
 #define ATA_SEEK                        0x70    /* seek */
 #define ATA_PACKET_CMD                  0xa0    /* packet command */
diff --git a/freebsd/sys/sys/bus_dma.h b/freebsd/sys/sys/bus_dma.h
index 6fbac13..6e91a01 100644
--- a/freebsd/sys/sys/bus_dma.h
+++ b/freebsd/sys/sys/bus_dma.h
@@ -16,13 +16,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the NetBSD
- *	Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/freebsd/sys/sys/conf.h b/freebsd/sys/sys/conf.h
index a8dfc30..a0a7352 100644
--- a/freebsd/sys/sys/conf.h
+++ b/freebsd/sys/sys/conf.h
@@ -64,6 +64,7 @@ struct cdev {
 #define SI_DUMPDEV	0x0080	/* is kernel dumpdev */
 #define SI_CANDELETE	0x0100	/* can do BIO_DELETE */
 #define SI_CLONELIST	0x0200	/* on a clone list */
+#define	SI_UNMAPPED	0x0400	/* can handle unmapped I/O */
 #ifndef __rtems__
 	struct timespec	si_atime;
 	struct timespec	si_ctime;
diff --git a/freebsd/sys/sys/eventhandler.h b/freebsd/sys/sys/eventhandler.h
index 47bc894..95d03b8 100644
--- a/freebsd/sys/sys/eventhandler.h
+++ b/freebsd/sys/sys/eventhandler.h
@@ -253,6 +253,24 @@ EVENTHANDLER_DECLARE(thread_fini, thread_fini_fn);
 
 typedef void (*uma_zone_chfn)(void *);
 EVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn);
+EVENTHANDLER_DECLARE(nmbufs_change, uma_zone_chfn);
 EVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn);
 
+/* Kernel linker file load and unload events */
+struct linker_file;
+typedef void (*kld_load_fn)(void *, struct linker_file *);
+typedef void (*kld_unload_fn)(void *, const char *, caddr_t, size_t);
+typedef void (*kld_unload_try_fn)(void *, struct linker_file *, int *);
+EVENTHANDLER_DECLARE(kld_load, kld_load_fn);
+EVENTHANDLER_DECLARE(kld_unload, kld_unload_fn);
+EVENTHANDLER_DECLARE(kld_unload_try, kld_unload_try_fn);
+
+/* Generic graphics framebuffer interface */
+struct fb_info;
+typedef void (*register_framebuffer_fn)(void *, struct fb_info *);
+typedef void (*unregister_framebuffer_fn)(void *, struct fb_info *);
+EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn);
+EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn);
+
 #endif /* SYS_EVENTHANDLER_H */
+
diff --git a/freebsd/sys/sys/eventvar.h b/freebsd/sys/sys/eventvar.h
index 26fe34b..6af0fe8 100644
--- a/freebsd/sys/sys/eventvar.h
+++ b/freebsd/sys/sys/eventvar.h
@@ -41,7 +41,7 @@
 struct kqueue {
 	struct		mtx kq_lock;
 	int		kq_refcnt;
-	SLIST_ENTRY(kqueue)	kq_list;
+	TAILQ_ENTRY(kqueue)	kq_list;
 	TAILQ_HEAD(, knote)	kq_head;	/* list of pending event */
 	int		kq_count;		/* number of pending events */
 	struct		selinfo kq_sel;
diff --git a/freebsd/sys/sys/kernel.h b/freebsd/sys/sys/kernel.h
index 1318243..c739cd5 100644
--- a/freebsd/sys/sys/kernel.h
+++ b/freebsd/sys/sys/kernel.h
@@ -86,7 +86,7 @@ extern volatile int ticks;
  * enumeration values are explicit rather than implicit to provide
  * for binary compatibility with inserted elements.
  *
- * The SI_SUB_RUN_SCHEDULER value must have the highest lexical value.
+ * The SI_SUB_LAST value must have the highest lexical value.
  *
  * The SI_SUB_SWAP values represent a value used by
  * the BSD 4.4Lite but not by FreeBSD; it is maintained in dependent
@@ -172,7 +172,7 @@ enum sysinit_sub_id {
 	SI_SUB_KTHREAD_IDLE	= 0xee00000,	/* idle procs*/
 	SI_SUB_SMP		= 0xf000000,	/* start the APs*/
 	SI_SUB_RACCTD		= 0xf100000,	/* start raccd*/
-	SI_SUB_RUN_SCHEDULER	= 0xfffffff	/* scheduler*/
+	SI_SUB_LAST		= 0xfffffff	/* final initialization */
 };
 
 
diff --git a/freebsd/sys/sys/linker.h b/freebsd/sys/sys/linker.h
index 6948bb2..29db893 100644
--- a/freebsd/sys/sys/linker.h
+++ b/freebsd/sys/sys/linker.h
@@ -92,10 +92,6 @@ struct linker_file {
      */
     int			nenabled;	/* number of enabled probes. */
     int			fbt_nentries;	/* number of fbt entries created. */
-    void		*sdt_probes;
-    int			sdt_nentries;
-    size_t		sdt_nprobes;
-    size_t		sdt_size;
 };
 
 /*
diff --git a/freebsd/sys/sys/lockmgr.h b/freebsd/sys/sys/lockmgr.h
index 4c3a272..10227cd 100644
--- a/freebsd/sys/sys/lockmgr.h
+++ b/freebsd/sys/sys/lockmgr.h
@@ -168,6 +168,7 @@ _lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
 #define	LK_RELEASE	0x100000
 #define	LK_SHARED	0x200000
 #define	LK_UPGRADE	0x400000
+#define	LK_TRYUPGRADE	0x800000
 
 #define	LK_TOTAL_MASK	(LK_INIT_MASK | LK_EATTR_MASK | LK_TYPE_MASK)
 
diff --git a/freebsd/sys/sys/mbuf.h b/freebsd/sys/sys/mbuf.h
index 1232875..b6d58a2 100644
--- a/freebsd/sys/sys/mbuf.h
+++ b/freebsd/sys/sys/mbuf.h
@@ -396,7 +396,6 @@ struct mbstat {
  *
  * The rest of it is defined in kern/kern_mbuf.c
  */
-
 extern uma_zone_t	zone_mbuf;
 extern uma_zone_t	zone_clust;
 extern uma_zone_t	zone_pack;
@@ -451,6 +450,28 @@ m_gettype(int size)
 	return (type);
 }
 
+/*
+ * Associated an external reference counted buffer with an mbuf.
+ */
+static __inline void
+m_extaddref(struct mbuf *m, caddr_t buf, u_int size, u_int *ref_cnt,
+    void (*freef)(void *, void *), void *arg1, void *arg2)
+{
+
+	KASSERT(ref_cnt != NULL, ("%s: ref_cnt not provided", __func__));
+
+	atomic_add_int((int*)ref_cnt, 1);
+	m->m_flags |= M_EXT;
+	m->m_ext.ext_buf = buf;
+	m->m_ext.ref_cnt = ref_cnt;
+	m->m_data = m->m_ext.ext_buf;
+	m->m_ext.ext_size = size;
+	m->m_ext.ext_free = freef;
+	m->m_ext.ext_arg1 = arg1;
+	m->m_ext.ext_arg2 = arg2;
+	m->m_ext.ext_type = EXT_EXTREF;
+}
+
 static __inline uma_zone_t
 m_getzone(int size)
 {
diff --git a/freebsd/sys/sys/mman.h b/freebsd/sys/sys/mman.h
index 5ed9cdd..c79ad86 100644
--- a/freebsd/sys/sys/mman.h
+++ b/freebsd/sys/sys/mman.h
@@ -91,6 +91,17 @@
  */
 #define	MAP_NOCORE	 0x00020000 /* dont include these pages in a coredump */
 #define	MAP_PREFAULT_READ 0x00040000 /* prefault mapping for reading */
+
+/*
+ * Request specific alignment (n == log2 of the desired alignment).
+ *
+ * MAP_ALIGNED_SUPER requests optimal superpage alignment, but does
+ * not enforce a specific alignment.
+ */
+#define	MAP_ALIGNED(n)	 ((n) << MAP_ALIGNMENT_SHIFT)
+#define	MAP_ALIGNMENT_SHIFT	24
+#define	MAP_ALIGNMENT_MASK	MAP_ALIGNED(0xff)
+#define	MAP_ALIGNED_SUPER	MAP_ALIGNED(1) /* align on a superpage */
 #endif /* __BSD_VISIBLE */
 
 #if __POSIX_VISIBLE >= 199309
diff --git a/freebsd/sys/sys/pciio.h b/freebsd/sys/sys/pciio.h
index a0c4560..d70bfbc 100644
--- a/freebsd/sys/sys/pciio.h
+++ b/freebsd/sys/sys/pciio.h
@@ -116,10 +116,31 @@ struct pci_bar_io {
 	uint64_t	pbi_length;	/* length of BAR */
 };
 
+struct pci_vpd_element {
+	char		pve_keyword[2];
+	uint8_t		pve_flags;
+	uint8_t		pve_datalen;
+	uint8_t		pve_data[0];
+};
+
+#define	PVE_FLAG_IDENT		0x01	/* Element is the string identifier */
+#define	PVE_FLAG_RW		0x02	/* Element is read/write */
+
+#define	PVE_NEXT(pve)							\
+	((struct pci_vpd_element *)((char *)(pve) +			\
+	    sizeof(struct pci_vpd_element) + (pve)->pve_datalen))
+
+struct pci_list_vpd_io {
+	struct pcisel	plvi_sel;	/* device to operate on */
+	size_t		plvi_len;	/* size of the data area */
+	struct pci_vpd_element *plvi_data;
+};
+
 #define	PCIOCGETCONF	_IOWR('p', 5, struct pci_conf_io)
 #define	PCIOCREAD	_IOWR('p', 2, struct pci_io)
 #define	PCIOCWRITE	_IOWR('p', 3, struct pci_io)
 #define	PCIOCATTACHED	_IOWR('p', 4, struct pci_io)
 #define	PCIOCGETBAR	_IOWR('p', 6, struct pci_bar_io)
+#define	PCIOCLISTVPD	_IOWR('p', 7, struct pci_list_vpd_io)
 
 #endif /* !_SYS_PCIIO_H_ */
diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h
index 58d7d6c..1db9f8c 100644
--- a/freebsd/sys/sys/proc.h
+++ b/freebsd/sys/sys/proc.h
@@ -438,6 +438,8 @@ do {									\
 #define	TDP_RESETSPUR	0x04000000 /* Reset spurious page fault history. */
 #define	TDP_NERRNO	0x08000000 /* Last errno is already in td_errno */
 #define	TDP_UIOHELD	0x10000000 /* Current uio has pages held in td_ma */
+#define	TDP_DEVMEMIO	0x20000000 /* Accessing memory for /dev/mem */
+#define	TDP_EXECVMSPC	0x40000000 /* Execve destroyed old vmspace */
 
 /*
  * Reasons that the current thread can not be run yet.
@@ -507,11 +509,8 @@ struct proc {
 	struct callout	p_limco;	/* (c) Limit callout handle */
 	struct sigacts	*p_sigacts;	/* (x) Signal actions, state (CPU). */
 
-	/*
-	 * The following don't make too much sense.
-	 * See the td_ or ke_ versions of the same flags.
-	 */
 	int		p_flag;		/* (c) P_* flags. */
+	int		p_flag2;	/* (c) P2_* flags. */
 	enum {
 		PRS_NEW = 0,		/* In creation */
 		PRS_NORMAL,		/* threads can be run. */
@@ -658,6 +657,9 @@ struct proc {
 #define	P_SHOULDSTOP(p)	((p)->p_flag & P_STOPPED)
 #define	P_KILLED(p)	((p)->p_flag & P_WKILLED)
 
+/* These flags are kept in p_flag2. */
+#define	P2_INHERIT_PROTECTED 0x00000001 /* New children get P_PROTECTED. */
+
 /*
  * These were process status values (p_stat), now they are only used in
  * legacy conversion code.
diff --git a/freebsd/sys/sys/refcount.h b/freebsd/sys/sys/refcount.h
index 572a64e..b169f54 100644
--- a/freebsd/sys/sys/refcount.h
+++ b/freebsd/sys/sys/refcount.h
@@ -10,9 +10,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/freebsd/sys/sys/rmlock.h b/freebsd/sys/sys/rmlock.h
index 487cb39..e71789a 100644
--- a/freebsd/sys/sys/rmlock.h
+++ b/freebsd/sys/sys/rmlock.h
@@ -66,6 +66,10 @@ void	_rm_wunlock(struct rmlock *rm);
 int	_rm_rlock(struct rmlock *rm, struct rm_priotracker *tracker,
 	    int trylock);
 void	_rm_runlock(struct rmlock *rm,  struct rm_priotracker *tracker);
+#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
+void	_rm_assert(struct rmlock *rm, int what, const char *file,
+	    int line);
+#endif
 
 /*
  * Public interface for lock operations.
@@ -90,6 +94,9 @@ void	_rm_runlock(struct rmlock *rm,  struct rm_priotracker *tracker);
 #define	rm_try_rlock(rm,tracker)	_rm_rlock((rm),(tracker), 1)
 #define	rm_runlock(rm,tracker)		_rm_runlock((rm), (tracker))
 #endif
+#define	rm_sleep(chan, rm, pri, wmesg, timo)				\
+	_sleep((chan), &(rm)->lock_object, (pri), (wmesg),		\
+	    tick_sbt * (timo), 0, C_HARDCLOCK)
 
 #else /* __rtems__ */
   #define rm_init(rm, name)                rw_init(rm, name)
@@ -140,5 +147,20 @@ struct rm_args_flags {
 	SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
 	    rm_destroy, (rm))
 
+#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
+#define	RA_LOCKED		LA_LOCKED
+#define	RA_RLOCKED		LA_SLOCKED
+#define	RA_WLOCKED		LA_XLOCKED
+#define	RA_UNLOCKED		LA_UNLOCKED
+#define	RA_RECURSED		LA_RECURSED
+#define	RA_NOTRECURSED		LA_NOTRECURSED
+#endif
+
+#ifdef INVARIANTS
+#define	rm_assert(rm, what)	_rm_assert((rm), (what), LOCK_FILE, LOCK_LINE)
+#else
+#define	rm_assert(rm, what)
+#endif
+
 #endif /* _KERNEL */
 #endif /* !_SYS_RMLOCK_H_ */
diff --git a/freebsd/sys/sys/rwlock.h b/freebsd/sys/sys/rwlock.h
index ec2aed2..2dd1a25 100644
--- a/freebsd/sys/sys/rwlock.h
+++ b/freebsd/sys/sys/rwlock.h
@@ -10,9 +10,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/freebsd/sys/sys/sdt.h b/freebsd/sys/sys/sdt.h
index f2f9b31..ca820f6 100644
--- a/freebsd/sys/sys/sdt.h
+++ b/freebsd/sys/sys/sdt.h
@@ -77,23 +77,27 @@
 
 #else /* _KERNEL */
 
+#include <sys/cdefs.h>
+#include <sys/linker_set.h>
+
 #ifndef KDTRACE_HOOKS
 
 #define SDT_PROVIDER_DEFINE(prov)
 #define SDT_PROVIDER_DECLARE(prov)
-#define SDT_PROBE_DEFINE(prov, mod, func, name, sname)
+#define SDT_PROBE_DEFINE(prov, mod, func, name)
 #define SDT_PROBE_DECLARE(prov, mod, func, name)
 #define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4)
-#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type)
-
-#define	SDT_PROBE_DEFINE1(prov, mod, func, name, sname, arg0)
-#define	SDT_PROBE_DEFINE2(prov, mod, func, name, sname, arg0, arg1)
-#define	SDT_PROBE_DEFINE3(prov, mod, func, name, sname, arg0, arg1, arg2)
-#define	SDT_PROBE_DEFINE4(prov, mod, func, name, sname, arg0, arg1, arg2, arg3)
-#define	SDT_PROBE_DEFINE5(prov, mod, func, name, sname, arg0, arg1, arg2, arg3, arg4)
-#define	SDT_PROBE_DEFINE6(prov, mod, func, name, snamp, arg0, arg1, arg2,      \
+#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type, xtype)
+
+#define	SDT_PROBE_DEFINE0(prov, mod, func, name)
+#define	SDT_PROBE_DEFINE1(prov, mod, func, name, arg0)
+#define	SDT_PROBE_DEFINE2(prov, mod, func, name, arg0, arg1)
+#define	SDT_PROBE_DEFINE3(prov, mod, func, name, arg0, arg1, arg2)
+#define	SDT_PROBE_DEFINE4(prov, mod, func, name, arg0, arg1, arg2, arg3)
+#define	SDT_PROBE_DEFINE5(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4)
+#define	SDT_PROBE_DEFINE6(prov, mod, func, name, arg0, arg1, arg2,      \
     arg3, arg4, arg5)
-#define	SDT_PROBE_DEFINE7(prov, mod, func, name, snamp, arg0, arg1, arg2,      \
+#define	SDT_PROBE_DEFINE7(prov, mod, func, name, arg0, arg1, arg2,      \
     arg3, arg4, arg5, arg6)
 
 #define	SDT_PROBE0(prov, mod, func, name)
@@ -106,159 +110,182 @@
 #define	SDT_PROBE7(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4, arg5,  \
     arg6)
 
-#else
-
-/*
- * This type definition must match that of dtrace_probe. It is defined this
- * way to avoid having to rely on CDDL code.
- */
-typedef	void (*sdt_probe_func_t)(u_int32_t, uintptr_t arg0, uintptr_t arg1,
-    uintptr_t arg2, uintptr_t arg3, uintptr_t arg4);
+#define	SDT_PROBE_DEFINE0_XLATE(prov, mod, func, name)
+#define	SDT_PROBE_DEFINE1_XLATE(prov, mod, func, name, arg0, xarg0)
+#define	SDT_PROBE_DEFINE2_XLATE(prov, mod, func, name, arg0, xarg0,     \
+    arg1, xarg1)
+#define	SDT_PROBE_DEFINE3_XLATE(prov, mod, func, name, arg0, xarg0,     \
+    arg1, xarg1, arg2, xarg2)
+#define SDT_PROBE_DEFINE4_XLATE(prov, mod, func, name, arg0, xarg0,     \
+    arg1, xarg1, arg2, xarg2, arg3, xarg3)
+#define	SDT_PROBE_DEFINE5_XLATE(prov, mod, func, name, arg0, xarg0,     \
+    arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4)
+#define	SDT_PROBE_DEFINE6_XLATE(prov, mod, func, name, arg0, xarg0,     \
+    arg1,  xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4, arg5, xarg5)
+#define	SDT_PROBE_DEFINE7_XLATE(prov, mod, func, name, arg0, xarg0,     \
+    arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4, arg5, xarg5, arg6,     \
+    xarg6)
+
+#define	DTRACE_PROBE(name)
+#define	DTRACE_PROBE1(name, type0, arg0)
+#define	DTRACE_PROBE2(name, type0, arg0, type1, arg1)
+#define	DTRACE_PROBE3(name, type0, arg0, type1, arg1, type2, arg2)
+#define	DTRACE_PROBE4(name, type0, arg0, type1, arg1, type2, arg2, type3, arg3)
+#define	DTRACE_PROBE5(name, type0, arg0, type1, arg1, type2, arg2, type3, arg3,\
+    type4, arg4)
 
-/*
- * The hook for the probe function. See kern_sdt.c which defaults this to
- * it's own stub. The 'sdt' provider will set it to dtrace_probe when it
- * loads.
- */
-extern sdt_probe_func_t	sdt_probe_func;
-
-typedef enum {
-	SDT_UNINIT = 1,
-	SDT_INIT,
-} sdt_state_t;
-
-struct sdt_probe;
-struct sdt_provider;
-
-struct sdt_argtype {
-	int	ndx;			/* Argument index. */
-	const char *type;		/* Argument type string. */
-	TAILQ_ENTRY(sdt_argtype)
-			argtype_entry;	/* Argument type list entry. */
-	struct sdt_probe
-			*probe;		/* Ptr to the probe structure. */
-};
-
-struct sdt_probe {
-	int		version;	/* Set to sizeof(struct sdt_ref). */
-	sdt_state_t	state;
-	struct sdt_provider
-			*prov;		/* Ptr to the provider structure. */
-	TAILQ_ENTRY(sdt_probe)
-			probe_entry;	/* SDT probe list entry. */
-	TAILQ_HEAD(argtype_list_head, sdt_argtype) argtype_list;
-	const char	*mod;
-	const char	*func;
-	const char	*name;
-	id_t		id;		/* DTrace probe ID. */
-	int		n_args;		/* Number of arguments. */
-};
+#else
 
-struct sdt_provider {
-	const char *name;		/* Provider name. */
-	TAILQ_ENTRY(sdt_provider)
-			prov_entry;	/* SDT provider list entry. */
-	TAILQ_HEAD(probe_list_head, sdt_probe) probe_list;
-	uintptr_t	id;		/* DTrace provider ID. */
-};
+SET_DECLARE(sdt_providers_set, struct sdt_provider);
+SET_DECLARE(sdt_probes_set, struct sdt_probe);
+SET_DECLARE(sdt_argtypes_set, struct sdt_argtype);
 
 #define SDT_PROVIDER_DEFINE(prov)						\
 	struct sdt_provider sdt_provider_##prov[1] = {				\
-		{ #prov, { NULL, NULL }, { NULL, NULL } }			\
+		{ #prov, { NULL, NULL }, 0, 0 }					\
 	};									\
-	SYSINIT(sdt_provider_##prov##_init, SI_SUB_KDTRACE, 			\
-	    SI_ORDER_SECOND, sdt_provider_register, 				\
-	    sdt_provider_##prov );						\
-	SYSUNINIT(sdt_provider_##prov##_uninit, SI_SUB_KDTRACE,			\
-	    SI_ORDER_SECOND, sdt_provider_deregister, 				\
-	    sdt_provider_##prov )
+	DATA_SET(sdt_providers_set, sdt_provider_##prov);
 
 #define SDT_PROVIDER_DECLARE(prov)						\
 	extern struct sdt_provider sdt_provider_##prov[1]
 
-#define SDT_PROBE_DEFINE(prov, mod, func, name, sname)				\
+#define SDT_PROBE_DEFINE(prov, mod, func, name)					\
 	struct sdt_probe sdt_##prov##_##mod##_##func##_##name[1] = {		\
-		{ sizeof(struct sdt_probe), 0, sdt_provider_##prov,		\
-		    { NULL, NULL }, { NULL, NULL }, #mod, #func, #sname, 0, 0 }	\
+		{ sizeof(struct sdt_probe), sdt_provider_##prov,		\
+		    { NULL, NULL }, { NULL, NULL }, #mod, #func, #name, 0, 0,	\
+		    NULL }							\
 	};									\
-	SYSINIT(sdt_##prov##_##mod##_##func##_##name##_init, SI_SUB_KDTRACE, 	\
-	    SI_ORDER_SECOND + 1, sdt_probe_register, 				\
-	    sdt_##prov##_##mod##_##func##_##name );				\
-	SYSUNINIT(sdt_##prov##_##mod##_##func##_##name##_uninit, 		\
-	    SI_SUB_KDTRACE, SI_ORDER_SECOND + 1, sdt_probe_deregister, 		\
-	    sdt_##prov##_##mod##_##func##_##name )
+	DATA_SET(sdt_probes_set, sdt_##prov##_##mod##_##func##_##name);
 
 #define SDT_PROBE_DECLARE(prov, mod, func, name)				\
 	extern struct sdt_probe sdt_##prov##_##mod##_##func##_##name[1]
 
-#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4)		\
+#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4)	do {	\
 	if (sdt_##prov##_##mod##_##func##_##name->id)				\
 		(*sdt_probe_func)(sdt_##prov##_##mod##_##func##_##name->id,	\
 		    (uintptr_t) arg0, (uintptr_t) arg1, (uintptr_t) arg2,	\
-		    (uintptr_t) arg3, (uintptr_t) arg4)
+		    (uintptr_t) arg3, (uintptr_t) arg4);			\
+} while (0)
 
-#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type)			\
-	struct sdt_argtype sdt_##prov##_##mod##_##func##_##name##num[1]		\
-	    = { { num, type, { NULL, NULL },					\
+#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type, xtype)		\
+	static struct sdt_argtype sdta_##prov##_##mod##_##func##_##name##num[1]	\
+	    = { { num, type, xtype, { NULL, NULL },				\
 	    sdt_##prov##_##mod##_##func##_##name }				\
 	};									\
-	SYSINIT(sdt_##prov##_##mod##_##func##_##name##num##_init,		\
-	    SI_SUB_KDTRACE, SI_ORDER_SECOND + 2, sdt_argtype_register, 		\
-	    sdt_##prov##_##mod##_##func##_##name##num );			\
-	SYSUNINIT(sdt_##prov##_##mod##_##func##_##name##num##_uninit, 		\
-	    SI_SUB_KDTRACE, SI_ORDER_SECOND + 2, sdt_argtype_deregister,	\
-	    sdt_##prov##_##mod##_##func##_##name##num )
-
-#define	SDT_PROBE_DEFINE1(prov, mod, func, name, sname, arg0)		\
-	SDT_PROBE_DEFINE(prov, mod, func, name, sname);			\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0)
-
-#define	SDT_PROBE_DEFINE2(prov, mod, func, name, sname, arg0, arg1)	\
-	SDT_PROBE_DEFINE(prov, mod, func, name, sname);			\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1)
-
-#define	SDT_PROBE_DEFINE3(prov, mod, func, name, sname, arg0, arg1, arg2)\
-	SDT_PROBE_DEFINE(prov, mod, func, name, sname);			\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2)
-
-#define	SDT_PROBE_DEFINE4(prov, mod, func, name, sname, arg0, arg1, arg2, arg3) \
-	SDT_PROBE_DEFINE(prov, mod, func, name, sname);			\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3)
-
-#define	SDT_PROBE_DEFINE5(prov, mod, func, name, sname, arg0, arg1, arg2, arg3, arg4) \
-	SDT_PROBE_DEFINE(prov, mod, func, name, sname);			\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4)
-
-#define	SDT_PROBE_DEFINE6(prov, mod, func, name, sname, arg0, arg1, arg2, arg3,\
+	DATA_SET(sdt_argtypes_set, sdta_##prov##_##mod##_##func##_##name##num);
+
+#define	SDT_PROBE_DEFINE0(prov, mod, func, name)			\
+	SDT_PROBE_DEFINE(prov, mod, func, name)
+
+#define	SDT_PROBE_DEFINE1(prov, mod, func, name, arg0)			\
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL)
+
+#define	SDT_PROBE_DEFINE2(prov, mod, func, name, arg0, arg1)		\
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL)
+
+#define	SDT_PROBE_DEFINE3(prov, mod, func, name, arg0, arg1, arg2)\
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, NULL)
+
+#define	SDT_PROBE_DEFINE4(prov, mod, func, name, arg0, arg1, arg2, arg3) \
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, NULL)
+
+#define	SDT_PROBE_DEFINE5(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) \
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, NULL)
+
+#define	SDT_PROBE_DEFINE6(prov, mod, func, name, arg0, arg1, arg2, arg3,\
     arg4, arg5) \
-	SDT_PROBE_DEFINE(prov, mod, func, name, sname);			\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5);
-
-#define	SDT_PROBE_DEFINE7(prov, mod, func, name, sname, arg0, arg1, arg2, arg3,\
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5, NULL)
+
+#define	SDT_PROBE_DEFINE7(prov, mod, func, name, arg0, arg1, arg2, arg3,\
     arg4, arg5, arg6) \
-	SDT_PROBE_DEFINE(prov, mod, func, name, sname);			\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5);		\
-	SDT_PROBE_ARGTYPE(prov, mod, func, name, 6, arg6);
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5, NULL);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 6, arg6, NULL)
+
+#define	SDT_PROBE_DEFINE0_XLATE(prov, mod, func, name)		\
+	SDT_PROBE_DEFINE(prov, mod, func, name)
+
+#define	SDT_PROBE_DEFINE1_XLATE(prov, mod, func, name, arg0, xarg0) \
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0)
+
+#define	SDT_PROBE_DEFINE2_XLATE(prov, mod, func, name, arg0, xarg0, \
+    arg1,  xarg1)							\
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1)
+
+#define	SDT_PROBE_DEFINE3_XLATE(prov, mod, func, name, arg0, xarg0, \
+    arg1, xarg1, arg2, xarg2)						\
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, xarg2)
+
+#define	SDT_PROBE_DEFINE4_XLATE(prov, mod, func, name, arg0, xarg0, \
+    arg1, xarg1, arg2, xarg2, arg3, xarg3)				\
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, xarg2);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, xarg3)
+
+#define	SDT_PROBE_DEFINE5_XLATE(prov, mod, func, name, arg0, xarg0, \
+    arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4)			\
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, xarg2);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, xarg3);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, xarg4)
+
+#define	SDT_PROBE_DEFINE6_XLATE(prov, mod, func, name, arg0, xarg0, \
+    arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4, arg5, xarg5)	\
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, xarg2);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, xarg3);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, xarg4);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5, xarg5)
+
+#define	SDT_PROBE_DEFINE7_XLATE(prov, mod, func, name, arg0, xarg0, \
+    arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4, arg5, xarg5, arg6, \
+    xarg6)								\
+	SDT_PROBE_DEFINE(prov, mod, func, name);			\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, xarg2);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, xarg3);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, xarg4);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5, xarg5);	\
+	SDT_PROBE_ARGTYPE(prov, mod, func, name, 6, arg6, xarg6)
 
 #define	SDT_PROBE0(prov, mod, func, name)				\
 	SDT_PROBE(prov, mod, func, name, 0, 0, 0, 0, 0)
@@ -294,28 +321,105 @@ struct sdt_provider {
 			    (uintptr_t)arg6);				       \
 	} while (0)
 
-typedef int (*sdt_argtype_listall_func_t)(struct sdt_argtype *, void *);
-typedef int (*sdt_probe_listall_func_t)(struct sdt_probe *, void *);
-typedef int (*sdt_provider_listall_func_t)(struct sdt_provider *, void *);
-
-void sdt_argtype_deregister(void *);
-void sdt_argtype_register(void *);
-void sdt_probe_deregister(void *);
-void sdt_probe_register(void *);
-void sdt_provider_deregister(void *);
-void sdt_provider_register(void *);
-void sdt_probe_stub(u_int32_t, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2,
-    uintptr_t arg3, uintptr_t arg4);
-int sdt_argtype_listall(struct sdt_probe *, sdt_argtype_listall_func_t, void *);
-int sdt_probe_listall(struct sdt_provider *, sdt_probe_listall_func_t, void *);
-int sdt_provider_listall(sdt_provider_listall_func_t,void *);
-
-void sdt_register_callbacks(sdt_provider_listall_func_t, void *,
-    sdt_provider_listall_func_t, void *, sdt_probe_listall_func_t, void *);
-void sdt_deregister_callbacks(void);
+#define	DTRACE_PROBE_IMPL_START(name, arg0, arg1, arg2, arg3, arg4)	do { \
+	static SDT_PROBE_DEFINE(sdt, , , name);				     \
+	SDT_PROBE(sdt, , , name, arg0, arg1, arg2, arg3, arg4);
+#define DTRACE_PROBE_IMPL_END	} while (0)
+
+#define DTRACE_PROBE(name)						\
+	DTRACE_PROBE_IMPL_START(name, 0, 0, 0, 0, 0)			\
+	DTRACE_PROBE_IMPL_END
+
+#define DTRACE_PROBE1(name, type0, arg0)				\
+	DTRACE_PROBE_IMPL_START(name, arg0, 0, 0, 0, 0) 		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 0, #type0, NULL);		\
+	DTRACE_PROBE_IMPL_END
+
+#define DTRACE_PROBE2(name, type0, arg0, type1, arg1)			\
+	DTRACE_PROBE_IMPL_START(name, arg0, arg1, 0, 0, 0) 		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 0, #type0, NULL);		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 1, #type1, NULL);		\
+	DTRACE_PROBE_IMPL_END
+
+#define DTRACE_PROBE3(name, type0, arg0, type1, arg1, type2, arg2)	\
+	DTRACE_PROBE_IMPL_START(name, arg0, arg1, arg2, 0, 0)	 	\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 0, #type0, NULL);		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 1, #type1, NULL);		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 2, #type2, NULL);		\
+	DTRACE_PROBE_IMPL_END
+
+#define DTRACE_PROBE4(name, type0, arg0, type1, arg1, type2, arg2, type3, arg3)	\
+	DTRACE_PROBE_IMPL_START(name, arg0, arg1, arg2, arg3, 0) 	\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 0, #type0, NULL);		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 1, #type1, NULL);		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 2, #type2, NULL);		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 3, #type3, NULL);		\
+	DTRACE_PROBE_IMPL_END
+
+#define DTRACE_PROBE5(name, type0, arg0, type1, arg1, type2, arg2, type3, arg3,	\
+    type4, arg4)								\
+	DTRACE_PROBE_IMPL_START(name, arg0, arg1, arg2, arg3, arg4) 	\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 0, #type0, NULL);		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 1, #type1, NULL);		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 2, #type2, NULL);		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 3, #type3, NULL);		\
+	SDT_PROBE_ARGTYPE(sdt, , , name, 4, #type4, NULL);		\
+	DTRACE_PROBE_IMPL_END
 
 #endif /* KDTRACE_HOOKS */
 
+/*
+ * This type definition must match that of dtrace_probe. It is defined this
+ * way to avoid having to rely on CDDL code.
+ */
+typedef	void (*sdt_probe_func_t)(uint32_t, uintptr_t arg0, uintptr_t arg1,
+    uintptr_t arg2, uintptr_t arg3, uintptr_t arg4);
+
+/*
+ * The 'sdt' provider will set it to dtrace_probe when it loads.
+ */
+extern sdt_probe_func_t	sdt_probe_func;
+
+struct sdt_probe;
+struct sdt_provider;
+struct linker_file;
+
+struct sdt_argtype {
+	int		ndx;		/* Argument index. */
+	const char	*type;		/* Argument type string. */
+	const char	*xtype;		/* Translated argument type. */
+	TAILQ_ENTRY(sdt_argtype)
+			argtype_entry;	/* Argument type list entry. */
+	struct sdt_probe *probe;	/* Ptr to the probe structure. */
+};
+
+struct sdt_probe {
+	int		version;	/* Set to sizeof(struct sdt_probe). */
+	struct sdt_provider *prov;	/* Ptr to the provider structure. */
+	TAILQ_ENTRY(sdt_probe)
+			probe_entry;	/* SDT probe list entry. */
+	TAILQ_HEAD(argtype_list_head, sdt_argtype) argtype_list;
+	const char	*mod;
+	const char	*func;
+	const char	*name;
+	id_t		id;		/* DTrace probe ID. */
+	int		n_args;		/* Number of arguments. */
+	struct linker_file *sdtp_lf;	/* Module in which we're defined. */
+};
+
+struct sdt_provider {
+	char *name;			/* Provider name. */
+	TAILQ_ENTRY(sdt_provider)
+			prov_entry;	/* SDT provider list entry. */
+	uintptr_t	id;		/* DTrace provider ID. */
+	int		sdt_refs;	/* Number of module references. */
+};
+
+void sdt_probe_stub(uint32_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t,
+    uintptr_t);
+
+SDT_PROVIDER_DECLARE(sdt);
+
 #endif /* _KERNEL */
 
 #endif /* _SYS_SDT_H */
diff --git a/freebsd/sys/sys/sockbuf.h b/freebsd/sys/sys/sockbuf.h
index bfccd74..84fd1aa 100644
--- a/freebsd/sys/sys/sockbuf.h
+++ b/freebsd/sys/sys/sockbuf.h
@@ -127,6 +127,8 @@ int	sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
 	    struct mbuf *m0, struct mbuf *control);
 int	sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
 	    struct mbuf *m0, struct mbuf *control);
+int	sbappendaddr_nospacecheck_locked(struct sockbuf *sb,
+	    const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control);
 int	sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
 	    struct mbuf *control);
 int	sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
diff --git a/freebsd/sys/sys/sysctl.h b/freebsd/sys/sys/sysctl.h
index cf7b90c..1fca343 100644
--- a/freebsd/sys/sys/sysctl.h
+++ b/freebsd/sys/sys/sysctl.h
@@ -593,6 +593,7 @@ SYSCTL_ALLOWED_TYPES(UINT64, uint64_t *a; unsigned long long *b; );
 #define	KERN_PROC_PS_STRINGS	38	/* get ps_strings location */
 #define	KERN_PROC_UMASK		39	/* process umask */
 #define	KERN_PROC_OSREL		40	/* osreldate for process binary */
+#define	KERN_PROC_SIGTRAMP	41	/* signal trampoline location */
 
 /*
  * KERN_IPC identifiers
diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h
index 5b7b190..ed58a48 100644
--- a/freebsd/sys/sys/sysproto.h
+++ b/freebsd/sys/sys/sysproto.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: stable/9/sys/kern/syscalls.master 251051 2013-05-28 05:51:00Z kib 
+ * created from FreeBSD: stable/9/sys/kern/syscalls.master 260208 2014-01-02 21:57:03Z jhb 
  */
 
 #ifndef _SYS_SYSPROTO_H_
@@ -14,6 +14,7 @@
 #include <rtems/bsd/sys/cpuset.h>
 #include <sys/_semaphore.h>
 #include <sys/ucontext.h>
+#include <sys/wait.h>
 
 #include <bsm/audit_kevents.h>
 
@@ -765,6 +766,11 @@ struct nanosleep_args {
 	char rqtp_l_[PADL_(const struct timespec *)]; const struct timespec * rqtp; char rqtp_r_[PADR_(const struct timespec *)];
 	char rmtp_l_[PADL_(struct timespec *)]; struct timespec * rmtp; char rmtp_r_[PADR_(struct timespec *)];
 };
+struct clock_getcpuclockid2_args {
+	char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
+	char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)];
+	char clock_id_l_[PADL_(clockid_t *)]; clockid_t * clock_id; char clock_id_r_[PADR_(clockid_t *)];
+};
 struct ntp_gettime_args {
 	char ntvp_l_[PADL_(struct ntptimeval *)]; struct ntptimeval * ntvp; char ntvp_r_[PADR_(struct ntptimeval *)];
 };
@@ -1785,13 +1791,19 @@ struct posix_fadvise_args {
 	char advice_l_[PADL_(int)]; int advice; char advice_r_[PADR_(int)];
 };
 struct wait6_args {
-	char idtype_l_[PADL_(int)]; int idtype; char idtype_r_[PADR_(int)];
+	char idtype_l_[PADL_(idtype_t)]; idtype_t idtype; char idtype_r_[PADR_(idtype_t)];
 	char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
 	char status_l_[PADL_(int *)]; int * status; char status_r_[PADR_(int *)];
 	char options_l_[PADL_(int)]; int options; char options_r_[PADR_(int)];
 	char wrusage_l_[PADL_(struct __wrusage *)]; struct __wrusage * wrusage; char wrusage_r_[PADR_(struct __wrusage *)];
 	char info_l_[PADL_(siginfo_t *)]; siginfo_t * info; char info_r_[PADR_(siginfo_t *)];
 };
+struct procctl_args {
+	char idtype_l_[PADL_(idtype_t)]; idtype_t idtype; char idtype_r_[PADR_(idtype_t)];
+	char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
+	char com_l_[PADL_(int)]; int com; char com_r_[PADR_(int)];
+	char data_l_[PADL_(void *)]; void * data; char data_r_[PADR_(void *)];
+};
 int	nosys(struct thread *, struct nosys_args *);
 void	sys_sys_exit(struct thread *, struct sys_exit_args *);
 int	sys_fork(struct thread *, struct fork_args *);
@@ -1947,6 +1959,7 @@ int	sys_ktimer_settime(struct thread *, struct ktimer_settime_args *);
 int	sys_ktimer_gettime(struct thread *, struct ktimer_gettime_args *);
 int	sys_ktimer_getoverrun(struct thread *, struct ktimer_getoverrun_args *);
 int	sys_nanosleep(struct thread *, struct nanosleep_args *);
+int	sys_clock_getcpuclockid2(struct thread *, struct clock_getcpuclockid2_args *);
 int	sys_ntp_gettime(struct thread *, struct ntp_gettime_args *);
 int	sys_minherit(struct thread *, struct minherit_args *);
 int	sys_rfork(struct thread *, struct rfork_args *);
@@ -2170,6 +2183,7 @@ int	sys_rctl_remove_rule(struct thread *, struct rctl_remove_rule_args *);
 int	sys_posix_fallocate(struct thread *, struct posix_fallocate_args *);
 int	sys_posix_fadvise(struct thread *, struct posix_fadvise_args *);
 int	sys_wait6(struct thread *, struct wait6_args *);
+int	sys_procctl(struct thread *, struct procctl_args *);
 
 #ifdef COMPAT_43
 
@@ -2635,6 +2649,7 @@ int	freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
 #define	SYS_AUE_ktimer_gettime	AUE_NULL
 #define	SYS_AUE_ktimer_getoverrun	AUE_NULL
 #define	SYS_AUE_nanosleep	AUE_NULL
+#define	SYS_AUE_clock_getcpuclockid2	AUE_NULL
 #define	SYS_AUE_ntp_gettime	AUE_NULL
 #define	SYS_AUE_minherit	AUE_MINHERIT
 #define	SYS_AUE_rfork	AUE_RFORK
@@ -2862,6 +2877,7 @@ int	freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
 #define	SYS_AUE_posix_fallocate	AUE_NULL
 #define	SYS_AUE_posix_fadvise	AUE_NULL
 #define	SYS_AUE_wait6	AUE_WAIT6
+#define	SYS_AUE_procctl	AUE_NULL
 #endif /* __rtems__ */
 
 #undef PAD_
diff --git a/freebsd/sys/sys/systm.h b/freebsd/sys/sys/systm.h
index 44d2208..18ca646 100644
--- a/freebsd/sys/sys/systm.h
+++ b/freebsd/sys/sys/systm.h
@@ -156,7 +156,9 @@ extern const void *zero_region;	/* address space maps to a zeroed page	*/
 
 extern int unmapped_buf_allowed;
 extern int iosize_max_clamp;
+extern int devfs_iosize_max_clamp;
 #define	IOSIZE_MAX	(iosize_max_clamp ? INT_MAX : SSIZE_MAX)
+#define	DEVFS_IOSIZE_MAX	(devfs_iosize_max_clamp ? INT_MAX : SSIZE_MAX)
 
 /*
  * General function declarations.
diff --git a/freebsd/sys/sys/taskqueue.h b/freebsd/sys/sys/taskqueue.h
index b4c7d20..6800002 100644
--- a/freebsd/sys/sys/taskqueue.h
+++ b/freebsd/sys/sys/taskqueue.h
@@ -71,6 +71,7 @@ int	taskqueue_cancel_timeout(struct taskqueue *queue,
 void	taskqueue_drain(struct taskqueue *queue, struct task *task);
 void	taskqueue_drain_timeout(struct taskqueue *queue,
 	    struct timeout_task *timeout_task);
+void	taskqueue_drain_all(struct taskqueue *queue);
 void	taskqueue_free(struct taskqueue *queue);
 void	taskqueue_run(struct taskqueue *queue);
 void	taskqueue_block(struct taskqueue *queue);
diff --git a/freebsd/sys/sys/tty.h b/freebsd/sys/sys/tty.h
index 7061720..00cf4e6 100644
--- a/freebsd/sys/sys/tty.h
+++ b/freebsd/sys/sys/tty.h
@@ -166,6 +166,7 @@ void	tty_rel_gone(struct tty *tp);
 
 #define	tty_lock(tp)		mtx_lock((tp)->t_mtx)
 #define	tty_unlock(tp)		mtx_unlock((tp)->t_mtx)
+#define	tty_lock_owned(tp)	mtx_owned((tp)->t_mtx)
 #define	tty_lock_assert(tp,ma)	mtx_assert((tp)->t_mtx, (ma))
 #define	tty_getlock(tp)		((tp)->t_mtx)
 
@@ -192,6 +193,7 @@ int	tty_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
     struct thread *td);
 int	tty_ioctl_compat(struct tty *tp, u_long cmd, caddr_t data,
     int fflag, struct thread *td);
+void	tty_set_winsize(struct tty *tp, const struct winsize *wsz);
 void	tty_init_console(struct tty *tp, speed_t speed);
 void	tty_flush(struct tty *tp, int flags);
 void	tty_hiwat_in_block(struct tty *tp);
diff --git a/freebsd/sys/sys/user.h b/freebsd/sys/sys/user.h
index 4640167..659a610 100644
--- a/freebsd/sys/sys/user.h
+++ b/freebsd/sys/sys/user.h
@@ -83,7 +83,7 @@
  * it in two places: function fill_kinfo_proc in sys/kern/kern_proc.c and
  * function kvm_proclist in lib/libkvm/kvm_proc.c .
  */
-#define	KI_NSPARE_INT	9
+#define	KI_NSPARE_INT	7
 #define	KI_NSPARE_LONG	12
 #define	KI_NSPARE_PTR	6
 
@@ -186,6 +186,8 @@ struct kinfo_proc {
 	 */
 	char	ki_sparestrings[50];	/* spare string space */
 	int	ki_spareints[KI_NSPARE_INT];	/* spare room for growth */
+	int	ki_flag2;		/* P2_* flags */
+	int	ki_fibnum;		/* Default FIB number */
 	u_int	ki_cr_flags;		/* Credential flags */
 	int	ki_jid;			/* Process jail ID */
 	int	ki_numthreads;		/* XXXKSE number of threads in total */
@@ -407,6 +409,7 @@ struct kinfo_file {
 #define	KVME_TYPE_PHYS		5
 #define	KVME_TYPE_DEAD		6
 #define	KVME_TYPE_SG		7
+#define	KVME_TYPE_MGTDEVICE	8
 #define	KVME_TYPE_UNKNOWN	255
 
 #define	KVME_PROT_READ		0x00000001
@@ -496,6 +499,12 @@ struct kinfo_kstack {
 	int	 _kkst_ispare[16];		/* Space for more stuff. */
 };
 
+struct kinfo_sigtramp {
+	void	*ksigtramp_start;
+	void	*ksigtramp_end;
+	void	*ksigtramp_spare[4];
+};
+
 #ifdef _KERNEL
 /* Flags for kern_proc_out function. */
 #define KERN_PROC_NOTHREADS	0x1
diff --git a/freebsd/sys/vm/uma_core.c b/freebsd/sys/vm/uma_core.c
index e147c2a..8a88caa 100644
--- a/freebsd/sys/vm/uma_core.c
+++ b/freebsd/sys/vm/uma_core.c
@@ -1154,7 +1154,9 @@ keg_small_init(uma_keg_t keg)
 	keg->uk_rsize = rsize;
 	keg->uk_ppera = 1;
 
-	if (keg->uk_flags & UMA_ZONE_REFCNT) {
+	if (keg->uk_flags & UMA_ZONE_OFFPAGE) {
+		shsize = 0;
+	} else if (keg->uk_flags & UMA_ZONE_REFCNT) {
 		rsize += UMA_FRITMREF_SZ;	/* linkage & refcnt */
 		shsize = sizeof(struct uma_slab_refcnt);
 	} else {
@@ -1265,7 +1267,7 @@ keg_cachespread_init(uma_keg_t keg)
 	keg->uk_ipers = ((pages * PAGE_SIZE) + trailer) / rsize;
 	keg->uk_flags |= UMA_ZONE_OFFPAGE | UMA_ZONE_VTOSLAB;
 	KASSERT(keg->uk_ipers <= uma_max_ipers,
-	    ("keg_small_init: keg->uk_ipers too high(%d) increase max_ipers",
+	    ("%s: keg->uk_ipers too high(%d) increase max_ipers", __func__,
 	    keg->uk_ipers));
 }
 
@@ -1547,8 +1549,9 @@ keg_dtor(void *arg, int size, void *udata)
 	keg = (uma_keg_t)arg;
 	KEG_LOCK(keg);
 	if (keg->uk_free != 0) {
-		printf("Freed UMA keg was not empty (%d items). "
+		printf("Freed UMA keg (%s) was not empty (%d items). "
 		    " Lost %d pages of memory.\n",
+		    keg->uk_name ? keg->uk_name : "",
 		    keg->uk_free, keg->uk_pages);
 	}
 	KEG_UNLOCK(keg);
@@ -1720,7 +1723,7 @@ uma_startup(void *bootmem, int boot_pages)
 
 #ifdef UMA_DEBUG
 	printf("Calculated uma_max_ipers (for OFFPAGE) is %d\n", uma_max_ipers);
-	printf("Calculated uma_max_ipers_slab (for OFFPAGE) is %d\n",
+	printf("Calculated uma_max_ipers_ref (for OFFPAGE) is %d\n",
 	    uma_max_ipers_ref);
 #endif
 
diff --git a/freebsd/sys/vm/vm.h b/freebsd/sys/vm/vm.h
index 106c510..17aea47 100644
--- a/freebsd/sys/vm/vm.h
+++ b/freebsd/sys/vm/vm.h
@@ -151,6 +151,7 @@ int swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred);
 void swap_reserve_force(vm_ooffset_t incr);
 void swap_release(vm_ooffset_t decr);
 void swap_release_by_cred(vm_ooffset_t decr, struct ucred *cred);
+void swapper(void);
 
 #endif				/* VM_H */
 
diff --git a/freebsd/sys/vm/vm_extern.h b/freebsd/sys/vm/vm_extern.h
index 8b6c7ac..3b5be26 100644
--- a/freebsd/sys/vm/vm_extern.h
+++ b/freebsd/sys/vm/vm_extern.h
@@ -44,8 +44,8 @@ vm_offset_t kmem_alloc(vm_map_t, vm_size_t);
 vm_offset_t kmem_alloc_attr(vm_map_t map, vm_size_t size, int flags,
     vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr);
 vm_offset_t kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags,
-    vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
-    unsigned long boundary, vm_memattr_t memattr);
+    vm_paddr_t low, vm_paddr_t high, u_long alignment, u_long boundary,
+    vm_memattr_t memattr);
 vm_offset_t kmem_alloc_nofault(vm_map_t, vm_size_t);
 vm_offset_t kmem_alloc_nofault_space(vm_map_t, vm_size_t, int);
 vm_offset_t kmem_alloc_wait(vm_map_t, vm_size_t);
diff --git a/freebsd/usr.bin/netstat/main.c b/freebsd/usr.bin/netstat/main.c
index f3d1003..1caecbe 100644
--- a/freebsd/usr.bin/netstat/main.c
+++ b/freebsd/usr.bin/netstat/main.c
@@ -444,9 +444,23 @@ main(int argc, char *argv[])
 
 	af = AF_UNSPEC;
 
-	while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:Qq:rSTsuWw:xz"))
+	while ((ch = getopt(argc, argv, "46AaBbdf:ghI:iLlM:mN:np:Qq:rSTsuWw:xz"))
 	    != -1)
 		switch(ch) {
+		case '4':
+#ifdef INET
+			af = AF_INET;
+#else
+			errx(1, "IPv4 support is not compiled in");
+#endif
+			break;
+		case '6':
+#ifdef INET6
+			af = AF_INET6;
+#else
+			errx(1, "IPv6 support is not compiled in");
+#endif
+			break;
 		case 'A':
 			Aflag = 1;
 			break;
@@ -891,21 +905,21 @@ static void
 usage(void)
 {
 	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
-"usage: netstat [-AaLnSTWx] [-f protocol_family | -p protocol]\n"
+"usage: netstat [-46AaLnSTWx] [-f protocol_family | -p protocol]\n"
 "               [-M core] [-N system]",
-"       netstat -i | -I interface [-abdhnW] [-f address_family]\n"
+"       netstat -i | -I interface [-46abdhnW] [-f address_family]\n"
 "               [-M core] [-N system]",
-"       netstat -w wait [-I interface] [-d] [-M core] [-N system] [-q howmany]",
-"       netstat -s [-s] [-z] [-f protocol_family | -p protocol]\n"
+"       netstat -w wait [-I interface] [-46d] [-M core] [-N system] [-q howmany]",
+"       netstat -s [-s] [-46z] [-f protocol_family | -p protocol]\n"
 "               [-M core] [-N system]",
-"       netstat -i | -I interface -s [-f protocol_family | -p protocol]\n"
+"       netstat -i | -I interface [-46s] [-f protocol_family | -p protocol]\n"
 "               [-M core] [-N system]",
 "       netstat -m [-M core] [-N system]",
 "       netstat -B [-I interface]",
-"       netstat -r [-AanW] [-f address_family] [-M core] [-N system]",
+"       netstat -r [-46AanW] [-f address_family] [-M core] [-N system]",
 "       netstat -rs [-s] [-M core] [-N system]",
-"       netstat -g [-W] [-f address_family] [-M core] [-N system]",
-"       netstat -gs [-s] [-f address_family] [-M core] [-N system]",
+"       netstat -g [-46W] [-f address_family] [-M core] [-N system]",
+"       netstat -gs [-46s] [-f address_family] [-M core] [-N system]",
 "       netstat -Q");
 	exit(1);
 }
diff --git a/rtemsbsd/include/rtems/bsd/local/miidevs.h b/rtemsbsd/include/rtems/bsd/local/miidevs.h
index 66cb2ac..e7646c8 100644
--- a/rtemsbsd/include/rtems/bsd/local/miidevs.h
+++ b/rtemsbsd/include/rtems/bsd/local/miidevs.h
@@ -59,6 +59,7 @@
 #define	MII_OUI_BROADCOM	0x001018	/* Broadcom Corporation */
 #define	MII_OUI_BROADCOM2	0x000af7	/* Broadcom Corporation */
 #define	MII_OUI_BROADCOM3	0x001be9	/* Broadcom Corporation */
+#define	MII_OUI_BROADCOM4	0x18c086	/* Broadcom Corporation */
 #define	MII_OUI_CICADA	0x0003F1	/* Cicada Semiconductor */
 #define	MII_OUI_DAVICOM	0x00606e	/* Davicom Semiconductor */
 #define	MII_OUI_ENABLESEMI	0x0010dd	/* Enable Semiconductor */
@@ -251,6 +252,8 @@
 #define	MII_STR_BROADCOM3_BCM57765	"BCM57765 1000BASE-T media interface"
 #define	MII_MODEL_BROADCOM3_BCM5720C	0x0036
 #define	MII_STR_BROADCOM3_BCM5720C	"BCM5720C 1000BASE-T media interface"
+#define	MII_MODEL_BROADCOM4_BCM5725C	0x0038
+#define	MII_STR_BROADCOM4_BCM5725C	"BCM5725C 1000BASE-T media interface"
 #define	MII_MODEL_xxBROADCOM_ALT1_BCM5906	0x0004
 #define	MII_STR_xxBROADCOM_ALT1_BCM5906	"BCM5906 10/100baseTX media interface"
 
@@ -449,6 +452,8 @@
 #define	MII_STR_REALTEK_RTL8305SC	"RTL8305SC 10/100 802.1q switch"
 #define	MII_MODEL_REALTEK_RTL8201E	0x0008
 #define	MII_STR_REALTEK_RTL8201E	"RTL8201E 10/100 media interface"
+#define	MII_MODEL_REALTEK_RTL8251	0x0000
+#define	MII_STR_REALTEK_RTL8251	"RTL8251 1000BASE-T media interface"
 #define	MII_MODEL_REALTEK_RTL8169S	0x0011
 #define	MII_STR_REALTEK_RTL8169S	"RTL8169S/8110S/8211 1000BASE-T media interface"
 
diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs.h b/rtemsbsd/include/rtems/bsd/local/usbdevs.h
index 0a3d105..3543d85 100644
--- a/rtemsbsd/include/rtems/bsd/local/usbdevs.h
+++ b/rtemsbsd/include/rtems/bsd/local/usbdevs.h
@@ -522,11 +522,13 @@
 #define	USB_VENDOR_AMBIT	0x0bb2		/* Ambit Microsystems */
 #define	USB_VENDOR_HTC	0x0bb4		/* HTC */
 #define	USB_VENDOR_REALTEK	0x0bda		/* Realtek */
+#define	USB_VENDOR_ERICSSON2	0x0bdb		/* Ericsson */
 #define	USB_VENDOR_MEI	0x0bed		/* MEI */
 #define	USB_VENDOR_ADDONICS2	0x0bf6		/* Addonics Technology */
 #define	USB_VENDOR_FSC	0x0bf8		/* Fujitsu Siemens Computers */
 #define	USB_VENDOR_AGATE	0x0c08		/* Agate Technologies */
 #define	USB_VENDOR_DMI	0x0c0b		/* DMI */
+#define	USB_VENDOR_CANYON	0x0c10		/* Canyon */
 #define	USB_VENDOR_ICOM	0x0c26		/* Icom Inc. */
 #define	USB_VENDOR_GNOTOMETRICS	0x0c33		/* GN Otometrics */
 #define	USB_VENDOR_CHICONY2	0x0c45		/* Chicony */
@@ -574,10 +576,12 @@
 #define	USB_VENDOR_RIM	0x0fca		/* Research In Motion */
 #define	USB_VENDOR_DYNASTREAM	0x0fcf		/* Dynastream Innovations */
 #define	USB_VENDOR_LARSENBRUSGAARD	0x0fd8		/* Larsen and Brusgaard */
+#define	USB_VENDOR_OWL	0x0fde		/* OWL */
 #define	USB_VENDOR_KONTRON	0x0fe6		/* Kontron AG */
 #define	USB_VENDOR_QUALCOMM	0x1004		/* Qualcomm */
 #define	USB_VENDOR_APACER	0x1005		/* Apacer */
 #define	USB_VENDOR_MOTOROLA4	0x100d		/* Motorola */
+#define	USB_VENDOR_HP3	0x103c		/* Hewlett Packard */
 #define	USB_VENDOR_AIRPLUS	0x1011		/* Airplus */
 #define	USB_VENDOR_DESKNOTE	0x1019		/* Desknote */
 #define	USB_VENDOR_NEC3	0x1033		/* NEC */
@@ -589,6 +593,7 @@
 #define	USB_VENDOR_CURITEL	0x106c		/* Curitel Communications Inc */
 #define	USB_VENDOR_SILABS2	0x10a6		/* SILABS2 */
 #define	USB_VENDOR_USI	0x10ab		/* USI */
+#define	USB_VENDOR_LIEBERT2	0x10af		/* Liebert */
 #define	USB_VENDOR_PLX	0x10b5		/* PLX */
 #define	USB_VENDOR_ASANTE	0x10bd		/* Asante */
 #define	USB_VENDOR_SILABS	0x10c4		/* Silicon Labs */
@@ -645,6 +650,7 @@
 #define	USB_VENDOR_SILICOM	0x1485		/* Silicom */
 #define	USB_VENDOR_RALINK	0x148f		/* Ralink Technology */
 #define	USB_VENDOR_IMAGINATION	0x149a		/* Imagination Technologies */
+#define	USB_VENDOR_ATP	0x14af		/* ATP Electronics */
 #define	USB_VENDOR_CONCEPTRONIC2	0x14b2		/* Conceptronic */
 #define	USB_VENDOR_SUPERTOP	0x14cd		/* Super Top */
 #define	USB_VENDOR_PLANEX3	0x14ea		/* Planex Communications */
@@ -657,6 +663,8 @@
 #define	USB_VENDOR_OQO	0x1557		/* OQO */
 #define	USB_VENDOR_UMEDIA	0x157e		/* U-MEDIA Communications */
 #define	USB_VENDOR_FIBERLINE	0x1582		/* Fiberline */
+#define	USB_VENDOR_FREESCALE	0x15a2		/* Freescale Semiconductor, Inc. */
+#define	USB_VENDOR_AFATECH	0x15a4		/* Afatech Technologies, Inc. */
 #define	USB_VENDOR_SPARKLAN	0x15a9		/* SparkLAN */
 #define	USB_VENDOR_OLIMEX	0x15ba		/* Olimex */
 #define	USB_VENDOR_SOUNDGRAPH	0x15c2		/* Soundgraph, Inc. */
@@ -697,6 +705,7 @@
 #define	USB_VENDOR_BAYER	0x1a79		/* Bayer */
 #define	USB_VENDOR_WCH2	0x1a86		/* QinHeng Electronics */
 #define	USB_VENDOR_STELERA	0x1a8d		/* Stelera Wireless */
+#define	USB_VENDOR_SEL	0x1adb		/* Schweitzer Engineering Laboratories */
 #define	USB_VENDOR_CORSAIR	0x1b1c		/* Corsair */
 #define	USB_VENDOR_MATRIXORBITAL	0x1b3d		/* Matrix Orbital */
 #define	USB_VENDOR_OVISLINK	0x1b75		/* OvisLink */
@@ -717,6 +726,7 @@
 #define	USB_VENDOR_ALINK	0x1e0e		/* Alink */
 #define	USB_VENDOR_AIRTIES	0x1eda		/* AirTies */
 #define	USB_VENDOR_FESTO	0x1e29		/* Festo */
+#define	USB_VENDOR_LAKESHORE	0x1fb9		/* Lake Shore Cryotronics, Inc. */
 #define	USB_VENDOR_VERTEX	0x1fe7		/* Vertex Wireless Co., Ltd. */
 #define	USB_VENDOR_DLINK	0x2001		/* D-Link */
 #define	USB_VENDOR_PLANEX2	0x2019		/* Planex Communications */
@@ -726,10 +736,13 @@
 #define	USB_VENDOR_QIHARDWARE	0x20b7		/* QI-hardware */
 #define	USB_VENDOR_PARA	0x20b8		/* PARA Industrial */
 #define	USB_VENDOR_SIMTEC	0x20df		/* Simtec Electronics */
+#define	USB_VENDOR_TRENDNET	0x20f4		/* TRENDnet */
 #define	USB_VENDOR_RTSYSTEMS	0x2100		/* RTSYSTEMS */
 #define	USB_VENDOR_VIALABS	0x2109		/* VIA Labs */
 #define	USB_VENDOR_ERICSSON	0x2282		/* Ericsson */
 #define	USB_VENDOR_MOTOROLA2	0x22b8		/* Motorola */
+#define	USB_VENDOR_WETELECOM	0x22de		/* WeTelecom */
+#define	USB_VENDOR_WESTMOUNTAIN	0x2405		/* West Mountain Radio */
 #define	USB_VENDOR_TRIPPLITE	0x2478		/* Tripp-Lite */
 #define	USB_VENDOR_HIROSE	0x2631		/* Hirose Electric */
 #define	USB_VENDOR_NHJ	0x2770		/* NHJ */
@@ -747,6 +760,7 @@
 #define	USB_VENDOR_DELL	0x413c		/* Dell */
 #define	USB_VENDOR_WCH	0x4348		/* QinHeng Electronics */
 #define	USB_VENDOR_ACEECA	0x4766		/* Aceeca */
+#define	USB_VENDOR_FEIXUN	0x4855		/* FeiXun Communication */
 #define	USB_VENDOR_PAPOUCH	0x5050		/* Papouch products */
 #define	USB_VENDOR_AVERATEC	0x50c2		/* Averatec */
 #define	USB_VENDOR_SWEEX	0x5173		/* Sweex */
@@ -762,6 +776,7 @@
 #define	USB_VENDOR_ALLWIN	0x8516		/* ALLWIN Tech */
 #define	USB_VENDOR_SITECOM2	0x9016		/* Sitecom */
 #define	USB_VENDOR_MOSCHIP	0x9710		/* MosChip Semiconductor */
+#define	USB_VENDOR_NETGEAR4	0x9846		/* Netgear */
 #define	USB_VENDOR_MARVELL	0x9e88		/* Marvell Technology Group Ltd. */
 #define	USB_VENDOR_3COM3	0xa727		/* 3Com */
 #define	USB_VENDOR_EVOLUTION	0xdeee		/* Evolution Robotics products */
@@ -819,6 +834,9 @@
 #define	USB_PRODUCT_ABOCOM_RT2573_2	0xb21c		/* RT2573 */
 #define	USB_PRODUCT_ABOCOM_RT2573_3	0xb21d		/* RT2573 */
 #define	USB_PRODUCT_ABOCOM_RT2573_4	0xb21e		/* RT2573 */
+#define	USB_PRODUCT_ABOCOM_RTL8188CU_1	0x8188		/* RTL8188CU */
+#define	USB_PRODUCT_ABOCOM_RTL8188CU_2	0x8189		/* RTL8188CU */
+#define	USB_PRODUCT_ABOCOM_RTL8192CU	0x8178		/* RTL8192CU */
 #define	USB_PRODUCT_ABOCOM_WUG2700	0xb21f		/* WUG2700 */
 
 /* Acton Research Corp. */
@@ -846,6 +864,7 @@
 #define	USB_PRODUCT_ACCTON_RT2870_1	0xb522		/* RT2870 */
 #define	USB_PRODUCT_ACCTON_RT3070_3	0xc522		/* RT3070 */
 #define	USB_PRODUCT_ACCTON_RT3070_5	0xd522		/* RT3070 */
+#define	USB_PRODUCT_ACCTON_RTL8192SU	0xc512		/* RTL8192SU */
 #define	USB_PRODUCT_ACCTON_ZD1211B	0xe501		/* ZD1211B */
 
 /* Aceeca products */
@@ -923,6 +942,9 @@
 /* AEI products */
 #define	USB_PRODUCT_AEI_FASTETHERNET	0x1701		/* Fast Ethernet */
 
+/* Afatech Technologies, Inc. */
+#define	USB_PRODUCT_AFATECH_AFATECH1336	0x1336		/* Flash Card Reader */
+
 /* Agate Technologies products */
 #define	USB_PRODUCT_AGATE_QDRIVE	0x0378		/* Q-Drive */
 
@@ -1062,12 +1084,54 @@
 #define	USB_PRODUCT_APPLE_IMAC_KBD	0x0201		/* USB iMac Keyboard */
 #define	USB_PRODUCT_APPLE_KBD	0x0202		/* USB Keyboard M2452 */
 #define	USB_PRODUCT_APPLE_EXT_KBD	0x020c		/* Apple Extended USB Keyboard */
-#define	USB_PRODUCT_APPLE_KBD_TP_ANSI	0x0223		/* Apple Internal Keyboard/Trackpad (Wellspring/ANSI) */
-#define	USB_PRODUCT_APPLE_KBD_TP_ISO	0x0224		/* Apple Internal Keyboard/Trackpad (Wellspring/ISO) */
-#define	USB_PRODUCT_APPLE_KBD_TP_JIS	0x0225		/* Apple Internal Keyboard/Trackpad (Wellspring/JIS) */
-#define	USB_PRODUCT_APPLE_KBD_TP_ANSI2	0x0230		/* Apple Internal Keyboard/Trackpad (Wellspring2/ANSI) */
-#define	USB_PRODUCT_APPLE_KBD_TP_ISO2	0x0231		/* Apple Internal Keyboard/Trackpad (Wellspring2/ISO) */
-#define	USB_PRODUCT_APPLE_KBD_TP_JIS2	0x0232		/* Apple Internal Keyboard/Trackpad (Wellspring2/JIS) */
+/* MacbookAir, aka wellspring */
+#define	USB_PRODUCT_APPLE_WELLSPRING_ANSI	0x0223		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING_ISO	0x0224		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING_JIS	0x0225		/* Apple Internal Keyboard/Trackpad */
+/* MacbookProPenryn, aka wellspring2 */
+#define	USB_PRODUCT_APPLE_WELLSPRING2_ANSI	0x0230		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING2_ISO	0x0231		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING2_JIS	0x0232		/* Apple Internal Keyboard/Trackpad */
+/* Macbook5,1 (unibody), aka wellspring3 */
+#define	USB_PRODUCT_APPLE_WELLSPRING3_ANSI	0x0236		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING3_ISO	0x0237		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING3_JIS	0x0238		/* Apple Internal Keyboard/Trackpad */
+/* MacbookAir3,2 (unibody), aka wellspring4 */
+#define	USB_PRODUCT_APPLE_WELLSPRING4_ANSI	0x023f		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING4_ISO	0x0240		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING4_JIS	0x0241		/* Apple Internal Keyboard/Trackpad */
+/* MacbookAir3,1 (unibody), aka wellspring4 */
+#define	USB_PRODUCT_APPLE_WELLSPRING4A_ANSI	0x0242		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING4A_ISO	0x0243		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING4A_JIS	0x0244		/* Apple Internal Keyboard/Trackpad */
+/* Macbook8 (unibody, March 2011) */
+#define	USB_PRODUCT_APPLE_WELLSPRING5_ANSI	0x0245		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING5_ISO	0x0246		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING5_JIS	0x0247		/* Apple Internal Keyboard/Trackpad */
+/* MacbookAir4,1 (unibody, July 2011) */
+#define	USB_PRODUCT_APPLE_WELLSPRING6A_ANSI	0x0249		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING6A_ISO	0x024a		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING6A_JIS	0x024b		/* Apple Internal Keyboard/Trackpad */
+/* MacbookAir4,2 (unibody, July 2011) */
+#define	USB_PRODUCT_APPLE_WELLSPRING6_ANSI	0x024c		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING6_ISO	0x024d		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING6_JIS	0x024e		/* Apple Internal Keyboard/Trackpad */
+/* Macbook8,2 (unibody) */
+#define	USB_PRODUCT_APPLE_WELLSPRING5A_ANSI	0x0252		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING5A_ISO	0x0253		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING5A_JIS	0x0254		/* Apple Internal Keyboard/Trackpad */
+/* MacbookPro10,1 (unibody, June 2012) */
+#define	USB_PRODUCT_APPLE_WELLSPRING7_ANSI	0x0262		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING7_ISO	0x0263		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING7_JIS	0x0264		/* Apple Internal Keyboard/Trackpad */
+/* MacbookPro10,2 (unibody, October 2012) */
+#define	USB_PRODUCT_APPLE_WELLSPRING7A_ANSI	0x0259		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING7A_ISO	0x025a		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING7A_JIS	0x025b		/* Apple Internal Keyboard/Trackpad */
+/* MacbookAir6,2 (unibody, June 2013) */
+#define	USB_PRODUCT_APPLE_WELLSPRING8_ANSI	0x0290		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING8_ISO	0x0291		/* Apple Internal Keyboard/Trackpad */
+#define	USB_PRODUCT_APPLE_WELLSPRING8_JIS	0x0292		/* Apple Internal Keyboard/Trackpad */
 #define	USB_PRODUCT_APPLE_MOUSE	0x0301		/* Mouse M4848 */
 #define	USB_PRODUCT_APPLE_OPTMOUSE	0x0302		/* Optical mouse */
 #define	USB_PRODUCT_APPLE_MIGHTYMOUSE	0x0304		/* Mighty Mouse */
@@ -1107,6 +1171,8 @@
 /* ASIX Electronics products */
 #define	USB_PRODUCT_ASIX_AX88172	0x1720		/* 10/100 Ethernet */
 #define	USB_PRODUCT_ASIX_AX88178	0x1780		/* AX88178 */
+#define	USB_PRODUCT_ASIX_AX88178A	0x178a		/* AX88178A USB 2.0 10/100/1000 Ethernet */
+#define	USB_PRODUCT_ASIX_AX88179	0x1790		/* AX88179 USB 3.0 10/100/1000 Ethernet */
 #define	USB_PRODUCT_ASIX_AX88772	0x7720		/* AX88772 */
 #define	USB_PRODUCT_ASIX_AX88772A	0x772a		/* AX88772A USB 2.0 10/100 Ethernet */
 #define	USB_PRODUCT_ASIX_AX88772B	0x772b		/* AX88772B USB 2.0 10/100 Ethernet */
@@ -1128,6 +1194,10 @@
 #define	USB_PRODUCT_ASUS_RT2870_5	0x1761		/* RT2870 */
 #define	USB_PRODUCT_ASUS_USBN13	0x1784		/* USB-N13 */
 #define	USB_PRODUCT_ASUS_RT3070_1	0x1790		/* RT3070 */
+#define	USB_PRODUCT_ASUS_USBN10	0x1786		/* USB-N10 */
+#define	USB_PRODUCT_ASUS_RTL8192CU	0x17ab		/* RTL8192CU */
+#define	USB_PRODUCT_ASUS_USBN66	0x17ad		/* USB-N66 */
+#define	USB_PRODUCT_ASUS_RTL8192SU	0x1791		/* RTL8192SU */
 #define	USB_PRODUCT_ASUS_A730W	0x4202		/* ASUS MyPal A730W */
 #define	USB_PRODUCT_ASUS_P535	0x420f		/* ASUS P535 PDA */
 #define	USB_PRODUCT_ASUS_GMSC	0x422f		/* ASUS Generic Mass Storage */
@@ -1142,6 +1212,9 @@
 #define	USB_PRODUCT_ATEN_UC210T	0x2009		/* UC-210T Ethernet */
 #define	USB_PRODUCT_ATEN_DSB650C	0x4000		/* DSB-650C */
 
+/* ATP Electronics products */
+#define	USB_PRODUCT_ATP_EUSB	0xaf01		/* ATP IG eUSB SSD */
+
 /* Atheros Communications products */
 #define	USB_PRODUCT_ATHEROS_AR5523	0x0001		/* AR5523 */
 #define	USB_PRODUCT_ATHEROS_AR5523_NF	0x0002		/* AR5523 (no firmware) */
@@ -1175,6 +1248,14 @@
 #define	USB_PRODUCT_AZUREWAVE_RT3070_1	0x3273		/* RT3070 */
 #define	USB_PRODUCT_AZUREWAVE_RT3070_2	0x3284		/* RT3070 */
 #define	USB_PRODUCT_AZUREWAVE_RT3070_3	0x3305		/* RT3070 */
+#define	USB_PRODUCT_AZUREWAVE_RTL8188CU	0x3357		/* RTL8188CU */
+#define	USB_PRODUCT_AZUREWAVE_RTL8188CE_1	0x3358		/* RTL8188CE */
+#define	USB_PRODUCT_AZUREWAVE_RTL8188CE_2	0x3359		/* RTL8188CE */
+#define	USB_PRODUCT_AZUREWAVE_RTL8192SU_1	0x3306		/* RTL8192SU */
+#define	USB_PRODUCT_AZUREWAVE_RTL8192SU_2	0x3309		/* RTL8192SU */
+#define	USB_PRODUCT_AZUREWAVE_RTL8192SU_3	0x3310		/* RTL8192SU */
+#define	USB_PRODUCT_AZUREWAVE_RTL8192SU_4	0x3311		/* RTL8192SU */
+#define	USB_PRODUCT_AZUREWAVE_RTL8192SU_5	0x3325		/* RTL8192SU */
 
 /* Baltech products */
 #define	USB_PRODUCT_BALTECH_CARDREADER	0x9999		/* Card reader */
@@ -1217,6 +1298,10 @@
 #define	USB_PRODUCT_BELKIN_F5U409	0x0409		/* F5U409 Serial */
 #define	USB_PRODUCT_BELKIN_F6C550AVR	0x0551		/* F6C550-AVR UPS */
 #define	USB_PRODUCT_BELKIN_F5U120	0x1203		/* F5U120-PC Hub */
+#define	USB_PRODUCT_BELKIN_RTL8188CU	0x1102		/* RTL8188CU Wireless Adapter */
+#define	USB_PRODUCT_BELKIN_F9L1103	0x1103		/* F9L1103 Wireless Adapter */
+#define	USB_PRODUCT_BELKIN_RTL8192CU	0x2102		/* RTL8192CU Wireless Adapter */
+#define	USB_PRODUCT_BELKIN_F7D2102	0x2103		/* F7D2102 Wireless Adapter */
 #define	USB_PRODUCT_BELKIN_ZD1211B	0x4050		/* ZD1211B */
 #define	USB_PRODUCT_BELKIN_F5D5055	0x5055		/* F5D5055 */
 #define	USB_PRODUCT_BELKIN_F5D7050	0x7050		/* F5D7050 Wireless Adapter */
@@ -1228,11 +1313,15 @@
 #define	USB_PRODUCT_BELKIN_RT2870_1	0x8053		/* RT2870 */
 #define	USB_PRODUCT_BELKIN_RT2870_2	0x805c		/* RT2870 */
 #define	USB_PRODUCT_BELKIN_F5D8053V3	0x815c		/* F5D8053 v3 */
+#define	USB_PRODUCT_BELKIN_RTL8192SU_1	0x815f		/* RTL8192SU */
+#define	USB_PRODUCT_BELKIN_RTL8192SU_2	0x845a		/* RTL8192SU */
+#define	USB_PRODUCT_BELKIN_RTL8192SU_3	0x945a		/* RTL8192SU */
 #define	USB_PRODUCT_BELKIN_F5D8055	0x825a		/* F5D8055 */
 #define	USB_PRODUCT_BELKIN_F5D8055V2	0x825b		/* F5D8055 v2 */
 #define	USB_PRODUCT_BELKIN_F5D9050V3	0x905b		/* F5D9050 ver 3 Wireless Adapter */
 #define	USB_PRODUCT_BELKIN2_F5U002	0x0002		/* F5U002 Parallel printer */
 #define	USB_PRODUCT_BELKIN_F6D4050V1	0x935a		/* F6D4050 v1 */
+#define	USB_PRODUCT_BELKIN_F6D4050V2	0x935b		/* F6D4050 v2 */
 
 /* Billionton products */
 #define	USB_PRODUCT_BILLIONTON_USB100	0x0986		/* USB100N 10/100 FastEthernet */
@@ -1296,6 +1385,11 @@
 #define	USB_PRODUCT_CHICONY_KB8933	0x0001		/* KB-8933 keyboard */
 #define	USB_PRODUCT_CHICONY_KU0325	0x0116		/* KU-0325 keyboard */
 #define	USB_PRODUCT_CHICONY_CNF7129	0xb071		/* Notebook Web Camera */
+#define	USB_PRODUCT_CHICONY_RTL8188CUS_1	0xaff7		/* RTL8188CUS */
+#define	USB_PRODUCT_CHICONY_RTL8188CUS_2	0xaff8		/* RTL8188CUS */
+#define	USB_PRODUCT_CHICONY_RTL8188CUS_3	0xaff9		/* RTL8188CUS */
+#define	USB_PRODUCT_CHICONY_RTL8188CUS_4	0xaffa		/* RTL8188CUS */
+#define	USB_PRODUCT_CHICONY_RTL8188CUS_5	0xaffa		/* RTL8188CUS */
 #define	USB_PRODUCT_CHICONY2_TWINKLECAM	0x600d		/* TwinkleCam USB camera */
 
 /* CH Products */
@@ -1349,6 +1443,9 @@
 #define	USB_PRODUCT_CONCEPTRONIC_AR5523_1_NF	0x7802		/* AR5523 (no firmware) */
 #define	USB_PRODUCT_CONCEPTRONIC_AR5523_2	0x7811		/* AR5523 */
 #define	USB_PRODUCT_CONCEPTRONIC_AR5523_2_NF	0x7812		/* AR5523 (no firmware) */
+#define	USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_1	0x3300		/* RTL8192SU */
+#define	USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_2	0x3301		/* RTL8192SU */
+#define	USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_3	0x3302		/* RTL8192SU */
 #define	USB_PRODUCT_CONCEPTRONIC2_C54RU	0x3c02		/* C54RU WLAN */
 #define	USB_PRODUCT_CONCEPTRONIC2_C54RU2	0x3c22		/* C54RU */
 #define	USB_PRODUCT_CONCEPTRONIC2_RT3070_1	0x3c08		/* RT3070 */
@@ -1385,6 +1482,8 @@
 #define	USB_PRODUCT_COREGA_RT2870_3	0x003f		/* RT2870 */
 #define	USB_PRODUCT_COREGA_RT3070	0x0041		/* RT3070 */
 #define	USB_PRODUCT_COREGA_CGWLUSB300GNM	0x0042		/* CG-WLUSB300GNM */
+#define	USB_PRODUCT_COREGA_RTL8192SU	0x0047		/* RTL8192SU */
+#define	USB_PRODUCT_COREGA_RTL8192CU	0x0056		/* RTL8192CU */
 
 #define	USB_PRODUCT_COREGA_WLUSB_11_STICK	0x7613		/* WLAN USB Stick 11 */
 #define	USB_PRODUCT_COREGA_FETHER_USB_TXC	0x9601		/* FEther USB-TXC */
@@ -1495,6 +1594,7 @@
 /* D-Link products */
 /*product DLINK DSBS25		0x0100	DSB-S25 serial*/
 #define	USB_PRODUCT_DLINK_DUBE100	0x1a00		/* 10/100 Ethernet */
+#define	USB_PRODUCT_DLINK_DUBE100C1	0x1a02		/* DUB-E100 rev C1 */
 #define	USB_PRODUCT_DLINK_DSB650TX4	0x200c		/* 10/100 Ethernet */
 #define	USB_PRODUCT_DLINK_DWL120E	0x3200		/* DWL-120 rev E */
 #define	USB_PRODUCT_DLINK_DWL122	0x3700		/* DWL-122 */
@@ -1510,16 +1610,30 @@
 #define	USB_PRODUCT_DLINK_DUBE100B1	0x3c05		/* DUB-E100 rev B1 */
 #define	USB_PRODUCT_DLINK_RT2870	0x3c09		/* RT2870 */
 #define	USB_PRODUCT_DLINK_RT3072	0x3c0a		/* RT3072 */
+#define	USB_PRODUCT_DLINK_DWA140B3	0x3c15		/* DWA-140 rev B3 */
+#define	USB_PRODUCT_DLINK_DWA160B2	0x3c1a		/* DWA-160 rev B2 */
+#define	USB_PRODUCT_DLINK_DWA127	0x3c1b		/* DWA-127 Wireless Adapter */
+#define	USB_PRODUCT_DLINK_DWA162	0x3c1f		/* DWA-162 Wireless Adapter */
+#define	USB_PRODUCT_DLINK_DWA140D1	0x3c20		/* DWA-140 rev D1 */
 #define	USB_PRODUCT_DLINK_DSB650C	0x4000		/* 10Mbps Ethernet */
 #define	USB_PRODUCT_DLINK_DSB650TX1	0x4001		/* 10/100 Ethernet */
 #define	USB_PRODUCT_DLINK_DSB650TX	0x4002		/* 10/100 Ethernet */
 #define	USB_PRODUCT_DLINK_DSB650TX_PNA	0x4003		/* 1/10/100 Ethernet */
 #define	USB_PRODUCT_DLINK_DSB650TX3	0x400b		/* 10/100 Ethernet */
 #define	USB_PRODUCT_DLINK_DSB650TX2	0x4102		/* 10/100 Ethernet */
+#define	USB_PRODUCT_DLINK_DUB1312	0x4a00		/* 10/100/1000 Ethernet */
 #define	USB_PRODUCT_DLINK_DSB650	0xabc1		/* 10/100 Ethernet */
 #define	USB_PRODUCT_DLINK_DUBH7	0xf103		/* DUB-H7 USB 2.0 7-Port Hub */
 #define	USB_PRODUCT_DLINK_DWR510_CD	0xa805		/* DWR-510 CD-ROM Mode */
 #define	USB_PRODUCT_DLINK_DWR510	0x7e12		/* DWR-510 */
+#define	USB_PRODUCT_DLINK_RTL8188CU	0x3308		/* RTL8188CU */
+#define	USB_PRODUCT_DLINK_RTL8192CU_1	0x3307		/* RTL8192CU */
+#define	USB_PRODUCT_DLINK_RTL8192CU_2	0x3309		/* RTL8192CU */
+#define	USB_PRODUCT_DLINK_RTL8192CU_3	0x330a		/* RTL8192CU */
+#define	USB_PRODUCT_DLINK_DWA131B	0x330d		/* DWA-131 rev B */
+#define	USB_PRODUCT_DLINK2_RTL8192SU_1	0x3300		/* RTL8192SU */
+#define	USB_PRODUCT_DLINK2_RTL8192SU_2	0x3302		/* RTL8192SU */
+#define	USB_PRODUCT_DLINK2_DWA131A1	0x3303		/* DWA-131 A1 */
 #define	USB_PRODUCT_DLINK2_DWA120	0x3a0c		/* DWA-120 */
 #define	USB_PRODUCT_DLINK2_DWA120_NF	0x3a0d		/* DWA-120 (no firmware) */
 #define	USB_PRODUCT_DLINK2_DWLG122C1	0x3c03		/* DWL-G122 c1 */
@@ -1548,6 +1662,7 @@
 /* dresden elektronik products */
 #define	USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD	0x0001		/* SensorTerminalBoard */
 #define	USB_PRODUCT_DRESDENELEKTRONIK_WIRELESSHANDHELDTERMINAL	0x0004		/* Wireless Handheld Terminal */
+#define	USB_PRODUCT_DRESDENELEKTRONIK_LEVELSHIFTERSTICKLOWCOST	0x0022		/* Levelshifter Stick Low Cost */
 
 /* Dynastream Innovations */
 #define	USB_PRODUCT_DYNASTREAM_ANTDEVBOARD	0x1003		/* ANT dev board */
@@ -1556,9 +1671,15 @@
 
 /* Edimax products */
 #define	USB_PRODUCT_EDIMAX_EW7318USG	0x7318		/* USB Wireless dongle */
+#define	USB_PRODUCT_EDIMAX_RTL8192SU_1	0x7611		/* RTL8192SU */
+#define	USB_PRODUCT_EDIMAX_RTL8192SU_2	0x7612		/* RTL8192SU */
+#define	USB_PRODUCT_EDIMAX_EW7622UMN	0x7622		/* EW-7622UMn */
 #define	USB_PRODUCT_EDIMAX_RT2870_1	0x7711		/* RT2870 */
 #define	USB_PRODUCT_EDIMAX_EW7717	0x7717		/* EW-7717 */
 #define	USB_PRODUCT_EDIMAX_EW7718	0x7718		/* EW-7718 */
+#define	USB_PRODUCT_EDIMAX_EW7733UND	0x7733		/* EW-7733UnD */
+#define	USB_PRODUCT_EDIMAX_EW7811UN	0x7811		/* EW-7811Un */
+#define	USB_PRODUCT_EDIMAX_RTL8192CU	0x7822		/* RTL8192CU */
 
 /* eGalax Products */
 #define	USB_PRODUCT_EGALAX_TPANEL	0x0001		/* Touch Panel */
@@ -1691,6 +1812,10 @@
 #define	USB_PRODUCT_FEIYA_ELANGO	0x6200		/* MicroSDHC Card Reader */
 #define	USB_PRODUCT_FEIYA_AC110	0x6300		/* AC-110 Card Reader */
 
+/* FeiXun Communication products */
+#define	USB_PRODUCT_FEIXUN_RTL8188CU	0x0090		/* RTL8188CU */
+#define	USB_PRODUCT_FEIXUN_RTL8192CU	0x0091		/* RTL8192CU */
+
 /* Festo */
 #define	USB_PRODUCT_FESTO_CPX_USB	0x0102		/* CPX-USB */
 #define	USB_PRODUCT_FESTO_CMSP	0x0501		/* CMSP */
@@ -1722,6 +1847,7 @@
 #define	USB_PRODUCT_FTDI_SERIAL_232RL	0x6006		/* FT232RL Serial */
 #define	USB_PRODUCT_FTDI_SERIAL_2232C	0x6010		/* FT2232C Dual port Serial */
 #define	USB_PRODUCT_FTDI_232H	0x6014		/* FTDI compatible adapter */
+#define	USB_PRODUCT_FTDI_232EX	0x6015		/* FTDI compatible adapter */
 #define	USB_PRODUCT_FTDI_SERIAL_2232D	0x9e90		/* FT2232D Dual port Serial */
 #define	USB_PRODUCT_FTDI_SERIAL_4232H	0x6011		/* FT4232H Quad port Serial */
 #define	USB_PRODUCT_FTDI_BEAGLEBONE	0xa6d0		/* BeagleBone */
@@ -1879,6 +2005,7 @@
 #define	USB_PRODUCT_FTDI_LENZ_LIUSB	0xd780		/* FTDI compatible adapter */
 #define	USB_PRODUCT_FTDI_LM3S_DEVEL_BOARD	0xbcd8		/* FTDI compatible adapter */
 #define	USB_PRODUCT_FTDI_LM3S_EVAL_BOARD	0xbcd9		/* FTDI compatible adapter */
+#define	USB_PRODUCT_FTDI_LM3S_ICDI_B_BOARD	0xbcda		/* FTDI compatible adapter */
 #define	USB_PRODUCT_FTDI_MASTERDEVEL2	0xf449		/* FTDI compatible adapter */
 #define	USB_PRODUCT_FTDI_MHAM_DB9	0xeeed		/* FTDI compatible adapter */
 #define	USB_PRODUCT_FTDI_MHAM_IC	0xeeec		/* FTDI compatible adapter */
@@ -2042,6 +2169,9 @@
 #define	USB_PRODUCT_GUILLEMOT_HWGUSB254LB	0xe010		/* HWGUSB2-54-LB */
 #define	USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP	0xe020		/* HWGUSB2-54V2-AP */
 #define	USB_PRODUCT_GUILLEMOT_HWNU300	0xe030		/* HWNU-300 */
+#define	USB_PRODUCT_GUILLEMOT_HWNUM300	0xe031		/* HWNUm-300 */
+#define	USB_PRODUCT_GUILLEMOT_HWGUN54	0xe032		/* HWGUn-54 */
+#define	USB_PRODUCT_GUILLEMOT_HWNUP150	0xe033		/* HWNUP-150 */
 
 /* Hagiwara products */
 #define	USB_PRODUCT_HAGIWARA_FGSM	0x0002		/* FlashGate SmartMedia Card Reader */
@@ -2065,7 +2195,10 @@
 #define	USB_PRODUCT_HAWKING_RT2870_2	0x0003		/* RT2870 */
 #define	USB_PRODUCT_HAWKING_HWUN2	0x0009		/* HWUN2 */
 #define	USB_PRODUCT_HAWKING_RT3070	0x000b		/* RT3070 */
+#define	USB_PRODUCT_HAWKING_RTL8192CU	0x0019		/* RTL8192CU */
 #define	USB_PRODUCT_HAWKING_UF100	0x400c		/* 10/100 USB Ethernet */
+#define	USB_PRODUCT_HAWKING_RTL8192SU_1	0x0015		/* RTL8192SU */
+#define	USB_PRODUCT_HAWKING_RTL8192SU_2	0x0016		/* RTL8192SU */
 
 /* HID Global GmbH products */
 #define	USB_PRODUCT_HIDGLOBAL_CM2020	0x0596		/* Omnikey Cardman 2020 */
@@ -2114,6 +2247,7 @@
 #define	USB_PRODUCT_HP_2215	0x1016		/* iPAQ 22xx/Jornada 548 */
 #define	USB_PRODUCT_HP_568J	0x1116		/* Jornada 568 */
 #define	USB_PRODUCT_HP_930C	0x1204		/* DeskJet 930c */
+#define	USB_PRODUCT_HP3_RTL8188CU	0x1629		/* RTL8188CU */
 #define	USB_PRODUCT_HP_P2000U	0x1801		/* Inkjet P-2000U */
 #define	USB_PRODUCT_HP_HS2300	0x1e1d		/* HS2300 HSDPA (aka MC8775) */
 #define	USB_PRODUCT_HP_640C	0x2004		/* DeskJet 640c */
@@ -2379,6 +2513,7 @@
 /* Kingston products */
 #define	USB_PRODUCT_KINGSTON_XX1	0x0008		/* Ethernet */
 #define	USB_PRODUCT_KINGSTON_KNU101TX	0x000a		/* KNU101TX USB Ethernet */
+#define	USB_PRODUCT_KINGSTON_HYPERX3_0	0x162b		/* DT HyperX 3.0 */
 
 /* Kawasaki products */
 #define	USB_PRODUCT_KLSI_DUH3E10BT	0x0008		/* USB Ethernet */
@@ -2422,6 +2557,27 @@
 #define	USB_PRODUCT_LACIE_HD	0xa601		/* Hard Disk */
 #define	USB_PRODUCT_LACIE_CDRW	0xa602		/* CD R/W */
 
+/* Lake Shore Cryotronics products */
+#define	USB_PRODUCT_LAKESHORE_121	0x0100		/* 121 Current Source */
+#define	USB_PRODUCT_LAKESHORE_218A	0x0200		/* 218A Temperature Monitor */
+#define	USB_PRODUCT_LAKESHORE_219	0x0201		/* 219 Temperature Monitor */
+#define	USB_PRODUCT_LAKESHORE_233	0x0202		/* 233 Temperature Transmitter */
+#define	USB_PRODUCT_LAKESHORE_235	0x0203		/* 235 Temperature Transmitter */
+#define	USB_PRODUCT_LAKESHORE_335	0x0300		/* 335 Temperature Controller */
+#define	USB_PRODUCT_LAKESHORE_336	0x0301		/* 336 Temperature Controller */
+#define	USB_PRODUCT_LAKESHORE_350	0x0302		/* 350 Temperature Controller */
+#define	USB_PRODUCT_LAKESHORE_371	0x0303		/* 371 AC Bridge */
+#define	USB_PRODUCT_LAKESHORE_411	0x0400		/* 411 Handheld Gaussmeter */
+#define	USB_PRODUCT_LAKESHORE_425	0x0401		/* 425 Gaussmeter */
+#define	USB_PRODUCT_LAKESHORE_455A	0x0402		/* 455A DSP Gaussmeter */
+#define	USB_PRODUCT_LAKESHORE_475A	0x0403		/* 475A DSP Gaussmeter */
+#define	USB_PRODUCT_LAKESHORE_465	0x0404		/* 465 Gaussmeter */
+#define	USB_PRODUCT_LAKESHORE_625A	0x0600		/* 625A Magnet PSU */
+#define	USB_PRODUCT_LAKESHORE_642A	0x0601		/* 642A Magnet PSU */
+#define	USB_PRODUCT_LAKESHORE_648	0x0602		/* 648 Magnet PSU */
+#define	USB_PRODUCT_LAKESHORE_737	0x0700		/* 737 VSM Controller */
+#define	USB_PRODUCT_LAKESHORE_776	0x0701		/* 776 Matrix Switch */
+
 /* Larsen and Brusgaard products */
 #define	USB_PRODUCT_LARSENBRUSGAARD_ALTITRACK	0x0001		/* FTDI compatible adapter */
 
@@ -2440,6 +2596,7 @@
 
 /* Liebert products */
 #define	USB_PRODUCT_LIEBERT_POWERSURE_PXT	0xffff		/* PowerSure Personal XT */
+#define	USB_PRODUCT_LIEBERT2_PSI1000	0x0004		/* UPS PSI 1000 FW:08 */
 
 /* Link Instruments Inc. products */
 #define	USB_PRODUCT_LINKINSTRUMENTS_MSO19	0xf190		/* Link Instruments MSO-19 */
@@ -2475,6 +2632,7 @@
 #define	USB_PRODUCT_LOGITECH_PAGESCAN	0x040f		/* PageScan */
 #define	USB_PRODUCT_LOGITECH_QUICKCAMWEB	0x0801		/* QuickCam Web */
 #define	USB_PRODUCT_LOGITECH_QUICKCAMPRO	0x0810		/* QuickCam Pro */
+#define	USB_PRODUCT_LOGITECH_WEBCAMC100	0X0817		/* Webcam C100 */
 #define	USB_PRODUCT_LOGITECH_QUICKCAMEXP	0x0840		/* QuickCam Express */
 #define	USB_PRODUCT_LOGITECH_QUICKCAM	0x0850		/* QuickCam */
 #define	USB_PRODUCT_LOGITECH_QUICKCAMPRO3	0x0990		/* QuickCam Pro 9000 */
@@ -3011,18 +3169,23 @@
 /* NetChip Technology Products */
 #define	USB_PRODUCT_NETCHIP_TURBOCONNECT	0x1080		/* Turbo-Connect */
 #define	USB_PRODUCT_NETCHIP_CLIK_40	0xa140		/* USB Clik! 40 */
+#define	USB_PRODUCT_NETCHIP_GADGETZERO	0xa4a0		/* Linux Gadget Zero */
 #define	USB_PRODUCT_NETCHIP_ETHERNETGADGET	0xa4a2		/* Linux Ethernet/RNDIS gadget on pxa210/25x/26x */
+#define	USB_PRODUCT_NETCHIP_POCKETBOOK	0xa4a5		/* PocketBook */
 
 /* Netgear products */
 #define	USB_PRODUCT_NETGEAR_EA101	0x1001		/* Ethernet */
 #define	USB_PRODUCT_NETGEAR_EA101X	0x1002		/* Ethernet */
 #define	USB_PRODUCT_NETGEAR_FA101	0x1020		/* Ethernet 10/100, USB1.1 */
 #define	USB_PRODUCT_NETGEAR_FA120	0x1040		/* USB 2.0 Ethernet */
+#define	USB_PRODUCT_NETGEAR_M4100	0x1100		/* M4100/M5300/M7100 series switch */
 #define	USB_PRODUCT_NETGEAR_WG111V2_2	0x4240		/* PrismGT USB 2.0 WLAN */
 #define	USB_PRODUCT_NETGEAR_WG111V3	0x4260		/* WG111v3 */
 #define	USB_PRODUCT_NETGEAR_WG111U	0x4300		/* WG111U */
 #define	USB_PRODUCT_NETGEAR_WG111U_NF	0x4301		/* WG111U (no firmware) */
 #define	USB_PRODUCT_NETGEAR_WG111V2	0x6a00		/* WG111V2 */
+#define	USB_PRODUCT_NETGEAR_RTL8192CU	0x9021		/* RTL8192CU */
+#define	USB_PRODUCT_NETGEAR_WNA1000M	0x9041		/* WNA1000M */
 #define	USB_PRODUCT_NETGEAR2_MA101	0x4100		/* MA101 */
 #define	USB_PRODUCT_NETGEAR2_MA101B	0x4102		/* MA101 Rev B */
 #define	USB_PRODUCT_NETGEAR3_WG111T	0x4250		/* WG111T */
@@ -3030,6 +3193,7 @@
 #define	USB_PRODUCT_NETGEAR3_WPN111	0x5f00		/* WPN111 */
 #define	USB_PRODUCT_NETGEAR3_WPN111_NF	0x5f01		/* WPN111 (no firmware) */
 #define	USB_PRODUCT_NETGEAR3_WPN111_2	0x5f02		/* WPN111 */
+#define	USB_PRODUCT_NETGEAR4_RTL8188CU	0x9041		/* RTL8188CU */
 
 /* NetIndex products */
 #define	USB_PRODUCT_NETINDEX_WS002IN	0x2001		/* Willcom WS002IN */
@@ -3045,6 +3209,7 @@
 /* NovaTech Products */
 #define	USB_PRODUCT_NOVATECH_NV902	0x9020		/* NovaTech NV-902W */
 #define	USB_PRODUCT_NOVATECH_RT2573	0x9021		/* RT2573 */
+#define	USB_PRODUCT_NOVATECH_RTL8188CU	0x9071		/* RTL8188CU */
 
 /* Nokia products */
 #define	USB_PRODUCT_NOKIA_N958GB	0x0070		/* Nokia N95 8GBc */
@@ -3072,6 +3237,7 @@
 #define	USB_PRODUCT_NOVATEL_U727	0x4100		/* Merlin U727 CDMA */
 #define	USB_PRODUCT_NOVATEL_MC950D	0x4400		/* Novatel MC950D HSUPA */
 #define	USB_PRODUCT_NOVATEL_ZEROCD	0x5010		/* Novatel ZeroCD */
+#define	USB_PRODUCT_NOVATEL_MIFI2200V	0x5020		/* Novatel MiFi 2200 CDMA Virgin Mobile */
 #define	USB_PRODUCT_NOVATEL_ZEROCD2	0x5030		/* Novatel ZeroCD */
 #define	USB_PRODUCT_NOVATEL_MIFI2200	0x5041		/* Novatel MiFi 2200 CDMA */
 #define	USB_PRODUCT_NOVATEL_U727_2	0x5100		/* Merlin U727 CDMA */
@@ -3150,6 +3316,7 @@
 #define	USB_PRODUCT_OPTION_GE40X_1	0x7301		/* Globetrotter HSUPA */
 #define	USB_PRODUCT_OPTION_GE40X_2	0x7361		/* Globetrotter HSUPA */
 #define	USB_PRODUCT_OPTION_GE40X_3	0x7381		/* Globetrotter HSUPA */
+#define	USB_PRODUCT_OPTION_GTM661W	0x9000		/* GTM661W */
 #define	USB_PRODUCT_OPTION_ICONEDGE	0xc031		/* GlobeSurfer iCON EDGE */
 #define	USB_PRODUCT_OPTION_MODHSXPA	0xd013		/* Globetrotter HSUPA */
 #define	USB_PRODUCT_OPTION_ICON321	0xd031		/* Globetrotter HSUPA */
@@ -3178,6 +3345,9 @@
 /* Owen.ru products */
 #define	USB_PRODUCT_OWEN_AC4	0x0004		/* AC4 USB-RS485 converter */
 
+/* OWL producs */
+#define	USB_PRODUCT_OWL_CM_160	0xca05		/* OWL CM-160 power monitor */
+
 /* Palm Computing, Inc. product */
 #define	USB_PRODUCT_PALM_SERIAL	0x0080		/* USB Serial */
 #define	USB_PRODUCT_PALM_M500	0x0001		/* Palm m500 */
@@ -3273,8 +3443,14 @@
 
 /* Planex Communications products */
 #define	USB_PRODUCT_PLANEX_GW_US11H	0x14ea		/* GW-US11H WLAN */
+#define	USB_PRODUCT_PLANEX2_RTL8188CUS	0x1201		/* RTL8188CUS */
 #define	USB_PRODUCT_PLANEX2_GW_US11S	0x3220		/* GW-US11S WLAN */
 #define	USB_PRODUCT_PLANEX2_GW_US54GXS	0x5303		/* GW-US54GXS WLAN */
+#define	USB_PRODUCT_PLANEX2_RTL8188CU_1	0xab2a		/* RTL8188CU */
+#define	USB_PRODUCT_PLANEX2_RTL8188CU_2	0xed17		/* RTL8188CU */
+#define	USB_PRODUCT_PLANEX2_RTL8188CU_3	0x4902		/* RTL8188CU */
+#define	USB_PRODUCT_PLANEX2_RTL8188CU_4	0xab2e		/* RTL8188CU */
+#define	USB_PRODUCT_PLANEX2_RTL8192CU	0xab2b		/* RTL8192CU */
 #define	USB_PRODUCT_PLANEX2_GWUS54HP	0xab01		/* GW-US54HP */
 #define	USB_PRODUCT_PLANEX2_GWUS300MINIS	0xab24		/* GW-US300MiniS */
 #define	USB_PRODUCT_PLANEX2_RT3070	0xab25		/* RT3070 */
@@ -3290,6 +3466,7 @@
 #define	USB_PRODUCT_PLANEX3_GWUS54GZ	0xab10		/* GW-US54GZ */
 #define	USB_PRODUCT_PLANEX3_GU1000T	0xab11		/* GU-1000T */
 #define	USB_PRODUCT_PLANEX3_GWUS54MINI	0xab13		/* GW-US54Mini */
+#define	USB_PRODUCT_PLANEX2_GWUSNANO	0xab28		/* GW-USNano */
 
 /* Plextor Corp. */
 #define	USB_PRODUCT_PLEXTOR_40_12_40U	0x0011		/* PlexWriter 40/12/40U */
@@ -3486,12 +3663,15 @@
 #define	USB_PRODUCT_RALINK_RT2671	0x2671		/* RT2601USB Wireless Adapter */
 #define	USB_PRODUCT_RALINK_RT2770	0x2770		/* RT2770 */
 #define	USB_PRODUCT_RALINK_RT2870	0x2870		/* RT2870 */
+#define	USB_PRODUCT_RALINK_RT_STOR	0x2878		/* USB Storage */
 #define	USB_PRODUCT_RALINK_RT3070	0x3070		/* RT3070 */
 #define	USB_PRODUCT_RALINK_RT3071	0x3071		/* RT3071 */
 #define	USB_PRODUCT_RALINK_RT3072	0x3072		/* RT3072 */
 #define	USB_PRODUCT_RALINK_RT3370	0x3370		/* RT3370 */
 #define	USB_PRODUCT_RALINK_RT3572	0x3572		/* RT3572 */
+#define	USB_PRODUCT_RALINK_RT3573	0x3573		/* RT3573 */
 #define	USB_PRODUCT_RALINK_RT5370	0x5370		/* RT5370 */
+#define	USB_PRODUCT_RALINK_RT5572	0x5572		/* RT5572 */
 #define	USB_PRODUCT_RALINK_RT8070	0x8070		/* RT8070 */
 #define	USB_PRODUCT_RALINK_RT2570_3	0x9020		/* RT2500USB Wireless Adapter */
 #define	USB_PRODUCT_RALINK_RT2573_2	0x9021		/* RT2501USB Wireless Adapter */
@@ -3500,15 +3680,37 @@
 #define	USB_PRODUCT_RATOC_REXUSB60	0xb000		/* USB serial adapter REX-USB60 */
 #define	USB_PRODUCT_RATOC_REXUSB60F	0xb020		/* USB serial adapter REX-USB60F */
 
-/* ReakTek products */
+/* Realtek products */
 /* Green House and CompUSA OEM this part */
 #define	USB_PRODUCT_REALTEK_DUMMY	0x0000		/* Dummy product */
 #define	USB_PRODUCT_REALTEK_USB20CRW	0x0158		/* USB20CRW Card Reader */
+#define	USB_PRODUCT_REALTEK_RTL8188CTV	0x018a		/* RTL8188CTV */
 #define	USB_PRODUCT_REALTEK_USBKR100	0x8150		/* USBKR100 USB Ethernet */
+#define	USB_PRODUCT_REALTEK_RTL8188CE_0	0x8170		/* RTL8188CE */
+#define	USB_PRODUCT_REALTEK_RTL8171	0x8171		/* RTL8171 */
+#define	USB_PRODUCT_REALTEK_RTL8172	0x8172		/* RTL8172 */
+#define	USB_PRODUCT_REALTEK_RTL8173	0x8173		/* RTL8173 */
+#define	USB_PRODUCT_REALTEK_RTL8174	0x8174		/* RTL8174 */
+#define	USB_PRODUCT_REALTEK_RTL8188CU_0	0x8176		/* RTL8188CU */
+#define	USB_PRODUCT_REALTEK_RTL8188EU	0x8179		/* RTL8188EU */
+#define	USB_PRODUCT_REALTEK_RTL8188CE_1	0x817e		/* RTL8188CE */
+#define	USB_PRODUCT_REALTEK_RTL8188CU_1	0x817a		/* RTL8188CU */
+#define	USB_PRODUCT_REALTEK_RTL8188CU_2	0x817b		/* RTL8188CU */
 #define	USB_PRODUCT_REALTEK_RTL8187	0x8187		/* RTL8187 Wireless Adapter */
 #define	USB_PRODUCT_REALTEK_RTL8187B_0	0x8189		/* RTL8187B Wireless Adapter */
+#define	USB_PRODUCT_REALTEK_RTL8196EU	0x8196		/* RTL8196EU */
 #define	USB_PRODUCT_REALTEK_RTL8187B_1	0x8197		/* RTL8187B Wireless Adapter */
 #define	USB_PRODUCT_REALTEK_RTL8187B_2	0x8198		/* RTL8187B Wireless Adapter */
+#define	USB_PRODUCT_REALTEK_RTL8188CUS	0x818a		/* RTL8188CUS */
+#define	USB_PRODUCT_REALTEK_RTL8188CU_COMBO	0x8754		/* RTL8188CU */
+#define	USB_PRODUCT_REALTEK_RTL8191CU	0x8177		/* RTL8191CU */
+#define	USB_PRODUCT_REALTEK_RTL8192CU	0x8178		/* RTL8192CU */
+#define	USB_PRODUCT_REALTEK_RTL8192CE	0x817c		/* RTL8192CE */
+#define	USB_PRODUCT_REALTEK_RTL8188RU_1	0x817d		/* RTL8188RU */
+#define	USB_PRODUCT_REALTEK_RTL8712	0x8712		/* RTL8712 */
+#define	USB_PRODUCT_REALTEK_RTL8713	0x8712		/* RTL8713 */
+#define	USB_PRODUCT_REALTEK_RTL8188RU_2	0x317f		/* RTL8188RU */
+#define	USB_PRODUCT_REALTEK_RTL8192SU	0xc512		/* RTL8192SU */
 
 /* RedOctane products */
 #define	USB_PRODUCT_REDOCTANE_DUMMY	0x0000		/* Dummy product */
@@ -3582,6 +3784,7 @@
 #define	USB_PRODUCT_SANDISK_SDDR12	0x0100		/* ImageMate SDDR-12 */
 #define	USB_PRODUCT_SANDISK_SDDR09	0x0200		/* ImageMate SDDR-09 */
 #define	USB_PRODUCT_SANDISK_SDDR75	0x0810		/* ImageMate SDDR-75 */
+#define	USB_PRODUCT_SANDISK_SDCZ2_128	0x7100		/* Cruzer Mini 128MB */
 #define	USB_PRODUCT_SANDISK_SDCZ2_256	0x7104		/* Cruzer Mini 256MB */
 #define	USB_PRODUCT_SANDISK_SDCZ4_128	0x7112		/* Cruzer Micro 128MB */
 #define	USB_PRODUCT_SANDISK_SDCZ4_256	0x7113		/* Cruzer Micro 256MB */
@@ -3597,6 +3800,9 @@
 #define	USB_PRODUCT_SCANLOGIC_SL11R	0x0002		/* SL11R IDE Adapter */
 #define	USB_PRODUCT_SCANLOGIC_336CX	0x0300		/* Phantom 336CX - C3 scanner */
 
+/* Schweitzer Engineering Laboratories products */
+#define	USB_PRODUCT_SEL_C662	0x0001		/* C662 Cable */
+
 /* Sealevel products */
 #define	USB_PRODUCT_SEALEVEL_2101	0x2101		/* FTDI compatible adapter */
 #define	USB_PRODUCT_SEALEVEL_2102	0x2102		/* FTDI compatible adapter */
@@ -3659,6 +3865,8 @@
 #define	USB_PRODUCT_SENAO_RT3072_3	0x9708		/* RT3072 */
 #define	USB_PRODUCT_SENAO_RT3072_4	0x9709		/* RT3072 */
 #define	USB_PRODUCT_SENAO_RT3072_5	0x9801		/* RT3072 */
+#define	USB_PRODUCT_SENAO_RTL8192SU_1	0x9603		/* RTL8192SU */
+#define	USB_PRODUCT_SENAO_RTL8192SU_2	0x9605		/* RTL8192SU */
 
 /* ShanTou products */
 #define	USB_PRODUCT_SHANTOU_ST268	0x0268		/* ST268 */
@@ -3835,8 +4043,11 @@
 #define	USB_PRODUCT_SILABS_BALLUFF_RFID	0x8477		/* Balluff RFID reader */
 #define	USB_PRODUCT_SILABS_AC_SERV_IBUS	0x85ea		/* AC-Services IBUS Interface */
 #define	USB_PRODUCT_SILABS_AC_SERV_CIS	0x85eb		/* AC-Services CIS-IBUS */
+#define	USB_PRODUCT_SILABS_V_PREON32	0x85f8		/* Virtenio Preon32 */
 #define	USB_PRODUCT_SILABS_AC_SERV_CAN	0x8664		/* AC-Services CAN Interface */
 #define	USB_PRODUCT_SILABS_AC_SERV_OBD	0x8665		/* AC-Services OBD Interface */
+#define	USB_PRODUCT_SILABS_MMB_ZIGBEE	0x88a4		/* MMB Networks ZigBee */
+#define	USB_PRODUCT_SILABS_INGENI_ZIGBEE	0x88a5		/* Planet Innovation Ingeni ZigBee */
 #define	USB_PRODUCT_SILABS_CP2102	0xea60		/* SILABS USB UART */
 #define	USB_PRODUCT_SILABS_CP210X_2	0xea61		/* CP210x Serial */
 #define	USB_PRODUCT_SILABS_CP210X_3	0xea70		/* CP210x Serial */
@@ -3879,10 +4090,16 @@
 #define	USB_PRODUCT_SITECOMEU_RT3071	0x0040		/* RT3071 */
 #define	USB_PRODUCT_SITECOMEU_RT3072_1	0x0041		/* RT3072 */
 #define	USB_PRODUCT_SITECOMEU_RT3072_2	0x0042		/* RT3072 */
+#define	USB_PRODUCT_SITECOMEU_WL353	0x0045		/* WL-353 */
 #define	USB_PRODUCT_SITECOMEU_RT3072_3	0x0047		/* RT3072 */
 #define	USB_PRODUCT_SITECOMEU_RT3072_4	0x0048		/* RT3072 */
 #define	USB_PRODUCT_SITECOMEU_RT3072_5	0x004a		/* RT3072 */
+#define	USB_PRODUCT_SITECOMEU_WL349V1	0x004b		/* WL-349 v1 */
 #define	USB_PRODUCT_SITECOMEU_RT3072_6	0x004d		/* RT3072 */
+#define	USB_PRODUCT_SITECOMEU_RTL8188CU_1	0x0052		/* RTL8188CU */
+#define	USB_PRODUCT_SITECOMEU_RTL8188CU_2	0x005c		/* RTL8188CU */
+#define	USB_PRODUCT_SITECOMEU_RTL8192CU	0x0061		/* RTL8192CU */
+#define	USB_PRODUCT_SITECOMEU_LN032	0x0072		/* LN-032 */
 #define	USB_PRODUCT_SITECOMEU_LN028	0x061c		/* LN-028 */
 #define	USB_PRODUCT_SITECOMEU_WL113	0x9071		/* WL-113 */
 #define	USB_PRODUCT_SITECOMEU_ZD1211B	0x9075		/* ZD1211B */
@@ -3908,6 +4125,7 @@
 #define	USB_PRODUCT_SMC2_2020HUB	0x2020		/* USB Hub */
 #define	USB_PRODUCT_SMC2_2514HUB	0x2514		/* USB Hub */
 #define	USB_PRODUCT_SMC3_2662WUSB	0xa002		/* 2662W-AR Wireless */
+#define	USB_PRODUCT_SMC2_LAN9514_ETH	0xec00		/* USB/Ethernet */
 
 /* SOHOware products */
 #define	USB_PRODUCT_SOHOWARE_NUB100	0x9100		/* 10/100 USB Ethernet */
@@ -4008,6 +4226,7 @@
 
 /* Super Top products */
 #define	USB_PRODUCT_SUPERTOP_IDE	0x6600		/* USB-IDE */
+#define	USB_PRODUCT_SUPERTOP_FLASHDRIVE	0x121c		/* extrememory Snippy */
 
 /* Syntech products */
 #define	USB_PRODUCT_SYNTECH_CPT8001C	0x0001		/* CPT-8001C Barcode scanner */
@@ -4044,6 +4263,7 @@
 /* Sweex products */
 #define	USB_PRODUCT_SWEEX_ZD1211	0x1809		/* ZD1211 */
 #define	USB_PRODUCT_SWEEX2_LW153	0x0153		/* LW153 */
+#define	USB_PRODUCT_SWEEX2_LW154	0x0154		/* LW154 */
 #define	USB_PRODUCT_SWEEX2_LW303	0x0302		/* LW303 */
 #define	USB_PRODUCT_SWEEX2_LW313	0x0313		/* LW313 */
 
@@ -4110,6 +4330,10 @@
 #define	USB_PRODUCT_TREK_MEMKEY	0x8888		/* IBM USB Memory Key */
 #define	USB_PRODUCT_TREK_THUMBDRIVE_8MB	0x9988		/* ThumbDrive_8MB */
 
+/* TRENDnet products */
+#define	USB_PRODUCT_TRENDNET_RTL8192CU	0x624d		/* RTL8192CU */
+#define	USB_PRODUCT_TRENDNET_RTL8188CU	0x648b		/* RTL8188CU */
+
 /* Tripp-Lite products */
 #define	USB_PRODUCT_TRIPPLITE_U209	0x2008		/* Serial */
 
@@ -4214,12 +4438,19 @@
 #define	USB_PRODUCT_WCH2_CH341SER	0x7523		/* CH341/CH340 USB-Serial Bridge */
 #define	USB_PRODUCT_WCH2_U2M	0X752d		/* CH345 USB2.0-MIDI */
 
+/* West Mountain Radio products */
+#define	USB_PRODUCT_WESTMOUNTAIN_RIGBLASTER_ADVANTAGE	0x0003		/* RIGblaster Advantage */
+
 /* Western Digital products */
 #define	USB_PRODUCT_WESTERN_COMBO	0x0200		/* Firewire USB Combo */
 #define	USB_PRODUCT_WESTERN_EXTHDD	0x0400		/* External HDD */
 #define	USB_PRODUCT_WESTERN_HUB	0x0500		/* USB HUB */
 #define	USB_PRODUCT_WESTERN_MYBOOK	0x0901		/* MyBook External HDD */
 #define	USB_PRODUCT_WESTERN_MYPASSWORD	0x0704		/* MyPassword External HDD */
+#define	USB_PRODUCT_WESTERN_MYPASSPORT	0x0748		/* MyPassport External HDD */
+
+/* WeTelecom products */
+#define	USB_PRODUCT_WETELECOM_WM_D200	0x6801		/* WM-D200 */
 
 /* WIENER Plein & Baus GmbH products */
 #define	USB_PRODUCT_WIENERPLEINBAUS_PL512	0x0010		/* PL512 PSU */
@@ -4315,3 +4546,5 @@
 #define	USB_PRODUCT_ZYXEL_G202	0x3410		/* G-202 */
 #define	USB_PRODUCT_ZYXEL_RT2870_1	0x3416		/* RT2870 */
 #define	USB_PRODUCT_ZYXEL_RT2870_2	0x341a		/* RT2870 */
+#define	USB_PRODUCT_ZYXEL_RTL8192CU	0x341f		/* RTL8192CU */
+#define	USB_PRODUCT_ZYXEL_NWD2705	0x3421		/* NWD2705 */
diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
index 9ac09b5..c31eb4b 100644
--- a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
+++ b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
@@ -286,6 +286,24 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT2573",
 	},
 	{
+	    USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_1,
+	    0,
+	    "AboCom Systems",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_2,
+	    0,
+	    "AboCom Systems",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8192CU,
+	    0,
+	    "AboCom Systems",
+	    "RTL8192CU",
+	},
+	{
 	    USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700,
 	    0,
 	    "AboCom Systems",
@@ -424,6 +442,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT3070",
 	},
 	{
+	    USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RTL8192SU,
+	    0,
+	    "Accton Technology",
+	    "RTL8192SU",
+	},
+	{
 	    USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_ZD1211B,
 	    0,
 	    "Accton Technology",
@@ -670,6 +694,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "Fast Ethernet",
 	},
 	{
+	    USB_VENDOR_AFATECH, USB_PRODUCT_AFATECH_AFATECH1336,
+	    0,
+	    "Afatech Technologies, Inc.",
+	    "Flash Card Reader",
+	},
+	{
 	    USB_VENDOR_AGATE, USB_PRODUCT_AGATE_QDRIVE,
 	    0,
 	    "Agate Technologies",
@@ -1144,40 +1174,220 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "Apple Extended USB Keyboard",
 	},
 	{
-	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_ANSI,
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_ANSI,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_ISO,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_JIS,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_ANSI,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_ISO,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_JIS,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_ANSI,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_ISO,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_JIS,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_ANSI,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_ISO,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_JIS,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_ANSI,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_ISO,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_JIS,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_ANSI,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_ISO,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_JIS,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_ANSI,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_ISO,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_JIS,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_ANSI,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_ISO,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_JIS,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_ANSI,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_ISO,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_JIS,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_ANSI,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_ISO,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_JIS,
+	    0,
+	    "Apple Computer",
+	    "Apple Internal Keyboard/Trackpad",
+	},
+	{
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_ANSI,
 	    0,
 	    "Apple Computer",
-	    "Apple Internal Keyboard/Trackpad (Wellspring/ANSI)",
+	    "Apple Internal Keyboard/Trackpad",
 	},
 	{
-	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_ISO,
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_ISO,
 	    0,
 	    "Apple Computer",
-	    "Apple Internal Keyboard/Trackpad (Wellspring/ISO)",
+	    "Apple Internal Keyboard/Trackpad",
 	},
 	{
-	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_JIS,
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_JIS,
 	    0,
 	    "Apple Computer",
-	    "Apple Internal Keyboard/Trackpad (Wellspring/JIS)",
+	    "Apple Internal Keyboard/Trackpad",
 	},
 	{
-	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_ANSI2,
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ANSI,
 	    0,
 	    "Apple Computer",
-	    "Apple Internal Keyboard/Trackpad (Wellspring2/ANSI)",
+	    "Apple Internal Keyboard/Trackpad",
 	},
 	{
-	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_ISO2,
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ISO,
 	    0,
 	    "Apple Computer",
-	    "Apple Internal Keyboard/Trackpad (Wellspring2/ISO)",
+	    "Apple Internal Keyboard/Trackpad",
 	},
 	{
-	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_JIS2,
+	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_JIS,
 	    0,
 	    "Apple Computer",
-	    "Apple Internal Keyboard/Trackpad (Wellspring2/JIS)",
+	    "Apple Internal Keyboard/Trackpad",
 	},
 	{
 	    USB_VENDOR_APPLE, USB_PRODUCT_APPLE_MOUSE,
@@ -1366,6 +1576,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "AX88178",
 	},
 	{
+	    USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178A,
+	    0,
+	    "ASIX Electronics",
+	    "AX88178A USB 2.0 10/100/1000 Ethernet",
+	},
+	{
+	    USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88179,
+	    0,
+	    "ASIX Electronics",
+	    "AX88179 USB 3.0 10/100/1000 Ethernet",
+	},
+	{
 	    USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772,
 	    0,
 	    "ASIX Electronics",
@@ -1480,6 +1702,30 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT3070",
 	},
 	{
+	    USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN10,
+	    0,
+	    "ASUSTeK Computer",
+	    "USB-N10",
+	},
+	{
+	    USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU,
+	    0,
+	    "ASUSTeK Computer",
+	    "RTL8192CU",
+	},
+	{
+	    USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN66,
+	    0,
+	    "ASUSTeK Computer",
+	    "USB-N66",
+	},
+	{
+	    USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192SU,
+	    0,
+	    "ASUSTeK Computer",
+	    "RTL8192SU",
+	},
+	{
 	    USB_VENDOR_ASUS, USB_PRODUCT_ASUS_A730W,
 	    0,
 	    "ASUSTeK Computer",
@@ -1546,6 +1792,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "DSB-650C",
 	},
 	{
+	    USB_VENDOR_ATP, USB_PRODUCT_ATP_EUSB,
+	    0,
+	    "ATP Electronics",
+	    "ATP IG eUSB SSD",
+	},
+	{
 	    USB_VENDOR_ATHEROS, USB_PRODUCT_ATHEROS_AR5523,
 	    0,
 	    "Atheros Communications",
@@ -1678,6 +1930,54 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT3070",
 	},
 	{
+	    USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CU,
+	    0,
+	    "AsureWave",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_1,
+	    0,
+	    "AsureWave",
+	    "RTL8188CE",
+	},
+	{
+	    USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_2,
+	    0,
+	    "AsureWave",
+	    "RTL8188CE",
+	},
+	{
+	    USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_1,
+	    0,
+	    "AsureWave",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_2,
+	    0,
+	    "AsureWave",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_3,
+	    0,
+	    "AsureWave",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_4,
+	    0,
+	    "AsureWave",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_5,
+	    0,
+	    "AsureWave",
+	    "RTL8192SU",
+	},
+	{
 	    USB_VENDOR_BALTECH, USB_PRODUCT_BALTECH_CARDREADER,
 	    0,
 	    "Baltech",
@@ -1876,6 +2176,30 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "F5U120-PC Hub",
 	},
 	{
+	    USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8188CU,
+	    0,
+	    "Belkin Components",
+	    "RTL8188CU Wireless Adapter",
+	},
+	{
+	    USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F9L1103,
+	    0,
+	    "Belkin Components",
+	    "F9L1103 Wireless Adapter",
+	},
+	{
+	    USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192CU,
+	    0,
+	    "Belkin Components",
+	    "RTL8192CU Wireless Adapter",
+	},
+	{
+	    USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F7D2102,
+	    0,
+	    "Belkin Components",
+	    "F7D2102 Wireless Adapter",
+	},
+	{
 	    USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_ZD1211B,
 	    0,
 	    "Belkin Components",
@@ -1936,6 +2260,24 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "F5D8053 v3",
 	},
 	{
+	    USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_1,
+	    0,
+	    "Belkin Components",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_2,
+	    0,
+	    "Belkin Components",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_3,
+	    0,
+	    "Belkin Components",
+	    "RTL8192SU",
+	},
+	{
 	    USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D8055,
 	    0,
 	    "Belkin Components",
@@ -1966,6 +2308,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "F6D4050 v1",
 	},
 	{
+	    USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6D4050V2,
+	    0,
+	    "Belkin Components",
+	    "F6D4050 v2",
+	},
+	{
 	    USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100,
 	    0,
 	    "Billionton Systems",
@@ -2200,6 +2548,36 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "Notebook Web Camera",
 	},
 	{
+	    USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_1,
+	    0,
+	    "Chicony Electronics",
+	    "RTL8188CUS",
+	},
+	{
+	    USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_2,
+	    0,
+	    "Chicony Electronics",
+	    "RTL8188CUS",
+	},
+	{
+	    USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_3,
+	    0,
+	    "Chicony Electronics",
+	    "RTL8188CUS",
+	},
+	{
+	    USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_4,
+	    0,
+	    "Chicony Electronics",
+	    "RTL8188CUS",
+	},
+	{
+	    USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_5,
+	    0,
+	    "Chicony Electronics",
+	    "RTL8188CUS",
+	},
+	{
 	    USB_VENDOR_CHICONY2, USB_PRODUCT_CHICONY2_TWINKLECAM,
 	    0,
 	    "Chicony",
@@ -2434,6 +2812,24 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "AR5523 (no firmware)",
 	},
 	{
+	    USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_1,
+	    0,
+	    "Conceptronic",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_2,
+	    0,
+	    "Conceptronic",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_3,
+	    0,
+	    "Conceptronic",
+	    "RTL8192SU",
+	},
+	{
 	    USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU,
 	    0,
 	    "Conceptronic",
@@ -2614,6 +3010,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "CG-WLUSB300GNM",
 	},
 	{
+	    USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RTL8192SU,
+	    0,
+	    "Corega",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RTL8192CU,
+	    0,
+	    "Corega",
+	    "RTL8192CU",
+	},
+	{
 	    USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_STICK,
 	    0,
 	    "Corega",
@@ -3016,6 +3424,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "10/100 Ethernet",
 	},
 	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100C1,
+	    0,
+	    "D-Link",
+	    "DUB-E100 rev C1",
+	},
+	{
 	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4,
 	    0,
 	    "D-Link",
@@ -3070,40 +3484,70 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "DWL-G132 (no firmware)",
 	},
 	{
-	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122,
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122,
+	    0,
+	    "D-Link",
+	    "DWL-AG122",
+	},
+	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122_NF,
+	    0,
+	    "D-Link",
+	    "DWL-AG122 (no firmware)",
+	},
+	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122,
+	    0,
+	    "D-Link",
+	    "DWL-G122 b1 Wireless Adapter",
+	},
+	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1,
+	    0,
+	    "D-Link",
+	    "DUB-E100 rev B1",
+	},
+	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT2870,
+	    0,
+	    "D-Link",
+	    "RT2870",
+	},
+	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT3072,
 	    0,
 	    "D-Link",
-	    "DWL-AG122",
+	    "RT3072",
 	},
 	{
-	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122_NF,
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA140B3,
 	    0,
 	    "D-Link",
-	    "DWL-AG122 (no firmware)",
+	    "DWA-140 rev B3",
 	},
 	{
-	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122,
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA160B2,
 	    0,
 	    "D-Link",
-	    "DWL-G122 b1 Wireless Adapter",
+	    "DWA-160 rev B2",
 	},
 	{
-	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1,
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA127,
 	    0,
 	    "D-Link",
-	    "DUB-E100 rev B1",
+	    "DWA-127 Wireless Adapter",
 	},
 	{
-	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT2870,
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA162,
 	    0,
 	    "D-Link",
-	    "RT2870",
+	    "DWA-162 Wireless Adapter",
 	},
 	{
-	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT3072,
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA140D1,
 	    0,
 	    "D-Link",
-	    "RT3072",
+	    "DWA-140 rev D1",
 	},
 	{
 	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C,
@@ -3142,6 +3586,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "10/100 Ethernet",
 	},
 	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUB1312,
+	    0,
+	    "D-Link",
+	    "10/100/1000 Ethernet",
+	},
+	{
 	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650,
 	    0,
 	    "D-Link",
@@ -3166,6 +3616,54 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "DWR-510",
 	},
 	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8188CU,
+	    0,
+	    "D-Link",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_1,
+	    0,
+	    "D-Link",
+	    "RTL8192CU",
+	},
+	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_2,
+	    0,
+	    "D-Link",
+	    "RTL8192CU",
+	},
+	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_3,
+	    0,
+	    "D-Link",
+	    "RTL8192CU",
+	},
+	{
+	    USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA131B,
+	    0,
+	    "D-Link",
+	    "DWA-131 rev B",
+	},
+	{
+	    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RTL8192SU_1,
+	    0,
+	    "D-Link",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RTL8192SU_2,
+	    0,
+	    "D-Link",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA131A1,
+	    0,
+	    "D-Link",
+	    "DWA-131 A1",
+	},
+	{
 	    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA120,
 	    0,
 	    "D-Link",
@@ -3298,6 +3796,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "Wireless Handheld Terminal",
 	},
 	{
+	    USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_LEVELSHIFTERSTICKLOWCOST,
+	    0,
+	    "dresden elektronik",
+	    "Levelshifter Stick Low Cost",
+	},
+	{
 	    USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD,
 	    0,
 	    "Dynastream Innovations",
@@ -3322,6 +3826,24 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "USB Wireless dongle",
 	},
 	{
+	    USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_1,
+	    0,
+	    "Edimax",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_2,
+	    0,
+	    "Edimax",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7622UMN,
+	    0,
+	    "Edimax",
+	    "EW-7622UMn",
+	},
+	{
 	    USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RT2870_1,
 	    0,
 	    "Edimax",
@@ -3340,6 +3862,24 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "EW-7718",
 	},
 	{
+	    USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7733UND,
+	    0,
+	    "Edimax",
+	    "EW-7733UnD",
+	},
+	{
+	    USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7811UN,
+	    0,
+	    "Edimax",
+	    "EW-7811Un",
+	},
+	{
+	    USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192CU,
+	    0,
+	    "Edimax",
+	    "RTL8192CU",
+	},
+	{
 	    USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL,
 	    0,
 	    "eGalax, Inc.",
@@ -3886,6 +4426,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "AC-110 Card Reader",
 	},
 	{
+	    USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8188CU,
+	    0,
+	    "FeiXun Communication",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8192CU,
+	    0,
+	    "FeiXun Communication",
+	    "RTL8192CU",
+	},
+	{
 	    USB_VENDOR_FESTO, USB_PRODUCT_FESTO_CPX_USB,
 	    0,
 	    "Festo",
@@ -3982,6 +4534,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "FTDI compatible adapter",
 	},
 	{
+	    USB_VENDOR_FTDI, USB_PRODUCT_FTDI_232EX,
+	    0,
+	    "Future Technology Devices",
+	    "FTDI compatible adapter",
+	},
+	{
 	    USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232D,
 	    0,
 	    "Future Technology Devices",
@@ -4906,6 +5464,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "FTDI compatible adapter",
 	},
 	{
+	    USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LM3S_ICDI_B_BOARD,
+	    0,
+	    "Future Technology Devices",
+	    "FTDI compatible adapter",
+	},
+	{
 	    USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MASTERDEVEL2,
 	    0,
 	    "Future Technology Devices",
@@ -5644,6 +6208,24 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "HWNU-300",
 	},
 	{
+	    USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUM300,
+	    0,
+	    "Guillemot",
+	    "HWNUm-300",
+	},
+	{
+	    USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUN54,
+	    0,
+	    "Guillemot",
+	    "HWGUn-54",
+	},
+	{
+	    USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUP150,
+	    0,
+	    "Guillemot",
+	    "HWNUP-150",
+	},
+	{
 	    USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM,
 	    0,
 	    "Hagiwara Sys-Com",
@@ -5722,12 +6304,30 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT3070",
 	},
 	{
+	    USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192CU,
+	    0,
+	    "Hawking",
+	    "RTL8192CU",
+	},
+	{
 	    USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100,
 	    0,
 	    "Hawking",
 	    "10/100 USB Ethernet",
 	},
 	{
+	    USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192SU_1,
+	    0,
+	    "Hawking",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192SU_2,
+	    0,
+	    "Hawking",
+	    "RTL8192SU",
+	},
+	{
 	    USB_VENDOR_HIDGLOBAL, USB_PRODUCT_HIDGLOBAL_CM2020,
 	    0,
 	    "HID Global",
@@ -5980,6 +6580,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "DeskJet 930c",
 	},
 	{
+	    USB_VENDOR_HP3, USB_PRODUCT_HP3_RTL8188CU,
+	    0,
+	    "Hewlett Packard",
+	    "RTL8188CU",
+	},
+	{
 	    USB_VENDOR_HP, USB_PRODUCT_HP_P2000U,
 	    0,
 	    "Hewlett Packard",
@@ -7186,6 +7792,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "KNU101TX USB Ethernet",
 	},
 	{
+	    USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_HYPERX3_0,
+	    0,
+	    "Kingston Technology",
+	    "DT HyperX 3.0",
+	},
+	{
 	    USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT,
 	    0,
 	    "Kawasaki LSI",
@@ -7342,6 +7954,120 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "CD R/W",
 	},
 	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_121,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "121 Current Source",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_218A,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "218A Temperature Monitor",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_219,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "219 Temperature Monitor",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_233,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "233 Temperature Transmitter",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_235,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "235 Temperature Transmitter",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_335,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "335 Temperature Controller",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_336,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "336 Temperature Controller",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_350,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "350 Temperature Controller",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_371,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "371 AC Bridge",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_411,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "411 Handheld Gaussmeter",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_425,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "425 Gaussmeter",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_455A,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "455A DSP Gaussmeter",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_475A,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "475A DSP Gaussmeter",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_465,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "465 Gaussmeter",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_625A,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "625A Magnet PSU",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_642A,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "642A Magnet PSU",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_648,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "648 Magnet PSU",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_737,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "737 VSM Controller",
+	},
+	{
+	    USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_776,
+	    0,
+	    "Lake Shore Cryotronics, Inc.",
+	    "776 Matrix Switch",
+	},
+	{
 	    USB_VENDOR_LARSENBRUSGAARD, USB_PRODUCT_LARSENBRUSGAARD_ALTITRACK,
 	    0,
 	    "Larsen and Brusgaard",
@@ -7384,6 +8110,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "PowerSure Personal XT",
 	},
 	{
+	    USB_VENDOR_LIEBERT2, USB_PRODUCT_LIEBERT2_PSI1000,
+	    0,
+	    "Liebert",
+	    "UPS PSI 1000 FW:08",
+	},
+	{
 	    USB_VENDOR_LINKINSTRUMENTS, USB_PRODUCT_LINKINSTRUMENTS_MSO19,
 	    0,
 	    "Link Instruments Inc.",
@@ -7546,6 +8278,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "QuickCam Pro",
 	},
 	{
+	    USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC100,
+	    0,
+	    "Logitech",
+	    "Webcam C100",
+	},
+	{
 	    USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMEXP,
 	    0,
 	    "Logitech",
@@ -10240,12 +10978,24 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "USB Clik! 40",
 	},
 	{
+	    USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_GADGETZERO,
+	    0,
+	    "NetChip Technology",
+	    "Linux Gadget Zero",
+	},
+	{
 	    USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET,
 	    0,
 	    "NetChip Technology",
 	    "Linux Ethernet/RNDIS gadget on pxa210/25x/26x",
 	},
 	{
+	    USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_POCKETBOOK,
+	    0,
+	    "NetChip Technology",
+	    "PocketBook",
+	},
+	{
 	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101,
 	    0,
 	    "BayNETGEAR",
@@ -10270,6 +11020,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "USB 2.0 Ethernet",
 	},
 	{
+	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_M4100,
+	    0,
+	    "BayNETGEAR",
+	    "M4100/M5300/M7100 series switch",
+	},
+	{
 	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V2_2,
 	    0,
 	    "BayNETGEAR",
@@ -10300,6 +11056,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "WG111V2",
 	},
 	{
+	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_RTL8192CU,
+	    0,
+	    "BayNETGEAR",
+	    "RTL8192CU",
+	},
+	{
+	    USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000M,
+	    0,
+	    "BayNETGEAR",
+	    "WNA1000M",
+	},
+	{
 	    USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101,
 	    0,
 	    "Netgear",
@@ -10342,6 +11110,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "WPN111",
 	},
 	{
+	    USB_VENDOR_NETGEAR4, USB_PRODUCT_NETGEAR4_RTL8188CU,
+	    0,
+	    "Netgear",
+	    "RTL8188CU",
+	},
+	{
 	    USB_VENDOR_NETINDEX, USB_PRODUCT_NETINDEX_WS002IN,
 	    0,
 	    "NetIndex",
@@ -10384,6 +11158,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT2573",
 	},
 	{
+	    USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RTL8188CU,
+	    0,
+	    "NovaTech",
+	    "RTL8188CU",
+	},
+	{
 	    USB_VENDOR_NOKIA, USB_PRODUCT_NOKIA_N958GB,
 	    0,
 	    "Nokia",
@@ -10522,6 +11302,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "Novatel ZeroCD",
 	},
 	{
+	    USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MIFI2200V,
+	    0,
+	    "Novatel Wireless",
+	    "Novatel MiFi 2200 CDMA Virgin Mobile",
+	},
+	{
 	    USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD2,
 	    0,
 	    "Novatel Wireless",
@@ -10906,6 +11692,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "Globetrotter HSUPA",
 	},
 	{
+	    USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTM661W,
+	    0,
+	    "Option N.V.",
+	    "GTM661W",
+	},
+	{
 	    USB_VENDOR_OPTION, USB_PRODUCT_OPTION_ICONEDGE,
 	    0,
 	    "Option N.V.",
@@ -11008,6 +11800,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "AC4 USB-RS485 converter",
 	},
 	{
+	    USB_VENDOR_OWL, USB_PRODUCT_OWL_CM_160,
+	    0,
+	    "OWL",
+	    "OWL CM-160 power monitor",
+	},
+	{
 	    USB_VENDOR_PALM, USB_PRODUCT_PALM_SERIAL,
 	    0,
 	    "Palm Computing",
@@ -11440,6 +12238,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "GW-US11H WLAN",
 	},
 	{
+	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CUS,
+	    0,
+	    "Planex Communications",
+	    "RTL8188CUS",
+	},
+	{
 	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US11S,
 	    0,
 	    "Planex Communications",
@@ -11449,7 +12253,37 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US54GXS,
 	    0,
 	    "Planex Communications",
-	    "GW-US54GXS WLAN",
+	    "GW-US54GXS WLAN",
+	},
+	{
+	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_1,
+	    0,
+	    "Planex Communications",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_2,
+	    0,
+	    "Planex Communications",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_3,
+	    0,
+	    "Planex Communications",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_4,
+	    0,
+	    "Planex Communications",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8192CU,
+	    0,
+	    "Planex Communications",
+	    "RTL8192CU",
 	},
 	{
 	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP,
@@ -11542,6 +12376,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "GW-US54Mini",
 	},
 	{
+	    USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSNANO,
+	    0,
+	    "Planex Communications",
+	    "GW-USNano",
+	},
+	{
 	    USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U,
 	    0,
 	    "Plextor",
@@ -12490,6 +13330,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT2870",
 	},
 	{
+	    USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT_STOR,
+	    0,
+	    "Ralink Technology",
+	    "USB Storage",
+	},
+	{
 	    USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3070,
 	    0,
 	    "Ralink Technology",
@@ -12520,12 +13366,24 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT3572",
 	},
 	{
+	    USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3573,
+	    0,
+	    "Ralink Technology",
+	    "RT3573",
+	},
+	{
 	    USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT5370,
 	    0,
 	    "Ralink Technology",
 	    "RT5370",
 	},
 	{
+	    USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT5572,
+	    0,
+	    "Ralink Technology",
+	    "RT5572",
+	},
+	{
 	    USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT8070,
 	    0,
 	    "Ralink Technology",
@@ -12568,12 +13426,78 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "USB20CRW Card Reader",
 	},
 	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CTV,
+	    0,
+	    "Realtek",
+	    "RTL8188CTV",
+	},
+	{
 	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_USBKR100,
 	    0,
 	    "Realtek",
 	    "USBKR100 USB Ethernet",
 	},
 	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_0,
+	    0,
+	    "Realtek",
+	    "RTL8188CE",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8171,
+	    0,
+	    "Realtek",
+	    "RTL8171",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8172,
+	    0,
+	    "Realtek",
+	    "RTL8172",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8173,
+	    0,
+	    "Realtek",
+	    "RTL8173",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8174,
+	    0,
+	    "Realtek",
+	    "RTL8174",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_0,
+	    0,
+	    "Realtek",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188EU,
+	    0,
+	    "Realtek",
+	    "RTL8188EU",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_1,
+	    0,
+	    "Realtek",
+	    "RTL8188CE",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_1,
+	    0,
+	    "Realtek",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_2,
+	    0,
+	    "Realtek",
+	    "RTL8188CU",
+	},
+	{
 	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187,
 	    0,
 	    "Realtek",
@@ -12586,6 +13510,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RTL8187B Wireless Adapter",
 	},
 	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8196EU,
+	    0,
+	    "Realtek",
+	    "RTL8196EU",
+	},
+	{
 	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187B_1,
 	    0,
 	    "Realtek",
@@ -12598,6 +13528,66 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RTL8187B Wireless Adapter",
 	},
 	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CUS,
+	    0,
+	    "Realtek",
+	    "RTL8188CUS",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_COMBO,
+	    0,
+	    "Realtek",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8191CU,
+	    0,
+	    "Realtek",
+	    "RTL8191CU",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CU,
+	    0,
+	    "Realtek",
+	    "RTL8192CU",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CE,
+	    0,
+	    "Realtek",
+	    "RTL8192CE",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_1,
+	    0,
+	    "Realtek",
+	    "RTL8188RU",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8712,
+	    0,
+	    "Realtek",
+	    "RTL8712",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8713,
+	    0,
+	    "Realtek",
+	    "RTL8713",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_2,
+	    0,
+	    "Realtek",
+	    "RTL8188RU",
+	},
+	{
+	    USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192SU,
+	    0,
+	    "Realtek",
+	    "RTL8192SU",
+	},
+	{
 	    USB_VENDOR_REDOCTANE, USB_PRODUCT_REDOCTANE_DUMMY,
 	    0,
 	    "RedOctane",
@@ -12892,6 +13882,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "ImageMate SDDR-75",
 	},
 	{
+	    USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_128,
+	    0,
+	    "SanDisk",
+	    "Cruzer Mini 128MB",
+	},
+	{
 	    USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256,
 	    0,
 	    "SanDisk",
@@ -12940,6 +13936,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "Phantom 336CX - C3 scanner",
 	},
 	{
+	    USB_VENDOR_SEL, USB_PRODUCT_SEL_C662,
+	    0,
+	    "Schweitzer Engineering Laboratories",
+	    "C662 Cable",
+	},
+	{
 	    USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2101,
 	    0,
 	    "Sealevel System",
@@ -13294,6 +14296,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT3072",
 	},
 	{
+	    USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RTL8192SU_1,
+	    0,
+	    "Senao",
+	    "RTL8192SU",
+	},
+	{
+	    USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RTL8192SU_2,
+	    0,
+	    "Senao",
+	    "RTL8192SU",
+	},
+	{
 	    USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268,
 	    0,
 	    "ShanTou",
@@ -14224,6 +15238,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "AC-Services CIS-IBUS",
 	},
 	{
+	    USB_VENDOR_SILABS, USB_PRODUCT_SILABS_V_PREON32,
+	    0,
+	    "Silicon Labs",
+	    "Virtenio Preon32",
+	},
+	{
 	    USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AC_SERV_CAN,
 	    0,
 	    "Silicon Labs",
@@ -14236,6 +15256,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "AC-Services OBD Interface",
 	},
 	{
+	    USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MMB_ZIGBEE,
+	    0,
+	    "Silicon Labs",
+	    "MMB Networks ZigBee",
+	},
+	{
+	    USB_VENDOR_SILABS, USB_PRODUCT_SILABS_INGENI_ZIGBEE,
+	    0,
+	    "Silicon Labs",
+	    "Planet Innovation Ingeni ZigBee",
+	},
+	{
 	    USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2102,
 	    0,
 	    "Silicon Labs",
@@ -14440,6 +15472,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT3072",
 	},
 	{
+	    USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL353,
+	    0,
+	    "Sitecom Europe",
+	    "WL-353",
+	},
+	{
 	    USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_3,
 	    0,
 	    "Sitecom Europe",
@@ -14458,12 +15496,42 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT3072",
 	},
 	{
+	    USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL349V1,
+	    0,
+	    "Sitecom Europe",
+	    "WL-349 v1",
+	},
+	{
 	    USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_6,
 	    0,
 	    "Sitecom Europe",
 	    "RT3072",
 	},
 	{
+	    USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU_1,
+	    0,
+	    "Sitecom Europe",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU_2,
+	    0,
+	    "Sitecom Europe",
+	    "RTL8188CU",
+	},
+	{
+	    USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CU,
+	    0,
+	    "Sitecom Europe",
+	    "RTL8192CU",
+	},
+	{
+	    USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN032,
+	    0,
+	    "Sitecom Europe",
+	    "LN-032",
+	},
+	{
 	    USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028,
 	    0,
 	    "Sitecom Europe",
@@ -14566,6 +15634,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "2662W-AR Wireless",
 	},
 	{
+	    USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9514_ETH,
+	    0,
+	    "Standard Microsystems",
+	    "USB/Ethernet",
+	},
+	{
 	    USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100,
 	    0,
 	    "SOHOware",
@@ -14968,6 +16042,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "USB-IDE",
 	},
 	{
+	    USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_FLASHDRIVE,
+	    0,
+	    "Super Top",
+	    "extrememory Snippy",
+	},
+	{
 	    USB_VENDOR_SYNTECH, USB_PRODUCT_SYNTECH_CPT8001C,
 	    0,
 	    "Syntech Information",
@@ -15076,6 +16156,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "LW153",
 	},
 	{
+	    USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW154,
+	    0,
+	    "Sweex",
+	    "LW154",
+	},
+	{
 	    USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW303,
 	    0,
 	    "Sweex",
@@ -15274,6 +16360,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "ThumbDrive_8MB",
 	},
 	{
+	    USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8192CU,
+	    0,
+	    "TRENDnet",
+	    "RTL8192CU",
+	},
+	{
+	    USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8188CU,
+	    0,
+	    "TRENDnet",
+	    "RTL8188CU",
+	},
+	{
 	    USB_VENDOR_TRIPPLITE, USB_PRODUCT_TRIPPLITE_U209,
 	    0,
 	    "Tripp-Lite",
@@ -15610,6 +16708,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "CH345 USB2.0-MIDI",
 	},
 	{
+	    USB_VENDOR_WESTMOUNTAIN, USB_PRODUCT_WESTMOUNTAIN_RIGBLASTER_ADVANTAGE,
+	    0,
+	    "West Mountain Radio",
+	    "RIGblaster Advantage",
+	},
+	{
 	    USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_COMBO,
 	    0,
 	    "Western Digital",
@@ -15640,6 +16744,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "MyPassword External HDD",
 	},
 	{
+	    USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT,
+	    0,
+	    "Western Digital",
+	    "MyPassport External HDD",
+	},
+	{
+	    USB_VENDOR_WETELECOM, USB_PRODUCT_WETELECOM_WM_D200,
+	    0,
+	    "WeTelecom",
+	    "WM-D200",
+	},
+	{
 	    USB_VENDOR_WIENERPLEINBAUS, USB_PRODUCT_WIENERPLEINBAUS_PL512,
 	    0,
 	    "WIENER Plein & Baus GmbH.",
@@ -15994,6 +17110,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    "RT2870",
 	},
 	{
+	    USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RTL8192CU,
+	    0,
+	    "ZyXEL Communication",
+	    "RTL8192CU",
+	},
+	{
+	    USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD2705,
+	    0,
+	    "ZyXEL Communication",
+	    "NWD2705",
+	},
+	{
 	    USB_VENDOR_UNKNOWN1, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Unknown vendor",
@@ -18754,6 +19882,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_ERICSSON2, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "Ericsson",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_MEI, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "MEI",
@@ -18784,6 +19918,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_CANYON, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "Canyon",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_ICOM, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Icom Inc.",
@@ -19066,6 +20206,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_OWL, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "OWL",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_KONTRON, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Kontron AG",
@@ -19090,6 +20236,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_HP3, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "Hewlett Packard",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_AIRPLUS, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Airplus",
@@ -19156,6 +20308,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_LIEBERT2, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "Liebert",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_PLX, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "PLX",
@@ -19492,6 +20650,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_ATP, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "ATP Electronics",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_CONCEPTRONIC2, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Conceptronic",
@@ -19564,6 +20728,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_FREESCALE, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "Freescale Semiconductor, Inc.",
+	    NULL,
+	},
+	{
+	    USB_VENDOR_AFATECH, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "Afatech Technologies, Inc.",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_SPARKLAN, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "SparkLAN",
@@ -19804,6 +20980,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_SEL, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "Schweitzer Engineering Laboratories",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_CORSAIR, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Corsair",
@@ -19924,6 +21106,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_LAKESHORE, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "Lake Shore Cryotronics, Inc.",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_VERTEX, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Vertex Wireless Co., Ltd.",
@@ -19978,6 +21166,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_TRENDNET, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "TRENDnet",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_RTSYSTEMS, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "RTSYSTEMS",
@@ -20002,6 +21196,18 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_WETELECOM, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "WeTelecom",
+	    NULL,
+	},
+	{
+	    USB_VENDOR_WESTMOUNTAIN, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "West Mountain Radio",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_TRIPPLITE, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Tripp-Lite",
@@ -20104,6 +21310,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_FEIXUN, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "FeiXun Communication",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_PAPOUCH, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Papouch products",
@@ -20194,6 +21406,12 @@ const struct usb_knowndev usb_knowndevs[] = {
 	    NULL,
 	},
 	{
+	    USB_VENDOR_NETGEAR4, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "Netgear",
+	    NULL,
+	},
+	{
 	    USB_VENDOR_MARVELL, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "Marvell Technology Group Ltd.",
diff --git a/rtemsbsd/include/rtems/bsd/sys/param.h b/rtemsbsd/include/rtems/bsd/sys/param.h
index 76ba0b7..2945691 100644
--- a/rtemsbsd/include/rtems/bsd/sys/param.h
+++ b/rtemsbsd/include/rtems/bsd/sys/param.h
@@ -61,7 +61,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 802000	/* Master, propagated to newvers */
+#define __FreeBSD_version 903000	/* Master, propagated to newvers */
 
 #ifdef _KERNEL
 #define	P_OSREL_SIGSEGV		700004
diff --git a/rtemsbsd/rtems/rtems-bsd-mutex.c b/rtemsbsd/rtems/rtems-bsd-mutex.c
index 37cc04c..26f6ce2 100644
--- a/rtemsbsd/rtems/rtems-bsd-mutex.c
+++ b/rtemsbsd/rtems/rtems-bsd-mutex.c
@@ -222,4 +222,5 @@ void
 mutex_init(void)
 {
 	mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
+	mtx_lock(&Giant);
 }
diff --git a/rtemsbsd/rtems/rtems-bsd-thread.c b/rtemsbsd/rtems/rtems-bsd-thread.c
index 4fd5184..ef94188 100644
--- a/rtemsbsd/rtems/rtems-bsd-thread.c
+++ b/rtemsbsd/rtems/rtems-bsd-thread.c
@@ -238,7 +238,7 @@ rtems_bsd_threads_init_late(void *arg)
 SYSINIT(rtems_bsd_threads_early, SI_SUB_INTRINSIC, SI_ORDER_ANY,
     rtems_bsd_threads_init_early, NULL);
 
-SYSINIT(rtems_bsd_threads_late, SI_SUB_RUN_SCHEDULER, SI_ORDER_ANY,
+SYSINIT(rtems_bsd_threads_late, SI_SUB_LAST, SI_ORDER_ANY,
     rtems_bsd_threads_init_late, NULL);
 
 static int




More information about the vc mailing list