Author: sephe
Date: Tue Nov  1 06:54:25 2016
New Revision: 308163
URL: https://svnweb.freebsd.org/changeset/base/308163

Log:
  hyperv/hn: Rename cleaned up file.
  
  MFC after:    1 week
  Sponsored by: Microsoft
  Differential Revision:        https://reviews.freebsd.org/D8390

Added:
  head/sys/dev/hyperv/netvsc/if_hn.c
     - copied unchanged from r308162, 
head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
Deleted:
  head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
Modified:
  head/sys/conf/files.amd64
  head/sys/conf/files.i386
  head/sys/modules/hyperv/netvsc/Makefile

Modified: head/sys/conf/files.amd64
==============================================================================
--- head/sys/conf/files.amd64   Tue Nov  1 04:44:11 2016        (r308162)
+++ head/sys/conf/files.amd64   Tue Nov  1 06:54:25 2016        (r308163)
@@ -293,7 +293,7 @@ dev/hwpmc/hwpmc_tsc.c               optional        hwpmc
 dev/hwpmc/hwpmc_x86.c          optional        hwpmc
 dev/hyperv/netvsc/hn_nvs.c                             optional        hyperv
 dev/hyperv/netvsc/hn_rndis.c                           optional        hyperv
-dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c              optional        hyperv
+dev/hyperv/netvsc/if_hn.c                              optional        hyperv
 dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c            optional        hyperv
 dev/hyperv/utilities/hv_heartbeat.c                    optional        hyperv
 dev/hyperv/utilities/hv_kvp.c                          optional        hyperv

Modified: head/sys/conf/files.i386
==============================================================================
--- head/sys/conf/files.i386    Tue Nov  1 04:44:11 2016        (r308162)
+++ head/sys/conf/files.i386    Tue Nov  1 06:54:25 2016        (r308163)
@@ -250,7 +250,7 @@ dev/hwpmc/hwpmc_tsc.c               optional hwpmc
 dev/hwpmc/hwpmc_x86.c          optional hwpmc
 dev/hyperv/netvsc/hn_nvs.c                             optional        hyperv
 dev/hyperv/netvsc/hn_rndis.c                           optional        hyperv
-dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c              optional        hyperv
+dev/hyperv/netvsc/if_hn.c                              optional        hyperv
 dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c            optional        hyperv
 dev/hyperv/utilities/hv_heartbeat.c                    optional        hyperv
 dev/hyperv/utilities/hv_kvp.c                          optional        hyperv

