Index: sys/conf/files.amd64 =================================================================== --- sys/conf/files.amd64 +++ sys/conf/files.amd64 @@ -278,6 +278,7 @@ dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv +dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/amd64/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/amd64/vmbus_vector.S optional hyperv dev/nfe/if_nfe.c optional nfe pci Index: sys/conf/files.i386 =================================================================== --- sys/conf/files.i386 +++ sys/conf/files.i386 @@ -253,6 +253,7 @@ dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv +dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/i386/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/i386/vmbus_vector.S optional hyperv dev/ichwd/ichwd.c optional ichwd Index: sys/dev/hyperv/include/hyperv.h =================================================================== --- sys/dev/hyperv/include/hyperv.h +++ sys/dev/hyperv/include/hyperv.h @@ -73,10 +73,13 @@ * 2.4 -- Windows 8 * 3.0 -- Windows 8.1 */ -#define HV_VMBUS_VERSION_WS2008 ((0 << 16) | (13)) -#define HV_VMBUS_VERSION_WIN7 ((1 << 16) | (1)) -#define HV_VMBUS_VERSION_WIN8 ((2 << 16) | (4)) -#define HV_VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) +#define VMBUS_VERSION_WS2008 ((0 << 16) | (13)) +#define VMBUS_VERSION_WIN7 ((1 << 16) | (1)) +#define VMBUS_VERSION_WIN8 ((2 << 16) | (4)) +#define VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) + +#define VMBUS_VERSION_MAJOR(ver) (((uint32_t)(ver)) >> 16) +#define VMBUS_VERSION_MINOR(ver) (((uint32_t)(ver)) & 0xffff) /* * Make maximum size of pipe payload of 16K @@ -723,5 +726,4 @@ return (ret); } -extern uint32_t hv_vmbus_protocal_version; #endif /* __HYPERV_H__ */ Index: sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c =================================================================== --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -114,9 +114,11 @@ #include #include + #include "hv_net_vsc.h" #include "hv_rndis.h" #include "hv_rndis_filter.h" +#include "vmbus_if.h" #define hv_chan_rxr hv_chan_priv1 #define hv_chan_txr hv_chan_priv2 @@ -2369,8 +2371,10 @@ hn_create_tx_ring(struct hn_softc *sc, int id) { struct hn_tx_ring *txr = &sc->hn_tx_ring[id]; + device_t dev = sc->hn_dev; bus_dma_tag_t parent_dtag; int error, i; + uint32_t version; txr->hn_sc = sc; txr->hn_tx_idx = id; @@ -2409,10 +2413,18 @@ } txr->hn_direct_tx_size = hn_direct_tx_size; - if (hv_vmbus_protocal_version >= HV_VMBUS_VERSION_WIN8_1) + version = VMBUS_GET_VERSION(device_get_parent(dev), dev); + if (version >= VMBUS_VERSION_WIN8_1) { txr->hn_csum_assist = HN_CSUM_ASSIST; - else + } else { txr->hn_csum_assist = HN_CSUM_ASSIST_WIN8; + if (id == 0) { + device_printf(dev, "bus version %u.%u, " + "no UDP checksum offloading\n", + VMBUS_VERSION_MAJOR(version), + VMBUS_VERSION_MINOR(version)); + } + } /* * Always schedule transmission instead of trying to do direct @@ -2420,7 +2432,7 @@ */ txr->hn_sched_tx = 1; - parent_dtag = bus_get_dma_tag(sc->hn_dev); + parent_dtag = bus_get_dma_tag(dev); /* DMA tag for RNDIS messages. */ error = bus_dma_tag_create(parent_dtag, /* parent */ @@ -2437,7 +2449,7 @@ NULL, /* lockfuncarg */ &txr->hn_tx_rndis_dtag); if (error) { - device_printf(sc->hn_dev, "failed to create rndis dmatag\n"); + device_printf(dev, "failed to create rndis dmatag\n"); return error; } @@ -2456,7 +2468,7 @@ NULL, /* lockfuncarg */ &txr->hn_tx_data_dtag); if (error) { - device_printf(sc->hn_dev, "failed to create data dmatag\n"); + device_printf(dev, "failed to create data dmatag\n"); return error; } @@ -2473,7 +2485,7 @@ BUS_DMA_WAITOK | BUS_DMA_COHERENT, &txd->rndis_msg_dmap); if (error) { - device_printf(sc->hn_dev, + device_printf(dev, "failed to allocate rndis_msg, %d\n", i); return error; } @@ -2484,7 +2496,7 @@ hyperv_dma_map_paddr, &txd->rndis_msg_paddr, BUS_DMA_NOWAIT); if (error) { - device_printf(sc->hn_dev, + device_printf(dev, "failed to load rndis_msg, %d\n", i); bus_dmamem_free(txr->hn_tx_rndis_dtag, txd->rndis_msg, txd->rndis_msg_dmap); @@ -2495,7 +2507,7 @@ error = bus_dmamap_create(txr->hn_tx_data_dtag, 0, &txd->data_dmap); if (error) { - device_printf(sc->hn_dev, + device_printf(dev, "failed to allocate tx data dmamap\n"); bus_dmamap_unload(txr->hn_tx_rndis_dtag, txd->rndis_msg_dmap); @@ -2523,7 +2535,7 @@ * Create per TX ring sysctl tree: * dev.hn.UNIT.tx.RINGID */ - ctx = device_get_sysctl_ctx(sc->hn_dev); + ctx = device_get_sysctl_ctx(dev); child = SYSCTL_CHILDREN(sc->hn_tx_sysctl_tree); snprintf(name, sizeof(name), "%d", id); Index: sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c =================================================================== --- sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c +++ sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c @@ -72,7 +72,9 @@ #include #include + #include "hv_vstorage.h" +#include "vmbus_if.h" #define STORVSC_RINGBUFFER_SIZE (20*PAGE_SIZE) #define STORVSC_MAX_LUNS_PER_TARGET (64) @@ -465,6 +467,7 @@ struct storvsc_softc *sc; uint16_t max_chans = 0; boolean_t support_multichannel = FALSE; + uint32_t version; max_chans = 0; support_multichannel = FALSE; @@ -589,8 +592,9 @@ /* multi-channels feature is supported by WIN8 and above version */ max_chans = vstor_packet->u.chan_props.max_channel_cnt; - if ((hv_vmbus_protocal_version != HV_VMBUS_VERSION_WIN7) && - (hv_vmbus_protocal_version != HV_VMBUS_VERSION_WS2008) && + version = VMBUS_GET_VERSION(device_get_parent(dev->device), + dev->device); + if (version != VMBUS_VERSION_WIN7 && version != VMBUS_VERSION_WS2008 && (vstor_packet->u.chan_props.flags & HV_STORAGE_SUPPORTS_MULTI_CHANNEL)) { support_multichannel = TRUE; Index: sys/dev/hyperv/vmbus/hv_channel_mgmt.c =================================================================== --- sys/dev/hyperv/vmbus/hv_channel_mgmt.c +++ sys/dev/hyperv/vmbus/hv_channel_mgmt.c @@ -222,8 +222,8 @@ { KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpu %d", cpu)); - if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 || - hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7) { + if (chan->vmbus_sc->vmbus_version == VMBUS_VERSION_WS2008 || + chan->vmbus_sc->vmbus_version == VMBUS_VERSION_WIN7) { /* Only cpu0 is supported */ cpu = 0; } @@ -305,7 +305,7 @@ } new_channel->ch_sigevt->hc_connid = VMBUS_CONNID_EVENT; - if (hv_vmbus_protocal_version != HV_VMBUS_VERSION_WS2008) { + if (sc->vmbus_version != VMBUS_VERSION_WS2008) { new_channel->is_dedicated_interrupt = (offer->is_dedicated_interrupt != 0); new_channel->ch_sigevt->hc_connid = offer->connection_id; Index: sys/dev/hyperv/vmbus/hv_connection.c =================================================================== --- sys/dev/hyperv/vmbus/hv_connection.c +++ sys/dev/hyperv/vmbus/hv_connection.c @@ -50,8 +50,6 @@ { .connect_state = HV_DISCONNECTED, .next_gpadl_handle = 0xE1E10, }; -uint32_t hv_vmbus_protocal_version; - /** * Send a connect request on the partition service connection */ Index: sys/dev/hyperv/vmbus/vmbus.c =================================================================== --- sys/dev/hyperv/vmbus/vmbus.c +++ sys/dev/hyperv/vmbus/vmbus.c @@ -68,6 +68,7 @@ #include #include "acpi_if.h" +#include "vmbus_if.h" struct vmbus_msghc { struct hypercall_postmsg_in *mh_inprm; @@ -113,10 +114,10 @@ extern inthand_t IDTVEC(vmbus_isr); static const uint32_t vmbus_version[] = { - HV_VMBUS_VERSION_WIN8_1, - HV_VMBUS_VERSION_WIN8, - HV_VMBUS_VERSION_WIN7, - HV_VMBUS_VERSION_WS2008 + VMBUS_VERSION_WIN8_1, + VMBUS_VERSION_WIN8, + VMBUS_VERSION_WIN7, + VMBUS_VERSION_WS2008 }; static struct vmbus_msghc * @@ -415,10 +416,10 @@ error = vmbus_connect(sc, vmbus_version[i]); if (!error) { - hv_vmbus_protocal_version = vmbus_version[i]; + sc->vmbus_version = vmbus_version[i]; device_printf(sc->vmbus_dev, "version %u.%u\n", - (hv_vmbus_protocal_version >> 16), - (hv_vmbus_protocal_version & 0xffff)); + VMBUS_VERSION_MAJOR(sc->vmbus_version), + VMBUS_VERSION_MINOR(sc->vmbus_version)); return 0; } } @@ -1064,14 +1065,23 @@ static int vmbus_sysctl_version(SYSCTL_HANDLER_ARGS) { + struct vmbus_softc *sc = arg1; char verstr[16]; snprintf(verstr, sizeof(verstr), "%u.%u", - hv_vmbus_protocal_version >> 16, - hv_vmbus_protocal_version & 0xffff); + VMBUS_VERSION_MAJOR(sc->vmbus_version), + VMBUS_VERSION_MINOR(sc->vmbus_version)); return sysctl_handle_string(oidp, verstr, sizeof(verstr), req); } +static uint32_t +vmbus_get_version_method(device_t bus, device_t dev) +{ + struct vmbus_softc *sc = device_get_softc(bus); + + return sc->vmbus_version; +} + static int vmbus_probe(device_t dev) { @@ -1155,8 +1165,8 @@ if (ret != 0) goto cleanup; - if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 || - hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7) + if (sc->vmbus_version == VMBUS_VERSION_WS2008 || + sc->vmbus_version == VMBUS_VERSION_WIN7) sc->vmbus_event_proc = vmbus_event_proc_compat; else sc->vmbus_event_proc = vmbus_event_proc; @@ -1168,7 +1178,7 @@ ctx = device_get_sysctl_ctx(sc->vmbus_dev); child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vmbus_dev)); SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "version", - CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, vmbus_sysctl_version, "A", "vmbus version"); return (ret); @@ -1281,6 +1291,9 @@ DEVMETHOD(bus_write_ivar, vmbus_write_ivar), DEVMETHOD(bus_child_pnpinfo_str, vmbus_child_pnpinfo_str), + /* Vmbus interface */ + DEVMETHOD(vmbus_get_version, vmbus_get_version_method), + DEVMETHOD_END }; Index: sys/dev/hyperv/vmbus/vmbus_if.m =================================================================== --- /dev/null +++ sys/dev/hyperv/vmbus/vmbus_if.m @@ -0,0 +1,37 @@ +#- +# Copyright (c) 2016 Microsoft Corp. +# 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. +# +# $FreeBSD$ +# + +#include +#include + +INTERFACE vmbus; + +METHOD uint32_t get_version { + device_t bus; + device_t dev; +}; Index: sys/dev/hyperv/vmbus/vmbus_var.h =================================================================== --- sys/dev/hyperv/vmbus/vmbus_var.h +++ sys/dev/hyperv/vmbus/vmbus_var.h @@ -78,10 +78,14 @@ struct vmbus_msghc_ctx *vmbus_msg_hc; struct vmbus_pcpu_data vmbus_pcpu[MAXCPU]; - /* Rarely used fields */ + /* + * Rarely used fields + */ + device_t vmbus_dev; int vmbus_idtvec; uint32_t vmbus_flags; /* see VMBUS_FLAG_ */ + uint32_t vmbus_version; /* Shared memory for vmbus_{rx,tx}_evtflags */ void *vmbus_evtflags; Index: sys/modules/hyperv/netvsc/Makefile =================================================================== --- sys/modules/hyperv/netvsc/Makefile +++ sys/modules/hyperv/netvsc/Makefile @@ -1,12 +1,13 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../../dev/hyperv/netvsc +.PATH: ${.CURDIR}/../../../dev/hyperv/netvsc \ + ${.CURDIR}/../../../dev/hyperv/vmbus KMOD= hv_netvsc SRCS= hv_net_vsc.c \ hv_netvsc_drv_freebsd.c \ hv_rndis_filter.c -SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h +SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h vmbus_if.h CFLAGS+= -I${.CURDIR}/../../../dev/hyperv/netvsc Index: sys/modules/hyperv/storvsc/Makefile =================================================================== --- sys/modules/hyperv/storvsc/Makefile +++ sys/modules/hyperv/storvsc/Makefile @@ -1,11 +1,12 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../../dev/hyperv/storvsc +.PATH: ${.CURDIR}/../../../dev/hyperv/storvsc \ + ${.CURDIR}/../../../dev/hyperv/vmbus \ KMOD= hv_storvsc SRCS = hv_storvsc_drv_freebsd.c \ hv_vstorage.h -SRCS+= bus_if.h device_if.h opt_cam.h +SRCS+= bus_if.h device_if.h opt_cam.h vmbus_if.h CFLAGS+= -I${.CURDIR}/../../../dev/hyperv/include \ -I${.CURDIR}/../../../dev/hyperv/vmbus \ Index: sys/modules/hyperv/vmbus/Makefile =================================================================== --- sys/modules/hyperv/vmbus/Makefile +++ sys/modules/hyperv/vmbus/Makefile @@ -13,7 +13,7 @@ hyperv_machdep.c \ vmbus.c \ vmbus_et.c -SRCS+= acpi_if.h bus_if.h device_if.h opt_acpi.h +SRCS+= acpi_if.h bus_if.h device_if.h opt_acpi.h vmbus_if.h # XXX: for assym.s SRCS+= opt_kstack_pages.h opt_nfs.h opt_apic.h opt_hwpmc_hooks.h opt_compat.h