Index: head/sys/dev/hyperv/include/hyperv.h =================================================================== --- head/sys/dev/hyperv/include/hyperv.h +++ head/sys/dev/hyperv/include/hyperv.h @@ -83,122 +83,8 @@ int hyperv_guid2str(const struct hyperv_guid *, char *, size_t); -typedef struct { - /* - * offset in bytes from the start of ring data below - */ - volatile uint32_t write_index; - /* - * offset in bytes from the start of ring data below - */ - volatile uint32_t read_index; - /* - * NOTE: The interrupt_mask field is used only for channels, but - * vmbus connection also uses this data structure - */ - volatile uint32_t interrupt_mask; - /* pad it to PAGE_SIZE so that data starts on a page */ - uint8_t reserved[4084]; - - /* - * WARNING: Ring data starts here - * !!! DO NOT place any fields below this !!! - */ - uint8_t buffer[0]; /* doubles as interrupt mask */ -} __packed hv_vmbus_ring_buffer; - -typedef struct { - hv_vmbus_ring_buffer* ring_buffer; - struct mtx ring_lock; - uint32_t ring_data_size; /* ring_size */ -} hv_vmbus_ring_buffer_info; - struct hv_vmbus_channel; -typedef void (*vmbus_chan_callback_t)(struct hv_vmbus_channel *, void *); - -typedef struct hv_vmbus_channel { - device_t ch_dev; - struct vmbus_softc *ch_vmbus; - uint32_t ch_flags; /* VMBUS_CHAN_FLAG_ */ - uint32_t ch_id; /* channel id */ - - /* - * These are based on the offer_msg.monitor_id. - * Save it here for easy access. - */ - int ch_montrig_idx; /* MNF trig index */ - uint32_t ch_montrig_mask;/* MNF trig mask */ - - /* - * TX bufring; at the beginning of ch_bufring. - */ - hv_vmbus_ring_buffer_info ch_txbr; - /* - * RX bufring; immediately following ch_txbr. - */ - hv_vmbus_ring_buffer_info ch_rxbr; - - struct taskqueue *ch_tq; - struct task ch_task; - vmbus_chan_callback_t ch_cb; - void *ch_cbarg; - - struct hyperv_mon_param *ch_monprm; - struct hyperv_dma ch_monprm_dma; - - int ch_cpuid; /* owner cpu */ - /* - * Virtual cpuid for ch_cpuid; it is used to communicate cpuid - * related information w/ Hyper-V. If MSR_HV_VP_INDEX does not - * exist, ch_vcpuid will always be 0 for compatibility. - */ - uint32_t ch_vcpuid; - - /* - * If this is a primary channel, ch_subchan* fields - * contain sub-channels belonging to this primary - * channel. - */ - struct mtx ch_subchan_lock; - TAILQ_HEAD(, hv_vmbus_channel) ch_subchans; - int ch_subchan_cnt; - - /* If this is a sub-channel */ - TAILQ_ENTRY(hv_vmbus_channel) ch_sublink; /* sub-channel link */ - struct hv_vmbus_channel *ch_prichan; /* owner primary chan */ - - void *ch_bufring; /* TX+RX bufrings */ - struct hyperv_dma ch_bufring_dma; - uint32_t ch_bufring_gpadl; - - struct task ch_detach_task; - TAILQ_ENTRY(hv_vmbus_channel) ch_prilink; /* primary chan link */ - uint32_t ch_subidx; /* subchan index */ - volatile uint32_t ch_stflags; /* atomic-op */ - /* VMBUS_CHAN_ST_ */ - struct hyperv_guid ch_guid_type; - struct hyperv_guid ch_guid_inst; - - struct sysctl_ctx_list ch_sysctl_ctx; -} hv_vmbus_channel; - -#define VMBUS_CHAN_ISPRIMARY(chan) ((chan)->ch_subidx == 0) - -#define VMBUS_CHAN_FLAG_HASMNF 0x0001 -/* - * If this flag is set, this channel's interrupt will be masked in ISR, - * and the RX bufring will be drained before this channel's interrupt is - * unmasked. - * - * This flag is turned on by default. Drivers can turn it off according - * to their own requirement. - */ -#define VMBUS_CHAN_FLAG_BATCHREAD 0x0002 - -#define VMBUS_CHAN_ST_OPENED_SHIFT 0 -#define VMBUS_CHAN_ST_OPENED (1 << VMBUS_CHAN_ST_OPENED_SHIFT) - /** * @brief Get physical address from virtual */ Index: head/sys/dev/hyperv/include/vmbus.h =================================================================== --- head/sys/dev/hyperv/include/vmbus.h +++ head/sys/dev/hyperv/include/vmbus.h @@ -88,6 +88,9 @@ #define VMBUS_CHAN_PRPLIST_MAX 32 struct hv_vmbus_channel; +struct hyperv_guid; + +typedef void (*vmbus_chan_callback_t)(struct hv_vmbus_channel *, void *); int vmbus_chan_open(struct hv_vmbus_channel *chan, int txbr_size, int rxbr_size, const void *udata, int udlen, @@ -124,4 +127,10 @@ struct vmbus_gpa_range *prp, int prp_cnt, void *data, int dlen, uint64_t xactid); +uint32_t vmbus_chan_id(const struct hv_vmbus_channel *chan); +uint32_t vmbus_chan_subidx(const struct hv_vmbus_channel *chan); +bool vmbus_chan_is_primary(const struct hv_vmbus_channel *chan); +const struct hyperv_guid * + vmbus_chan_guid_inst(const struct hv_vmbus_channel *chan); + #endif /* !_VMBUS_H_ */ Index: head/sys/dev/hyperv/netvsc/hv_net_vsc.c =================================================================== --- head/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -641,9 +641,9 @@ void hv_nv_subchan_attach(struct hv_vmbus_channel *chan, struct hn_rx_ring *rxr) { - KASSERT(rxr->hn_rx_idx == chan->ch_subidx, + KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan), ("chan%u subidx %u, rxr%d mismatch", - chan->ch_id, chan->ch_subidx, rxr->hn_rx_idx)); + vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx)); vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, hv_nv_on_channel_callback, rxr); @@ -673,9 +673,9 @@ /* * Open the channel */ - KASSERT(rxr->hn_rx_idx == chan->ch_subidx, + KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan), ("chan%u subidx %u, rxr%d mismatch", - chan->ch_id, chan->ch_subidx, rxr->hn_rx_idx)); + vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx)); ret = vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, hv_nv_on_channel_callback, rxr); Index: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c =================================================================== --- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -791,9 +791,8 @@ txr = txd->txr; KASSERT(txr->hn_chan == chan, - ("channel mismatch, on channel%u, should be channel%u", - chan->ch_subidx, - txr->hn_chan->ch_subidx)); + ("channel mismatch, on chan%u, should be chan%u", + vmbus_chan_subidx(chan), vmbus_chan_subidx(txr->hn_chan))); txr->hn_has_txeof = 1; hn_txdesc_put(txr, txd); @@ -2917,7 +2916,7 @@ struct hn_rx_ring *rxr; int idx; - idx = chan->ch_subidx; + idx = vmbus_chan_subidx(chan); KASSERT(idx >= 0 && idx < sc->hn_rx_ring_inuse, ("invalid channel index %d, should > 0 && < %d", @@ -2929,7 +2928,7 @@ if (bootverbose) { if_printf(sc->hn_ifp, "link RX ring %d to channel%u\n", - idx, chan->ch_id); + idx, vmbus_chan_id(chan)); } if (idx < sc->hn_tx_ring_inuse) { @@ -2942,7 +2941,7 @@ txr->hn_chan = chan; if (bootverbose) { if_printf(sc->hn_ifp, "link TX ring %d to channel%u\n", - idx, chan->ch_id); + idx, vmbus_chan_id(chan)); } } @@ -2954,11 +2953,8 @@ hn_subchan_attach(struct hn_softc *sc, struct hv_vmbus_channel *chan) { - KASSERT(!VMBUS_CHAN_ISPRIMARY(chan), + KASSERT(!vmbus_chan_is_primary(chan), ("subchannel callback on primary channel")); - KASSERT(chan->ch_subidx > 0, - ("invalid channel subidx %u", - chan->ch_subidx)); hn_channel_attach(sc, chan); } @@ -2979,7 +2975,7 @@ /* NOTE: Calling order is critical. */ hn_subchan_attach(sc, subchan); hv_nv_subchan_attach(subchan, - &sc->hn_rx_ring[subchan->ch_subidx]); + &sc->hn_rx_ring[vmbus_chan_subidx(subchan)]); } /* Release the sub-channels */ Index: head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c =================================================================== --- head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c +++ head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c @@ -876,7 +876,7 @@ sc->hs_cpu2chan[cpu] = vmbus_chan_cpu2chan(sc->hs_chan, cpu); if (bootverbose) { device_printf(sc->hs_dev, "cpu%d -> chan%u\n", - cpu, sc->hs_cpu2chan[cpu]->ch_id); + cpu, vmbus_chan_id(sc->hs_cpu2chan[cpu])); } } } Index: head/sys/dev/hyperv/utilities/hv_kvp.c =================================================================== --- head/sys/dev/hyperv/utilities/hv_kvp.c +++ head/sys/dev/hyperv/utilities/hv_kvp.c @@ -342,7 +342,8 @@ * TODO: need vmbus interface. */ chan = vmbus_get_channel(dev); - hyperv_guid2str(&chan->ch_guid_inst, buf, sizeof(buf)); + hyperv_guid2str(vmbus_chan_guid_inst(chan), + buf, sizeof(buf)); if (strncmp(buf, (char *)umsg->body.kvp_ip_val.adapter_id, HYPERV_GUID_STRLEN - 1) == 0) { @@ -615,7 +616,7 @@ hv_kvp_process_request(void *context, int pending) { uint8_t *kvp_buf; - hv_vmbus_channel *channel; + struct hv_vmbus_channel *channel; uint32_t recvlen = 0; uint64_t requestid; struct hv_vmbus_icmsg_hdr *icmsghdrp; Index: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h =================================================================== --- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h +++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h @@ -37,7 +37,7 @@ #include #include -#include +#include struct vmbus_softc; Index: head/sys/dev/hyperv/vmbus/vmbus_chan.c =================================================================== --- head/sys/dev/hyperv/vmbus/vmbus_chan.c +++ head/sys/dev/hyperv/vmbus/vmbus_chan.c @@ -1378,3 +1378,30 @@ else chan->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD; } + +uint32_t +vmbus_chan_id(const struct hv_vmbus_channel *chan) +{ + return chan->ch_id; +} + +uint32_t +vmbus_chan_subidx(const struct hv_vmbus_channel *chan) +{ + return chan->ch_subidx; +} + +bool +vmbus_chan_is_primary(const struct hv_vmbus_channel *chan) +{ + if (VMBUS_CHAN_ISPRIMARY(chan)) + return true; + else + return false; +} + +const struct hyperv_guid * +vmbus_chan_guid_inst(const struct hv_vmbus_channel *chan) +{ + return &chan->ch_guid_inst; +} Index: head/sys/dev/hyperv/vmbus/vmbus_chanvar.h =================================================================== --- head/sys/dev/hyperv/vmbus/vmbus_chanvar.h +++ head/sys/dev/hyperv/vmbus/vmbus_chanvar.h @@ -0,0 +1,155 @@ +/*- + * 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$ + */ + +#ifndef _VMBUS_CHANVAR_H_ +#define _VMBUS_CHANVAR_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef struct { + /* + * offset in bytes from the start of ring data below + */ + volatile uint32_t write_index; + /* + * offset in bytes from the start of ring data below + */ + volatile uint32_t read_index; + /* + * NOTE: The interrupt_mask field is used only for channels, but + * vmbus connection also uses this data structure + */ + volatile uint32_t interrupt_mask; + /* pad it to PAGE_SIZE so that data starts on a page */ + uint8_t reserved[4084]; + + /* + * WARNING: Ring data starts here + * !!! DO NOT place any fields below this !!! + */ + uint8_t buffer[0]; /* doubles as interrupt mask */ +} __packed hv_vmbus_ring_buffer; + +typedef struct { + hv_vmbus_ring_buffer* ring_buffer; + struct mtx ring_lock; + uint32_t ring_data_size; /* ring_size */ +} hv_vmbus_ring_buffer_info; + +typedef struct hv_vmbus_channel { + device_t ch_dev; + struct vmbus_softc *ch_vmbus; + uint32_t ch_flags; /* VMBUS_CHAN_FLAG_ */ + uint32_t ch_id; /* channel id */ + + /* + * These are based on the offer_msg.monitor_id. + * Save it here for easy access. + */ + int ch_montrig_idx; /* MNF trig index */ + uint32_t ch_montrig_mask;/* MNF trig mask */ + + /* + * TX bufring; at the beginning of ch_bufring. + */ + hv_vmbus_ring_buffer_info ch_txbr; + /* + * RX bufring; immediately following ch_txbr. + */ + hv_vmbus_ring_buffer_info ch_rxbr; + + struct taskqueue *ch_tq; + struct task ch_task; + vmbus_chan_callback_t ch_cb; + void *ch_cbarg; + + struct hyperv_mon_param *ch_monprm; + struct hyperv_dma ch_monprm_dma; + + int ch_cpuid; /* owner cpu */ + /* + * Virtual cpuid for ch_cpuid; it is used to communicate cpuid + * related information w/ Hyper-V. If MSR_HV_VP_INDEX does not + * exist, ch_vcpuid will always be 0 for compatibility. + */ + uint32_t ch_vcpuid; + + /* + * If this is a primary channel, ch_subchan* fields + * contain sub-channels belonging to this primary + * channel. + */ + struct mtx ch_subchan_lock; + TAILQ_HEAD(, hv_vmbus_channel) ch_subchans; + int ch_subchan_cnt; + + /* If this is a sub-channel */ + TAILQ_ENTRY(hv_vmbus_channel) ch_sublink; /* sub-channel link */ + struct hv_vmbus_channel *ch_prichan; /* owner primary chan */ + + void *ch_bufring; /* TX+RX bufrings */ + struct hyperv_dma ch_bufring_dma; + uint32_t ch_bufring_gpadl; + + struct task ch_detach_task; + TAILQ_ENTRY(hv_vmbus_channel) ch_prilink; /* primary chan link */ + uint32_t ch_subidx; /* subchan index */ + volatile uint32_t ch_stflags; /* atomic-op */ + /* VMBUS_CHAN_ST_ */ + struct hyperv_guid ch_guid_type; + struct hyperv_guid ch_guid_inst; + + struct sysctl_ctx_list ch_sysctl_ctx; +} hv_vmbus_channel; + +#define VMBUS_CHAN_ISPRIMARY(chan) ((chan)->ch_subidx == 0) + +#define VMBUS_CHAN_FLAG_HASMNF 0x0001 +/* + * If this flag is set, this channel's interrupt will be masked in ISR, + * and the RX bufring will be drained before this channel's interrupt is + * unmasked. + * + * This flag is turned on by default. Drivers can turn it off according + * to their own requirement. + */ +#define VMBUS_CHAN_FLAG_BATCHREAD 0x0002 + +#define VMBUS_CHAN_ST_OPENED_SHIFT 0 +#define VMBUS_CHAN_ST_OPENED (1 << VMBUS_CHAN_ST_OPENED_SHIFT) + +#endif /* !_VMBUS_CHANVAR_H_ */