Copied: head/sys/dev/hyperv/netvsc/if_hn.c (from r308162, 
head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/dev/hyperv/netvsc/if_hn.c  Tue Nov  1 06:54:25 2016        
(r308163, copy of r308162, head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c)
@@ -0,0 +1,4658 @@
+/*-
+ * Copyright (c) 2010-2012 Citrix Inc.
+ * Copyright (c) 2009-2012,2016 Microsoft Corp.
+ * Copyright (c) 2012 NetApp Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 2004-2006 Kip Macy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_inet6.h"
+#include "opt_inet.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <sys/queue.h>
+#include <sys/lock.h>
+#include <sys/smp.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sx.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/taskqueue.h>
+#include <sys/buf_ring.h>
+
+#include <machine/atomic.h>
+#include <machine/in_cksum.h>
+
+#include <net/bpf.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+#include <net/rndis.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_lro.h>
+#include <netinet/udp.h>
+
+#include <dev/hyperv/include/hyperv.h>
+#include <dev/hyperv/include/hyperv_busdma.h>
+#include <dev/hyperv/include/vmbus.h>
+#include <dev/hyperv/include/vmbus_xact.h>
+
+#include <dev/hyperv/netvsc/ndis.h>
+#include <dev/hyperv/netvsc/if_hnreg.h>
+#include <dev/hyperv/netvsc/if_hnvar.h>
+#include <dev/hyperv/netvsc/hn_nvs.h>
+#include <dev/hyperv/netvsc/hn_rndis.h>
+
+#include "vmbus_if.h"
+
+#define HN_RING_CNT_DEF_MAX            8
+
+/* YYY should get it from the underlying channel */
+#define HN_TX_DESC_CNT                 512
+
+#define HN_RNDIS_PKT_LEN                                       \
+       (sizeof(struct rndis_packet_msg) +                      \
+        HN_RNDIS_PKTINFO_SIZE(HN_NDIS_HASH_VALUE_SIZE) +       \
+        HN_RNDIS_PKTINFO_SIZE(NDIS_VLAN_INFO_SIZE) +           \
+        HN_RNDIS_PKTINFO_SIZE(NDIS_LSO2_INFO_SIZE) +           \
+        HN_RNDIS_PKTINFO_SIZE(NDIS_TXCSUM_INFO_SIZE))
+#define HN_RNDIS_PKT_BOUNDARY          PAGE_SIZE
+#define HN_RNDIS_PKT_ALIGN             CACHE_LINE_SIZE
+
+#define HN_TX_DATA_BOUNDARY            PAGE_SIZE
+#define HN_TX_DATA_MAXSIZE             IP_MAXPACKET
+#define HN_TX_DATA_SEGSIZE             PAGE_SIZE
+/* -1 for RNDIS packet message */
+#define HN_TX_DATA_SEGCNT_MAX          (HN_GPACNT_MAX - 1)
+
+#define HN_DIRECT_TX_SIZE_DEF          128
+
+#define HN_EARLY_TXEOF_THRESH          8
+
+#define HN_PKTBUF_LEN_DEF              (16 * 1024)
+
+#define HN_LROENT_CNT_DEF              128
+
+#define HN_LRO_LENLIM_MULTIRX_DEF      (12 * ETHERMTU)
+#define HN_LRO_LENLIM_DEF              (25 * ETHERMTU)
+/* YYY 2*MTU is a bit rough, but should be good enough. */
+#define HN_LRO_LENLIM_MIN(ifp)         (2 * (ifp)->if_mtu)
+
+#define HN_LRO_ACKCNT_DEF              1
+
+#define HN_LOCK_INIT(sc)               \
+       sx_init(&(sc)->hn_lock, device_get_nameunit((sc)->hn_dev))
+#define HN_LOCK_DESTROY(sc)            sx_destroy(&(sc)->hn_lock)
+#define HN_LOCK_ASSERT(sc)             sx_assert(&(sc)->hn_lock, SA_XLOCKED)
+#define HN_LOCK(sc)                    sx_xlock(&(sc)->hn_lock)
+#define HN_UNLOCK(sc)                  sx_xunlock(&(sc)->hn_lock)
+
+#define HN_CSUM_IP_MASK                        (CSUM_IP | CSUM_IP_TCP | 
CSUM_IP_UDP)
+#define HN_CSUM_IP6_MASK               (CSUM_IP6_TCP | CSUM_IP6_UDP)
+#define HN_CSUM_IP_HWASSIST(sc)                \
+       ((sc)->hn_tx_ring[0].hn_csum_assist & HN_CSUM_IP_MASK)
+#define HN_CSUM_IP6_HWASSIST(sc)       \
+       ((sc)->hn_tx_ring[0].hn_csum_assist & HN_CSUM_IP6_MASK)
+
+struct hn_txdesc {
+#ifndef HN_USE_TXDESC_BUFRING
+       SLIST_ENTRY(hn_txdesc)          link;
+#endif
+       struct mbuf                     *m;
+       struct hn_tx_ring               *txr;
+       int                             refs;
+       uint32_t                        flags;  /* HN_TXD_FLAG_ */
+       struct hn_nvs_sendctx           send_ctx;
+       uint32_t                        chim_index;
+       int                             chim_size;
+
+       bus_dmamap_t                    data_dmap;
+
+       bus_addr_t                      rndis_pkt_paddr;
+       struct rndis_packet_msg         *rndis_pkt;
+       bus_dmamap_t                    rndis_pkt_dmap;
+};
+
+#define HN_TXD_FLAG_ONLIST             0x0001
+#define HN_TXD_FLAG_DMAMAP             0x0002
+
+struct hn_rxinfo {
+       uint32_t                        vlan_info;
+       uint32_t                        csum_info;
+       uint32_t                        hash_info;
+       uint32_t                        hash_value;
+};
+
+#define HN_RXINFO_VLAN                 0x0001
+#define HN_RXINFO_CSUM                 0x0002
+#define HN_RXINFO_HASHINF              0x0004
+#define HN_RXINFO_HASHVAL              0x0008
+#define HN_RXINFO_ALL                  \
+       (HN_RXINFO_VLAN |               \
+        HN_RXINFO_CSUM |               \
+        HN_RXINFO_HASHINF |            \
+        HN_RXINFO_HASHVAL)
+
+#define HN_NDIS_VLAN_INFO_INVALID      0xffffffff
+#define HN_NDIS_RXCSUM_INFO_INVALID    0
+#define HN_NDIS_HASH_INFO_INVALID      0
+
+static int                     hn_probe(device_t);
+static int                     hn_attach(device_t);
+static int                     hn_detach(device_t);
+static int                     hn_shutdown(device_t);
+static void                    hn_chan_callback(struct vmbus_channel *,
+                                   void *);
+
+static void                    hn_init(void *);
+static int                     hn_ioctl(struct ifnet *, u_long, caddr_t);
+static void                    hn_start(struct ifnet *);
+static int                     hn_transmit(struct ifnet *, struct mbuf *);
+static void                    hn_xmit_qflush(struct ifnet *);
+static int                     hn_ifmedia_upd(struct ifnet *);
+static void                    hn_ifmedia_sts(struct ifnet *,
+                                   struct ifmediareq *);
+
+static int                     hn_rndis_rxinfo(const void *, int,
+                                   struct hn_rxinfo *);
+static void                    hn_rndis_rx_data(struct hn_rx_ring *,
+                                   const void *, int);
+static void                    hn_rndis_rx_status(struct hn_softc *,
+                                   const void *, int);
+
+static void                    hn_nvs_handle_notify(struct hn_softc *,
+                                   const struct vmbus_chanpkt_hdr *);
+static void                    hn_nvs_handle_comp(struct hn_softc *,
+                                   struct vmbus_channel *,
+                                   const struct vmbus_chanpkt_hdr *);
+static void                    hn_nvs_handle_rxbuf(struct hn_rx_ring *,
+                                   struct vmbus_channel *,
+                                   const struct vmbus_chanpkt_hdr *);
+static void                    hn_nvs_ack_rxbuf(struct hn_rx_ring *,
+                                   struct vmbus_channel *, uint64_t);
+
+#if __FreeBSD_version >= 1100099
+static int                     hn_lro_lenlim_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_lro_ackcnt_sysctl(SYSCTL_HANDLER_ARGS);
+#endif
+static int                     hn_trust_hcsum_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_chim_size_sysctl(SYSCTL_HANDLER_ARGS);
+#if __FreeBSD_version < 1100095
+static int                     hn_rx_stat_int_sysctl(SYSCTL_HANDLER_ARGS);
+#else
+static int                     hn_rx_stat_u64_sysctl(SYSCTL_HANDLER_ARGS);
+#endif
+static int                     hn_rx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_tx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_caps_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_hwassist_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_rxfilter_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS);
+static int                     hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS);
+
+static void                    hn_stop(struct hn_softc *);
+static void                    hn_init_locked(struct hn_softc *);
+static int                     hn_chan_attach(struct hn_softc *,
+                                   struct vmbus_channel *);
+static void                    hn_chan_detach(struct hn_softc *,
+                                   struct vmbus_channel *);
+static int                     hn_attach_subchans(struct hn_softc *);
+static void                    hn_detach_allchans(struct hn_softc *);
+static void                    hn_chan_rollup(struct hn_rx_ring *,
+                                   struct hn_tx_ring *);
+static void                    hn_set_ring_inuse(struct hn_softc *, int);
+static int                     hn_synth_attach(struct hn_softc *, int);
+static void                    hn_synth_detach(struct hn_softc *);
+static int                     hn_synth_alloc_subchans(struct hn_softc *,
+                                   int *);
+static void                    hn_suspend(struct hn_softc *);
+static void                    hn_suspend_data(struct hn_softc *);
+static void                    hn_suspend_mgmt(struct hn_softc *);
+static void                    hn_resume(struct hn_softc *);
+static void                    hn_resume_data(struct hn_softc *);
+static void                    hn_resume_mgmt(struct hn_softc *);
+static void                    hn_suspend_mgmt_taskfunc(void *, int);
+static void                    hn_chan_drain(struct vmbus_channel *);
+
+static void                    hn_update_link_status(struct hn_softc *);
+static void                    hn_change_network(struct hn_softc *);
+static void                    hn_link_taskfunc(void *, int);
+static void                    hn_netchg_init_taskfunc(void *, int);
+static void                    hn_netchg_status_taskfunc(void *, int);
+static void                    hn_link_status(struct hn_softc *);
+
+static int                     hn_create_rx_data(struct hn_softc *, int);
+static void                    hn_destroy_rx_data(struct hn_softc *);
+static int                     hn_check_iplen(const struct mbuf *, int);
+static int                     hn_set_rxfilter(struct hn_softc *);
+static int                     hn_rss_reconfig(struct hn_softc *);
+static void                    hn_rss_ind_fixup(struct hn_softc *, int);
+static int                     hn_rxpkt(struct hn_rx_ring *, const void *,
+                                   int, const struct hn_rxinfo *);
+
+static int                     hn_tx_ring_create(struct hn_softc *, int);
+static void                    hn_tx_ring_destroy(struct hn_tx_ring *);
+static int                     hn_create_tx_data(struct hn_softc *, int);
+static void                    hn_fixup_tx_data(struct hn_softc *);
+static void                    hn_destroy_tx_data(struct hn_softc *);
+static void                    hn_txdesc_dmamap_destroy(struct hn_txdesc *);
+static int                     hn_encap(struct hn_tx_ring *,
+                                   struct hn_txdesc *, struct mbuf **);
+static int                     hn_txpkt(struct ifnet *, struct hn_tx_ring *,
+                                   struct hn_txdesc *);
+static void                    hn_set_chim_size(struct hn_softc *, int);
+static void                    hn_set_tso_maxsize(struct hn_softc *, int, int);
+static bool                    hn_tx_ring_pending(struct hn_tx_ring *);
+static void                    hn_tx_ring_qflush(struct hn_tx_ring *);
+static void                    hn_resume_tx(struct hn_softc *, int);
+static int                     hn_get_txswq_depth(const struct hn_tx_ring *);
+static void                    hn_txpkt_done(struct hn_nvs_sendctx *,
+                                   struct hn_softc *, struct vmbus_channel *,
+                                   const void *, int);
+static int                     hn_txpkt_sglist(struct hn_tx_ring *,
+                                   struct hn_txdesc *);
+static int                     hn_txpkt_chim(struct hn_tx_ring *,
+                                   struct hn_txdesc *);
+static int                     hn_xmit(struct hn_tx_ring *, int);
+static void                    hn_xmit_taskfunc(void *, int);
+static void                    hn_xmit_txeof(struct hn_tx_ring *);
+static void                    hn_xmit_txeof_taskfunc(void *, int);
+static int                     hn_start_locked(struct hn_tx_ring *, int);
+static void                    hn_start_taskfunc(void *, int);
+static void                    hn_start_txeof(struct hn_tx_ring *);
+static void                    hn_start_txeof_taskfunc(void *, int);
+
+SYSCTL_NODE(_hw, OID_AUTO, hn, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
+    "Hyper-V network interface");
+
+/* Trust tcp segements verification on host side. */
+static int                     hn_trust_hosttcp = 1;
+SYSCTL_INT(_hw_hn, OID_AUTO, trust_hosttcp, CTLFLAG_RDTUN,
+    &hn_trust_hosttcp, 0,
+    "Trust tcp segement verification on host side, "
+    "when csum info is missing (global setting)");
+
+/* Trust udp datagrams verification on host side. */
+static int                     hn_trust_hostudp = 1;
+SYSCTL_INT(_hw_hn, OID_AUTO, trust_hostudp, CTLFLAG_RDTUN,
+    &hn_trust_hostudp, 0,
+    "Trust udp datagram verification on host side, "
+    "when csum info is missing (global setting)");
+
+/* Trust ip packets verification on host side. */
+static int                     hn_trust_hostip = 1;
+SYSCTL_INT(_hw_hn, OID_AUTO, trust_hostip, CTLFLAG_RDTUN,
+    &hn_trust_hostip, 0,
+    "Trust ip packet verification on host side, "
+    "when csum info is missing (global setting)");
+
+/* Limit TSO burst size */
+static int                     hn_tso_maxlen = IP_MAXPACKET;
+SYSCTL_INT(_hw_hn, OID_AUTO, tso_maxlen, CTLFLAG_RDTUN,
+    &hn_tso_maxlen, 0, "TSO burst limit");
+
+/* Limit chimney send size */
+static int                     hn_tx_chimney_size = 0;
+SYSCTL_INT(_hw_hn, OID_AUTO, tx_chimney_size, CTLFLAG_RDTUN,
+    &hn_tx_chimney_size, 0, "Chimney send packet size limit");
+
+/* Limit the size of packet for direct transmission */
+static int                     hn_direct_tx_size = HN_DIRECT_TX_SIZE_DEF;
+SYSCTL_INT(_hw_hn, OID_AUTO, direct_tx_size, CTLFLAG_RDTUN,
+    &hn_direct_tx_size, 0, "Size of the packet for direct transmission");
+
+/* # of LRO entries per RX ring */
+#if defined(INET) || defined(INET6)
+#if __FreeBSD_version >= 1100095
+static int                     hn_lro_entry_count = HN_LROENT_CNT_DEF;
+SYSCTL_INT(_hw_hn, OID_AUTO, lro_entry_count, CTLFLAG_RDTUN,
+    &hn_lro_entry_count, 0, "LRO entry count");
+#endif
+#endif
+
+/* Use shared TX taskqueue */
+static int                     hn_share_tx_taskq = 0;
+SYSCTL_INT(_hw_hn, OID_AUTO, share_tx_taskq, CTLFLAG_RDTUN,
+    &hn_share_tx_taskq, 0, "Enable shared TX taskqueue");
+
+#ifndef HN_USE_TXDESC_BUFRING
+static int                     hn_use_txdesc_bufring = 0;
+#else
+static int                     hn_use_txdesc_bufring = 1;
+#endif
+SYSCTL_INT(_hw_hn, OID_AUTO, use_txdesc_bufring, CTLFLAG_RD,
+    &hn_use_txdesc_bufring, 0, "Use buf_ring for TX descriptors");
+
+/* Bind TX taskqueue to the target CPU */
+static int                     hn_bind_tx_taskq = -1;
+SYSCTL_INT(_hw_hn, OID_AUTO, bind_tx_taskq, CTLFLAG_RDTUN,
+    &hn_bind_tx_taskq, 0, "Bind TX taskqueue to the specified cpu");
+
+/* Use ifnet.if_start instead of ifnet.if_transmit */
+static int                     hn_use_if_start = 0;
+SYSCTL_INT(_hw_hn, OID_AUTO, use_if_start, CTLFLAG_RDTUN,
+    &hn_use_if_start, 0, "Use if_start TX method");
+
+/* # of channels to use */
+static int                     hn_chan_cnt = 0;
+SYSCTL_INT(_hw_hn, OID_AUTO, chan_cnt, CTLFLAG_RDTUN,
+    &hn_chan_cnt, 0,
+    "# of channels to use; each channel has one RX ring and one TX ring");
+
+/* # of transmit rings to use */
+static int                     hn_tx_ring_cnt = 0;
+SYSCTL_INT(_hw_hn, OID_AUTO, tx_ring_cnt, CTLFLAG_RDTUN,
+    &hn_tx_ring_cnt, 0, "# of TX rings to use");
+
+/* Software TX ring deptch */
+static int                     hn_tx_swq_depth = 0;
+SYSCTL_INT(_hw_hn, OID_AUTO, tx_swq_depth, CTLFLAG_RDTUN,
+    &hn_tx_swq_depth, 0, "Depth of IFQ or BUFRING");
+
+/* Enable sorted LRO, and the depth of the per-channel mbuf queue */
+#if __FreeBSD_version >= 1100095
+static u_int                   hn_lro_mbufq_depth = 0;
+SYSCTL_UINT(_hw_hn, OID_AUTO, lro_mbufq_depth, CTLFLAG_RDTUN,
+    &hn_lro_mbufq_depth, 0, "Depth of LRO mbuf queue");
+#endif
+
+static u_int                   hn_cpu_index;   /* next CPU for channel */
+static struct taskqueue                *hn_tx_taskq;   /* shared TX taskqueue 
*/
+
+static const uint8_t
+hn_rss_key_default[NDIS_HASH_KEYSIZE_TOEPLITZ] = {
+       0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
+       0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
+       0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
+       0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
+       0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
+};
+
+static device_method_t hn_methods[] = {
+       /* Device interface */
+       DEVMETHOD(device_probe,         hn_probe),
+       DEVMETHOD(device_attach,        hn_attach),
+       DEVMETHOD(device_detach,        hn_detach),
+       DEVMETHOD(device_shutdown,      hn_shutdown),
+       DEVMETHOD_END
+};
+
+static driver_t hn_driver = {
+       "hn",
+       hn_methods,
+       sizeof(struct hn_softc)
+};
+
+static devclass_t hn_devclass;
+
+DRIVER_MODULE(hn, vmbus, hn_driver, hn_devclass, 0, 0);
+MODULE_VERSION(hn, 1);
+MODULE_DEPEND(hn, vmbus, 1, 1, 1);
+
+#if __FreeBSD_version >= 1100099
+static void
+hn_set_lro_lenlim(struct hn_softc *sc, int lenlim)
+{
+       int i;
+
+       for (i = 0; i < sc->hn_rx_ring_inuse; ++i)
+               sc->hn_rx_ring[i].hn_lro.lro_length_lim = lenlim;
+}
+#endif
+
+static int
+hn_txpkt_sglist(struct hn_tx_ring *txr, struct hn_txdesc *txd)
+{
+
+       KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID &&
+           txd->chim_size == 0, ("invalid rndis sglist txd"));
+       return (hn_nvs_send_rndis_sglist(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA,
+           &txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt));
+}
+
+static int
+hn_txpkt_chim(struct hn_tx_ring *txr, struct hn_txdesc *txd)
+{
+       struct hn_nvs_rndis rndis;
+
+       KASSERT(txd->chim_index != HN_NVS_CHIM_IDX_INVALID &&
+           txd->chim_size > 0, ("invalid rndis chim txd"));
+
+       rndis.nvs_type = HN_NVS_TYPE_RNDIS;
+       rndis.nvs_rndis_mtype = HN_NVS_RNDIS_MTYPE_DATA;
+       rndis.nvs_chim_idx = txd->chim_index;
+       rndis.nvs_chim_sz = txd->chim_size;
+
+       return (hn_nvs_send(txr->hn_chan, VMBUS_CHANPKT_FLAG_RC,
+           &rndis, sizeof(rndis), &txd->send_ctx));
+}
+
+static __inline uint32_t
+hn_chim_alloc(struct hn_softc *sc)
+{
+       int i, bmap_cnt = sc->hn_chim_bmap_cnt;
+       u_long *bmap = sc->hn_chim_bmap;
+       uint32_t ret = HN_NVS_CHIM_IDX_INVALID;
+
+       for (i = 0; i < bmap_cnt; ++i) {
+               int idx;
+
+               idx = ffsl(~bmap[i]);
+               if (idx == 0)
+                       continue;
+
+               --idx; /* ffsl is 1-based */
+               KASSERT(i * LONG_BIT + idx < sc->hn_chim_cnt,
+                   ("invalid i %d and idx %d", i, idx));
+
+               if (atomic_testandset_long(&bmap[i], idx))
+                       continue;
+
+               ret = i * LONG_BIT + idx;
+               break;
+       }
+       return (ret);
+}
+
+static __inline void
+hn_chim_free(struct hn_softc *sc, uint32_t chim_idx)
+{
+       u_long mask;
+       uint32_t idx;
+
+       idx = chim_idx / LONG_BIT;
+       KASSERT(idx < sc->hn_chim_bmap_cnt,
+           ("invalid chimney index 0x%x", chim_idx));
+
+       mask = 1UL << (chim_idx % LONG_BIT);
+       KASSERT(sc->hn_chim_bmap[idx] & mask,
+           ("index bitmap 0x%lx, chimney index %u, "
+            "bitmap idx %d, bitmask 0x%lx",
+            sc->hn_chim_bmap[idx], chim_idx, idx, mask));
+
+       atomic_clear_long(&sc->hn_chim_bmap[idx], mask);
+}
+
+static int
+hn_set_rxfilter(struct hn_softc *sc)
+{
+       struct ifnet *ifp = sc->hn_ifp;
+       uint32_t filter;
+       int error = 0;
+
+       HN_LOCK_ASSERT(sc);
+
+       if (ifp->if_flags & IFF_PROMISC) {
+               filter = NDIS_PACKET_TYPE_PROMISCUOUS;
+       } else {
+               filter = NDIS_PACKET_TYPE_DIRECTED;
+               if (ifp->if_flags & IFF_BROADCAST)
+                       filter |= NDIS_PACKET_TYPE_BROADCAST;
+#ifdef notyet
+               /*
+                * See the comment in SIOCADDMULTI/SIOCDELMULTI.
+                */
+               /* TODO: support multicast list */
+               if ((ifp->if_flags & IFF_ALLMULTI) ||
+                   !TAILQ_EMPTY(&ifp->if_multiaddrs))
+                       filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
+#else
+               /* Always enable ALLMULTI */
+               filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
+#endif
+       }
+
+       if (sc->hn_rx_filter != filter) {
+               error = hn_rndis_set_rxfilter(sc, filter);
+               if (!error)
+                       sc->hn_rx_filter = filter;
+       }
+       return (error);
+}
+
+static int
+hn_get_txswq_depth(const struct hn_tx_ring *txr)
+{
+
+       KASSERT(txr->hn_txdesc_cnt > 0, ("tx ring is not setup yet"));
+       if (hn_tx_swq_depth < txr->hn_txdesc_cnt)
+               return txr->hn_txdesc_cnt;
+       return hn_tx_swq_depth;
+}
+
+static int
+hn_rss_reconfig(struct hn_softc *sc)
+{
+       int error;
+
+       HN_LOCK_ASSERT(sc);
+
+       if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0)
+               return (ENXIO);
+
+       /*
+        * Disable RSS first.
+        *
+        * NOTE:
+        * Direct reconfiguration by setting the UNCHG flags does
+        * _not_ work properly.
+        */
+       if (bootverbose)
+               if_printf(sc->hn_ifp, "disable RSS\n");
+       error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_DISABLE);
+       if (error) {
+               if_printf(sc->hn_ifp, "RSS disable failed\n");
+               return (error);
+       }
+
+       /*
+        * Reenable the RSS w/ the updated RSS key or indirect
+        * table.
+        */
+       if (bootverbose)
+               if_printf(sc->hn_ifp, "reconfig RSS\n");
+       error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_NONE);
+       if (error) {
+               if_printf(sc->hn_ifp, "RSS reconfig failed\n");
+               return (error);
+       }
+       return (0);
+}
+
+static void
+hn_rss_ind_fixup(struct hn_softc *sc, int nchan)
+{
+       struct ndis_rssprm_toeplitz *rss = &sc->hn_rss;
+       int i;
+
+       KASSERT(nchan > 1, ("invalid # of channels %d", nchan));
+
+       /*
+        * Check indirect table to make sure that all channels in it
+        * can be used.
+        */
+       for (i = 0; i < NDIS_HASH_INDCNT; ++i) {
+               if (rss->rss_ind[i] >= nchan) {
+                       if_printf(sc->hn_ifp,
+                           "RSS indirect table %d fixup: %u -> %d\n",
+                           i, rss->rss_ind[i], nchan - 1);
+                       rss->rss_ind[i] = nchan - 1;
+               }
+       }
+}
+
+static int
+hn_ifmedia_upd(struct ifnet *ifp __unused)
+{
+
+       return EOPNOTSUPP;
+}
+
+static void
+hn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+       struct hn_softc *sc = ifp->if_softc;
+
+       ifmr->ifm_status = IFM_AVALID;
+       ifmr->ifm_active = IFM_ETHER;
+
+       if ((sc->hn_link_flags & HN_LINK_FLAG_LINKUP) == 0) {
+               ifmr->ifm_active |= IFM_NONE;
+               return;
+       }
+       ifmr->ifm_status |= IFM_ACTIVE;
+       ifmr->ifm_active |= IFM_10G_T | IFM_FDX;
+}
+
+/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
+static const struct hyperv_guid g_net_vsc_device_type = {
+       .hv_guid = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
+               0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}
+};
+
+static int
+hn_probe(device_t dev)
+{
+
+       if (VMBUS_PROBE_GUID(device_get_parent(dev), dev,
+           &g_net_vsc_device_type) == 0) {
+               device_set_desc(dev, "Hyper-V Network Interface");
+               return BUS_PROBE_DEFAULT;
+       }
+       return ENXIO;
+}
+
+static int
+hn_attach(device_t dev)
+{
+       struct hn_softc *sc = device_get_softc(dev);
+       struct sysctl_oid_list *child;
+       struct sysctl_ctx_list *ctx;
+       uint8_t eaddr[ETHER_ADDR_LEN];
+       struct ifnet *ifp = NULL;
+       int error, ring_cnt, tx_ring_cnt;
+
+       sc->hn_dev = dev;
+       sc->hn_prichan = vmbus_get_channel(dev);
+       HN_LOCK_INIT(sc);
+
+       /*
+        * Setup taskqueue for transmission.
+        */
+       if (hn_tx_taskq == NULL) {
+               sc->hn_tx_taskq = taskqueue_create("hn_tx", M_WAITOK,
+                   taskqueue_thread_enqueue, &sc->hn_tx_taskq);
+               if (hn_bind_tx_taskq >= 0) {
+                       int cpu = hn_bind_tx_taskq;
+                       cpuset_t cpu_set;
+
+                       if (cpu > mp_ncpus - 1)
+                               cpu = mp_ncpus - 1;
+                       CPU_SETOF(cpu, &cpu_set);
+                       taskqueue_start_threads_cpuset(&sc->hn_tx_taskq, 1,
+                           PI_NET, &cpu_set, "%s tx",
+                           device_get_nameunit(dev));
+               } else {
+                       taskqueue_start_threads(&sc->hn_tx_taskq, 1, PI_NET,
+                           "%s tx", device_get_nameunit(dev));
+               }
+       } else {
+               sc->hn_tx_taskq = hn_tx_taskq;
+       }
+
+       /*
+        * Setup taskqueue for mangement tasks, e.g. link status.
+        */
+       sc->hn_mgmt_taskq0 = taskqueue_create("hn_mgmt", M_WAITOK,
+           taskqueue_thread_enqueue, &sc->hn_mgmt_taskq0);
+       taskqueue_start_threads(&sc->hn_mgmt_taskq0, 1, PI_NET, "%s mgmt",
+           device_get_nameunit(dev));
+       TASK_INIT(&sc->hn_link_task, 0, hn_link_taskfunc, sc);
+       TASK_INIT(&sc->hn_netchg_init, 0, hn_netchg_init_taskfunc, sc);
+       TIMEOUT_TASK_INIT(sc->hn_mgmt_taskq0, &sc->hn_netchg_status, 0,
+           hn_netchg_status_taskfunc, sc);
+
+       /*
+        * Allocate ifnet and setup its name earlier, so that if_printf
+        * can be used by functions, which will be called after
+        * ether_ifattach().
+        */
+       ifp = sc->hn_ifp = if_alloc(IFT_ETHER);
+       ifp->if_softc = sc;
+       if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+
+       /*
+        * Initialize ifmedia earlier so that it can be unconditionally
+        * destroyed, if error happened later on.
+        */
+       ifmedia_init(&sc->hn_media, 0, hn_ifmedia_upd, hn_ifmedia_sts);
+
+       /*
+        * Figure out the # of RX rings (ring_cnt) and the # of TX rings
+        * to use (tx_ring_cnt).
+        *
+        * NOTE:
+        * The # of RX rings to use is same as the # of channels to use.
+        */
+       ring_cnt = hn_chan_cnt;
+       if (ring_cnt <= 0) {
+               /* Default */
+               ring_cnt = mp_ncpus;
+               if (ring_cnt > HN_RING_CNT_DEF_MAX)
+                       ring_cnt = HN_RING_CNT_DEF_MAX;
+       } else if (ring_cnt > mp_ncpus) {
+               ring_cnt = mp_ncpus;
+       }
+
+       tx_ring_cnt = hn_tx_ring_cnt;
+       if (tx_ring_cnt <= 0 || tx_ring_cnt > ring_cnt)
+               tx_ring_cnt = ring_cnt;
+       if (hn_use_if_start) {
+               /* ifnet.if_start only needs one TX ring. */
+               tx_ring_cnt = 1;
+       }
+
+       /*
+        * Set the leader CPU for channels.
+        */
+       sc->hn_cpu = atomic_fetchadd_int(&hn_cpu_index, ring_cnt) % mp_ncpus;
+
+       /*
+        * Create enough TX/RX rings, even if only limited number of
+        * channels can be allocated.
+        */
+       error = hn_create_tx_data(sc, tx_ring_cnt);
+       if (error)
+               goto failed;
+       error = hn_create_rx_data(sc, ring_cnt);
+       if (error)
+               goto failed;
+
+       /*
+        * Create transaction context for NVS and RNDIS transactions.
+        */
+       sc->hn_xact = vmbus_xact_ctx_create(bus_get_dma_tag(dev),
+           HN_XACT_REQ_SIZE, HN_XACT_RESP_SIZE, 0);
+       if (sc->hn_xact == NULL)
+               goto failed;
+
+       /*
+        * Attach the synthetic parts, i.e. NVS and RNDIS.
+        */
+       error = hn_synth_attach(sc, ETHERMTU);
+       if (error)
+               goto failed;
+
+       error = hn_rndis_get_eaddr(sc, eaddr);
+       if (error)
+               goto failed;
+
+#if __FreeBSD_version >= 1100099
+       if (sc->hn_rx_ring_inuse > 1) {
+               /*
+                * Reduce TCP segment aggregation limit for multiple
+                * RX rings to increase ACK timeliness.
+                */
+               hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MULTIRX_DEF);
+       }
+#endif
+
+       /*
+        * Fixup TX stuffs after synthetic parts are attached.
+        */
+       hn_fixup_tx_data(sc);
+
+       ctx = device_get_sysctl_ctx(dev);
+       child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+       SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "nvs_version", CTLFLAG_RD,
+           &sc->hn_nvs_ver, 0, "NVS version");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version",
+           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+           hn_ndis_version_sysctl, "A", "NDIS version");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "caps",
+           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+           hn_caps_sysctl, "A", "capabilities");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "hwassist",
+           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+           hn_hwassist_sysctl, "A", "hwassist");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rxfilter",
+           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+           hn_rxfilter_sysctl, "A", "rxfilter");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_hash",
+           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+           hn_rss_hash_sysctl, "A", "RSS hash");
+       SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rss_ind_size",
+           CTLFLAG_RD, &sc->hn_rss_ind_size, 0, "RSS indirect entry count");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_key",
+           CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
+           hn_rss_key_sysctl, "IU", "RSS key");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_ind",
+           CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
+           hn_rss_ind_sysctl, "IU", "RSS indirect table");
+
+       /*
+        * Setup the ifmedia, which has been initialized earlier.
+        */
+       ifmedia_add(&sc->hn_media, IFM_ETHER | IFM_AUTO, 0, NULL);
+       ifmedia_set(&sc->hn_media, IFM_ETHER | IFM_AUTO);
+       /* XXX ifmedia_set really should do this for us */
+       sc->hn_media.ifm_media = sc->hn_media.ifm_cur->ifm_media;
+
+       /*
+        * Setup the ifnet for this interface.
+        */
+
+       ifp->if_baudrate = IF_Gbps(10);
+       ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+       ifp->if_ioctl = hn_ioctl;
+       ifp->if_init = hn_init;
+       if (hn_use_if_start) {
+               int qdepth = hn_get_txswq_depth(&sc->hn_tx_ring[0]);
+
+               ifp->if_start = hn_start;
+               IFQ_SET_MAXLEN(&ifp->if_snd, qdepth);
+               ifp->if_snd.ifq_drv_maxlen = qdepth - 1;
+               IFQ_SET_READY(&ifp->if_snd);
+       } else {
+               ifp->if_transmit = hn_transmit;
+               ifp->if_qflush = hn_xmit_qflush;
+       }
+
+       ifp->if_capabilities |= IFCAP_RXCSUM | IFCAP_LRO;
+#ifdef foo
+       /* We can't diff IPv6 packets from IPv4 packets on RX path. */
+       ifp->if_capabilities |= IFCAP_RXCSUM_IPV6;
+#endif
+       if (sc->hn_caps & HN_CAP_VLAN) {
+               /* XXX not sure about VLAN_MTU. */
+               ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
+       }
+
+       ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist;
+       if (ifp->if_hwassist & HN_CSUM_IP_MASK)
+               ifp->if_capabilities |= IFCAP_TXCSUM;
+       if (ifp->if_hwassist & HN_CSUM_IP6_MASK)
+               ifp->if_capabilities |= IFCAP_TXCSUM_IPV6;
+       if (sc->hn_caps & HN_CAP_TSO4) {
+               ifp->if_capabilities |= IFCAP_TSO4;
+               ifp->if_hwassist |= CSUM_IP_TSO;
+       }
+       if (sc->hn_caps & HN_CAP_TSO6) {
+               ifp->if_capabilities |= IFCAP_TSO6;
+               ifp->if_hwassist |= CSUM_IP6_TSO;
+       }
+
+       /* Enable all available capabilities by default. */
+       ifp->if_capenable = ifp->if_capabilities;
+
+       if (ifp->if_capabilities & (IFCAP_TSO6 | IFCAP_TSO4)) {
+               hn_set_tso_maxsize(sc, hn_tso_maxlen, ETHERMTU);
+               ifp->if_hw_tsomaxsegcount = HN_TX_DATA_SEGCNT_MAX;
+               ifp->if_hw_tsomaxsegsize = PAGE_SIZE;
+       }
+
+       ether_ifattach(ifp, eaddr);
+
+       if ((ifp->if_capabilities & (IFCAP_TSO6 | IFCAP_TSO4)) && bootverbose) {
+               if_printf(ifp, "TSO segcnt %u segsz %u\n",
+                   ifp->if_hw_tsomaxsegcount, ifp->if_hw_tsomaxsegsize);
+       }
+
+       /* Inform the upper layer about the long frame support. */
+       ifp->if_hdrlen = sizeof(struct ether_vlan_header);
+
+       /*
+        * Kick off link status check.
+        */
+       sc->hn_mgmt_taskq = sc->hn_mgmt_taskq0;
+       hn_update_link_status(sc);
+
+       return (0);
+failed:
+       if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED)
+               hn_synth_detach(sc);
+       hn_detach(dev);
+       return (error);
+}
+
+static int
+hn_detach(device_t dev)
+{
+       struct hn_softc *sc = device_get_softc(dev);
+       struct ifnet *ifp = sc->hn_ifp;
+
+       if (device_is_attached(dev)) {
+               HN_LOCK(sc);
+               if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) {
+                       if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+                               hn_stop(sc);
+                       /*
+                        * NOTE:
+                        * hn_stop() only suspends data, so managment
+                        * stuffs have to be suspended manually here.
+                        */
+                       hn_suspend_mgmt(sc);
+                       hn_synth_detach(sc);
+               }
+               HN_UNLOCK(sc);
+               ether_ifdetach(ifp);
+       }
+
+       ifmedia_removeall(&sc->hn_media);
+       hn_destroy_rx_data(sc);
+       hn_destroy_tx_data(sc);
+
+       if (sc->hn_tx_taskq != hn_tx_taskq)
+               taskqueue_free(sc->hn_tx_taskq);
+       taskqueue_free(sc->hn_mgmt_taskq0);
+
+       if (sc->hn_xact != NULL)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to