summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------freebsd-org0
-rw-r--r--freebsd/include/rpc/auth.h49
-rw-r--r--freebsd/include/rpc/auth_des.h53
-rw-r--r--freebsd/include/rpc/auth_unix.h49
-rw-r--r--freebsd/include/rpc/clnt.h69
-rw-r--r--freebsd/include/rpc/clnt_soc.h53
-rw-r--r--freebsd/include/rpc/pmap_clnt.h49
-rw-r--r--freebsd/include/rpc/pmap_prot.h49
-rw-r--r--freebsd/include/rpc/rpc.h49
-rw-r--r--freebsd/include/rpc/rpc_msg.h49
-rw-r--r--freebsd/include/rpc/rpcb_clnt.h53
-rw-r--r--freebsd/include/rpc/rpcb_prot.x49
-rw-r--r--freebsd/include/rpc/rpcent.h53
-rw-r--r--freebsd/include/rpc/svc.h49
-rw-r--r--freebsd/include/rpc/svc_auth.h49
-rw-r--r--freebsd/include/rpc/svc_soc.h53
-rw-r--r--freebsd/include/rpc/xdr.h49
-rw-r--r--freebsd/lib/libc/net/getaddrinfo.c111
-rw-r--r--freebsd/lib/libipsec/ipsec_dump_policy.c1
-rw-r--r--freebsd/sbin/ifconfig/af_inet.c4
-rw-r--r--freebsd/sbin/ifconfig/ifgroup.c4
-rw-r--r--freebsd/sbin/route/keywords2
-rw-r--r--freebsd/sbin/route/route.c24
-rw-r--r--freebsd/sys/cam/ata/ata_all.h2
-rw-r--r--freebsd/sys/cam/cam.h4
-rw-r--r--freebsd/sys/cam/cam_ccb.h17
-rw-r--r--freebsd/sys/cam/cam_debug.h17
-rw-r--r--freebsd/sys/cam/cam_periph.h3
-rw-r--r--freebsd/sys/cam/cam_xpt.h4
-rw-r--r--freebsd/sys/cam/cam_xpt_sim.h4
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.c32
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.h4
-rw-r--r--freebsd/sys/cam/scsi/scsi_da.h32
-rw-r--r--freebsd/sys/contrib/pf/net/pf_lb.c53
-rw-r--r--freebsd/sys/dev/bce/if_bce.c28
-rw-r--r--freebsd/sys/dev/bce/if_bcefw.h8
-rw-r--r--freebsd/sys/dev/bce/if_bcereg.h10
-rw-r--r--freebsd/sys/dev/bge/if_bge.c217
-rw-r--r--freebsd/sys/dev/bge/if_bgereg.h25
-rw-r--r--freebsd/sys/dev/e1000/e1000_defines.h2
-rw-r--r--freebsd/sys/dev/e1000/if_em.c9
-rw-r--r--freebsd/sys/dev/e1000/if_igb.c14
-rw-r--r--freebsd/sys/dev/e1000/if_lem.c10
-rw-r--r--freebsd/sys/dev/fxp/if_fxpreg.h2
-rw-r--r--freebsd/sys/dev/mii/brgphy.c3
-rw-r--r--freebsd/sys/dev/pci/pci.c283
-rw-r--r--freebsd/sys/dev/pci/pci_pci.c508
-rw-r--r--freebsd/sys/dev/pci/pci_private.h2
-rw-r--r--freebsd/sys/dev/pci/pci_user.c128
-rw-r--r--freebsd/sys/dev/pci/pcib_private.h3
-rw-r--r--freebsd/sys/dev/pci/pcireg.h9
-rw-r--r--freebsd/sys/dev/pci/pcivar.h9
-rw-r--r--freebsd/sys/dev/re/if_re.c84
-rw-r--r--freebsd/sys/dev/usb/controller/ehci.c112
-rw-r--r--freebsd/sys/dev/usb/controller/ohci.c5
-rw-r--r--freebsd/sys/dev/usb/controller/usb_controller.c67
-rw-r--r--freebsd/sys/dev/usb/controller/xhcireg.h3
-rw-r--r--freebsd/sys/dev/usb/quirk/usb_quirk.c11
-rw-r--r--freebsd/sys/dev/usb/storage/umass.c4
-rw-r--r--freebsd/sys/dev/usb/usb.h3
-rw-r--r--freebsd/sys/dev/usb/usb_bus.h1
-rw-r--r--freebsd/sys/dev/usb/usb_busdma.c27
-rw-r--r--freebsd/sys/dev/usb/usb_controller.h1
-rw-r--r--freebsd/sys/dev/usb/usb_core.h2
-rw-r--r--freebsd/sys/dev/usb/usb_dev.c254
-rw-r--r--freebsd/sys/dev/usb/usb_device.c116
-rw-r--r--freebsd/sys/dev/usb/usb_device.h17
-rw-r--r--freebsd/sys/dev/usb/usb_freebsd.h3
-rw-r--r--freebsd/sys/dev/usb/usb_generic.c84
-rw-r--r--freebsd/sys/dev/usb/usb_hub.c395
-rw-r--r--freebsd/sys/dev/usb/usb_hub.h7
-rw-r--r--freebsd/sys/dev/usb/usb_ioctl.h64
-rw-r--r--freebsd/sys/dev/usb/usb_msctest.c74
-rw-r--r--freebsd/sys/dev/usb/usb_process.c12
-rw-r--r--freebsd/sys/dev/usb/usb_process.h1
-rw-r--r--freebsd/sys/dev/usb/usb_request.c80
-rw-r--r--freebsd/sys/dev/usb/usb_transfer.c59
-rw-r--r--freebsd/sys/dev/usb/usbdi.h3
-rw-r--r--freebsd/sys/i386/include/machine/specialreg.h6
-rw-r--r--freebsd/sys/kern/init_main.c16
-rw-r--r--freebsd/sys/kern/kern_event.c131
-rw-r--r--freebsd/sys/kern/kern_linker.c197
-rw-r--r--freebsd/sys/kern/kern_mbuf.c137
-rw-r--r--freebsd/sys/kern/kern_mib.c7
-rw-r--r--freebsd/sys/kern/kern_time.c242
-rw-r--r--freebsd/sys/kern/kern_timeout.c16
-rw-r--r--freebsd/sys/kern/subr_lock.c4
-rw-r--r--freebsd/sys/kern/subr_rman.c31
-rw-r--r--freebsd/sys/kern/subr_sbuf.c5
-rw-r--r--freebsd/sys/kern/subr_taskqueue.c36
-rw-r--r--freebsd/sys/kern/sys_generic.c4
-rw-r--r--freebsd/sys/kern/uipc_sockbuf.c78
-rw-r--r--freebsd/sys/kern/uipc_socket.c59
-rw-r--r--freebsd/sys/kern/uipc_syscalls.c61
-rw-r--r--freebsd/sys/kern/uipc_usrreq.c19
-rw-r--r--freebsd/sys/mips/include/machine/cpufunc.h2
-rw-r--r--freebsd/sys/net/ieee8023ad_lacp.c41
-rw-r--r--freebsd/sys/net/if.c4
-rw-r--r--freebsd/sys/net/if_lagg.c19
-rw-r--r--freebsd/sys/net/if_media.h5
-rw-r--r--freebsd/sys/net/if_spppsubr.c2
-rw-r--r--freebsd/sys/net/if_tap.c6
-rw-r--r--freebsd/sys/net/if_tun.c1
-rw-r--r--freebsd/sys/net/if_vlan.c2
-rw-r--r--freebsd/sys/net/radix.c415
-rw-r--r--freebsd/sys/net/radix.h6
-rw-r--r--freebsd/sys/net/radix_mpath.c86
-rw-r--r--freebsd/sys/net/route.c167
-rw-r--r--freebsd/sys/net/route.h9
-rw-r--r--freebsd/sys/net/rtsock.c198
-rw-r--r--freebsd/sys/net80211/ieee80211.h1
-rw-r--r--freebsd/sys/net80211/ieee80211_proto.h3
-rw-r--r--freebsd/sys/netinet/if_ether.c8
-rw-r--r--freebsd/sys/netinet/in.c52
-rw-r--r--freebsd/sys/netinet/in_mcast.c30
-rw-r--r--freebsd/sys/netinet/in_pcb.c2
-rw-r--r--freebsd/sys/netinet/ip_icmp.c1
-rw-r--r--freebsd/sys/netinet/ip_input.c5
-rw-r--r--freebsd/sys/netinet/ip_mroute.c20
-rw-r--r--freebsd/sys/netinet/ip_output.c16
-rw-r--r--freebsd/sys/netinet/sctp.h79
-rw-r--r--freebsd/sys/netinet/sctp_asconf.c92
-rw-r--r--freebsd/sys/netinet/sctp_auth.c137
-rw-r--r--freebsd/sys/netinet/sctp_auth.h15
-rw-r--r--freebsd/sys/netinet/sctp_bsd_addr.c13
-rw-r--r--freebsd/sys/netinet/sctp_constants.h16
-rw-r--r--freebsd/sys/netinet/sctp_dtrace_define.h261
-rw-r--r--freebsd/sys/netinet/sctp_indata.c725
-rw-r--r--freebsd/sys/netinet/sctp_input.c128
-rw-r--r--freebsd/sys/netinet/sctp_os_bsd.h26
-rw-r--r--freebsd/sys/netinet/sctp_output.c302
-rw-r--r--freebsd/sys/netinet/sctp_pcb.c229
-rw-r--r--freebsd/sys/netinet/sctp_pcb.h2
-rw-r--r--freebsd/sys/netinet/sctp_structs.h4
-rw-r--r--freebsd/sys/netinet/sctp_sysctl.c17
-rw-r--r--freebsd/sys/netinet/sctp_sysctl.h8
-rw-r--r--freebsd/sys/netinet/sctp_timer.c48
-rw-r--r--freebsd/sys/netinet/sctp_uio.h4
-rw-r--r--freebsd/sys/netinet/sctp_usrreq.c176
-rw-r--r--freebsd/sys/netinet/sctputil.c138
-rw-r--r--freebsd/sys/netinet/sctputil.h4
-rw-r--r--freebsd/sys/netinet/tcp_input.c6
-rw-r--r--freebsd/sys/netinet/tcp_reass.c7
-rw-r--r--freebsd/sys/netinet/tcp_subr.c6
-rw-r--r--freebsd/sys/netinet6/frag6.c5
-rw-r--r--freebsd/sys/netinet6/icmp6.c1
-rw-r--r--freebsd/sys/netinet6/in6.c1
-rw-r--r--freebsd/sys/netinet6/in6_mcast.c69
-rw-r--r--freebsd/sys/netinet6/in6_pcb.c2
-rw-r--r--freebsd/sys/netinet6/ip6_forward.c7
-rw-r--r--freebsd/sys/netinet6/ip6_input.c16
-rw-r--r--freebsd/sys/netinet6/ip6_mroute.c596
-rw-r--r--freebsd/sys/netinet6/ip6_mroute.h5
-rw-r--r--freebsd/sys/netinet6/nd6.c17
-rw-r--r--freebsd/sys/netinet6/nd6_nbr.c4
-rw-r--r--freebsd/sys/netinet6/sctp6_usrreq.c4
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_dummynet.c2
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw2.c39
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_log.c11
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_nat.c76
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_private.h24
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c14
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_table.c8
-rw-r--r--freebsd/sys/opencrypto/deflate.c8
-rw-r--r--freebsd/sys/pci/if_rlreg.h29
-rw-r--r--freebsd/sys/rpc/types.h51
-rw-r--r--freebsd/sys/sys/_rmlock.h5
-rw-r--r--freebsd/sys/sys/_rwlock.h3
-rw-r--r--freebsd/sys/sys/ata.h7
-rw-r--r--freebsd/sys/sys/bus_dma.h7
-rw-r--r--freebsd/sys/sys/conf.h1
-rw-r--r--freebsd/sys/sys/eventhandler.h18
-rw-r--r--freebsd/sys/sys/eventvar.h2
-rw-r--r--freebsd/sys/sys/kernel.h4
-rw-r--r--freebsd/sys/sys/linker.h4
-rw-r--r--freebsd/sys/sys/lockmgr.h1
-rw-r--r--freebsd/sys/sys/mbuf.h23
-rw-r--r--freebsd/sys/sys/mman.h11
-rw-r--r--freebsd/sys/sys/pciio.h21
-rw-r--r--freebsd/sys/sys/proc.h10
-rw-r--r--freebsd/sys/sys/refcount.h3
-rw-r--r--freebsd/sys/sys/rmlock.h22
-rw-r--r--freebsd/sys/sys/rwlock.h3
-rw-r--r--freebsd/sys/sys/sdt.h420
-rw-r--r--freebsd/sys/sys/sockbuf.h2
-rw-r--r--freebsd/sys/sys/sysctl.h1
-rw-r--r--freebsd/sys/sys/sysproto.h20
-rw-r--r--freebsd/sys/sys/systm.h2
-rw-r--r--freebsd/sys/sys/taskqueue.h1
-rw-r--r--freebsd/sys/sys/tty.h2
-rw-r--r--freebsd/sys/sys/user.h11
-rw-r--r--freebsd/sys/vm/uma_core.c11
-rw-r--r--freebsd/sys/vm/vm.h1
-rw-r--r--freebsd/sys/vm/vm_extern.h4
-rw-r--r--freebsd/usr.bin/netstat/main.c32
-rw-r--r--rtemsbsd/include/rtems/bsd/local/miidevs.h5
-rw-r--r--rtemsbsd/include/rtems/bsd/local/usbdevs.h247
-rw-r--r--rtemsbsd/include/rtems/bsd/local/usbdevs_data.h1242
-rw-r--r--rtemsbsd/include/rtems/bsd/sys/param.h2
-rw-r--r--rtemsbsd/rtems/rtems-bsd-mutex.c1
-rw-r--r--rtemsbsd/rtems/rtems-bsd-thread.c2
201 files changed, 7707 insertions, 3927 deletions
diff --git a/freebsd-org b/freebsd-org
-Subproject 74d8320d56de778817fa39bc074b177c9394548
+Subproject a5feb686027eafe7ae45360846ff5ae4cd64fed
diff --git a/freebsd/include/rpc/auth.h b/freebsd/include/rpc/auth.h
index b19addc8..5503762b 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 fff4ebfe..58b34d77 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 b005bac8..fa47e8ba 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 1c85a4a7..66533e24 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 1e7a0dea..6536a4bb 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 89f1614a..e8314f60 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 366832a7..d880c40d 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 725b542a..e7a3dc8d 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 354b3414..6e8d0745 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 fa64a853..45527872 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 c5748413..a34bcc12 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 876b488b..405ba678 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 8466ef8b..2af5550f 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 41fc82b0..87b8efe7 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 6c528dbc..311c8322 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 ada5c5bd..9456f70c 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 5c1965b6..fbffd6b0 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 33d4bb13..a12727bc 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 0e6ace11..3e9ac8ea 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 daffb3b0..c8dae3b9 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 adfba7cf..676f781d 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 158445d8..05b4f5a3 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 25732b60..91e941c8 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 af57f1a6..499fffa3 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 893c6469..4222de9d 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 37acd7dc..7b619a29 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 102dc3c3..a58ec947 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 492fa3a4..97933b98 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 d32eea71..62ded090 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 5b504010..4cad972d 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 4fe0b1dd..cf84d396 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 57992381..4fbd7256 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 0c2046c2..16faac02 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 dfae5dcc..e186590f 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@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 8d97b31c..fa0d528a 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@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 450180bd..00903562 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@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 f9010aa1..c0f78a78 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 09ced543..acac8b28 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 48c04b01..0815ea8e 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 4c1d3469..2a3fe54a 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 e26a867c..09da15ca 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 5127445c..64a1bcc0 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 cc764b54..7fd60afd 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 de1249c3..75c15774 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 94eeb844..7dcaa0d5 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 bfaabf35..6c159aec 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 b8e446ea..92f36d5c 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 63d64c39..dc22106c 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 79135afa..e9d4c4bf 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 ef351356..f2d1ccbe 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 84e7c871..a951ca66 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 cde6bcee..99751374 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 456aff61..528e4a02 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 42129a8e..05c5e19b 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 37f79364..c0fda652 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 85d989a6..bd1d635c 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 9042c166..2f7ea792 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 76a1fcb6..39d32698 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 9492d491..bb5a60cd 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 459219bd..702f623d 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 80cd8c37..7d98155c 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 ad871913..f23ade21 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 3dfd0d1a..48e5ee83 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 7697b64c..3ff064ee 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 78ae3d8c..e18c32df 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 8e13e3de..361f5c3c 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 06369a25..4cd1758a 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 a0b7f007..e1fc141f 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 2dee6784..9b3bd076 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 23a1fa4f..557a0565 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 9e66bd5a..d5be169b 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 fcb9f026..4d28346c 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 59b26567..d36df36e 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 9b1a8534..06feee8b 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 167a7228..e9137bd2 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 b2528186..205a72f7 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 245777f0..6ec26a4a 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 3ca5e7ae..be36a914 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 88f5f685..f8d04f2c 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 69c47246..89cd1765 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 b1b46d7a..39664a85 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 98cfb1f0..74e7aa10 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@FreeBSD.org>. All rights reserved.
+ * Bosko Milekic <bmilekic@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 a8215b39..c3605582 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 e113aef6..dbb10d01 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 1ca98d9e..821b035d 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 dea7d408..4a55a95a 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 668201a9..c158b36e 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 9ea11990..e61b0844 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 867b0e6b..259b152d 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 6fc16fc5..eb1ed37d 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 2a0e527d..03b18b92 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 9ca2c14c..2dc76a9f 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 738b5c3c..b0c83e60 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 9254e9b2..b7cc060d 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 bfabe90b..7429312c 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 a1c1e49e..20288926 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 ea4a8a46..0bd72e44 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 4dee2afe..b0be3643 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 6424d662..12585095 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 4f2f6d05..fa6a7c1b 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 9c501f16..599905e8 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 25b73294..556a4860 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 f31b9be2..accfbbb6 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 875a482c..ba15eb51 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 5bacaa3a..3554c77c 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 0f89bf5e..1bce388e 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 fdd8a12c..b444b740 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 997f3cd6..0baa9a4c 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 1eebe095..e768e17b 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 9c12ef0c..43d87b3a 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 7e882161..b2ed3e80 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 98ed0b36..e4f76fee 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 0c3f72bc..bc7323e3 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 6d748f1f..4112046c 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 5100ac9b..b93abadf 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 b003d03f..b6876f77 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 2dbb2a7a..2247c1a8 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 6fc5cc68..20daee5a 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 a70d3142..93ebf4d6 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 03cf86a3..d0b90d34 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 71fa307c..551f0690 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 ddb12560..fc649032 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 eac89f6f..535c0fc0 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 4653b251..d558bd82 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 58ca808e..0ede04ca 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 1eb28f65..0bfe18c0 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 e00a470d..07d8fd2b 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 7cdb5b09..baf25af8 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 ca4be706..d33d1fd3 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 61260fb7..f3cb4b44 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 e21c2e03..16dc231f 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 91807c7c..8045765c 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 bc18f0e8..a8b86c62 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 95e3c589..ba7a00bf 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 8090373e..432d36a4 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 be601113..7d010c7b 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 063fd9f1..df9c2d2d 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 81db1dc1..e2bbced4 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 15928d8b..6cd82739 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 411bfafc..af5a0f29 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 50dfc1ce..20d645f0 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 aebda9db..d4f0bcde 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 4c6d14eb..d577f18f 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 8e6b0680..28b2b469 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 32d50e94..20b03a21 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 eac5e11e..f68f21f2 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 55f2fab2..e5457707 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 4d607f71..4b0b3389 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 2b45804f..c45ab10b 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 aba38ecf..0de64eb7 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 00eab8ed..044b96b8 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 d2df0dbe..33b41310 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 b84baf18..9233bef5 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 4574145f..09011b7e 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 f4dfe819..c8bc6620 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 bd7e3c0b..bb9a6736 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 1bd1b6fc..224ba937 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 97132257..60b0df7d 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 142c46c5..5d4dcc9f 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 869d9721..ceabf88d 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 40448a86..95cd8c81 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 58ee16e9..71579795 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 f8a46405..f29dfb42 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 be89c4f5..b0de60f4 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 5634c4dd..754d6279 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 283ea379..46672bb2 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 25eb55e9..95b21283 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 76d8f646..f46dd50c 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 6fbac13b..6e91a012 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 a8dfc300..a0a73522 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 47bc8940..95d03b83 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 26fe34b4..6af0fe82 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 1318243f..c739cd55 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 6948bb22..29db893f 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 4c3a272a..10227cdd 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 12328751..b6d58a25 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 5ed9cdd6..c79ad86d 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 a0c4560e..d70bfbcf 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 58d7d6cc..1db9f8c2 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 572a64e1..b169f542 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 487cb392..e71789ac 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 ec2aed27..2dd1a257 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 f2f9b317..ca820f68 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 bfccd74f..84fd1aa1 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 cf7b90ce..1fca343c 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 5b7b190a..ed58a487 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 44d2208f..18ca646f 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 b4c7d208..68000026 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 70617205..00cf4e6c 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 46401674..659a610c 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 e147c2a7..8a88caaf 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 106c510c..17aea47e 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 8b6c7ac5..3b5be268 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 f3d1003f..1caecbe0 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 66cb2ac8..e7646c8d 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 0a3d105c..3543d85a 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 9ac09b57..c31eb4ba 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 (Wellspring/ANSI)",
+ "Apple Internal Keyboard/Trackpad",
},
{
- USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_ISO,
+ USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_ANSI,
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_WELLSPRING6_ISO,
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_WELLSPRING6_JIS,
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_WELLSPRING5A_ANSI,
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_WELLSPRING5A_ISO,
0,
"Apple Computer",
- "Apple Internal Keyboard/Trackpad (Wellspring2/JIS)",
+ "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",
+ },
+ {
+ USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_ISO,
+ 0,
+ "Apple Computer",
+ "Apple Internal Keyboard/Trackpad",
+ },
+ {
+ USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_JIS,
+ 0,
+ "Apple Computer",
+ "Apple Internal Keyboard/Trackpad",
+ },
+ {
+ USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ANSI,
+ 0,
+ "Apple Computer",
+ "Apple Internal Keyboard/Trackpad",
+ },
+ {
+ USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ISO,
+ 0,
+ "Apple Computer",
+ "Apple Internal Keyboard/Trackpad",
+ },
+ {
+ USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_JIS,
+ 0,
+ "Apple Computer",
+ "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",
@@ -3106,6 +3520,36 @@ const struct usb_knowndev usb_knowndevs[] = {
"RT3072",
},
{
+ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA140B3,
+ 0,
+ "D-Link",
+ "DWA-140 rev B3",
+ },
+ {
+ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA160B2,
+ 0,
+ "D-Link",
+ "DWA-160 rev B2",
+ },
+ {
+ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA127,
+ 0,
+ "D-Link",
+ "DWA-127 Wireless Adapter",
+ },
+ {
+ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA162,
+ 0,
+ "D-Link",
+ "DWA-162 Wireless Adapter",
+ },
+ {
+ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA140D1,
+ 0,
+ "D-Link",
+ "DWA-140 rev D1",
+ },
+ {
USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C,
0,
"D-Link",
@@ -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",
@@ -11452,6 +12256,36 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
0,
"Planex Communications",
@@ -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 76ba0b7b..2945691f 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 37cc04ca..26f6ce28 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 4fd5184c..ef94188f 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