hyperv/vmbus: Hide channel struct definition.

MFC after:	1 week
Sponsored by:	Microsoft OSTC
Differential Revision:	https://reviews.freebsd.org/D7245
This commit is contained in:
Sepherosa Ziehau 2016-07-20 06:00:27 +00:00
parent fda1c6ee42
commit 6254947245
9 changed files with 207 additions and 133 deletions

View File

@ -83,122 +83,8 @@ struct hyperv_guid {
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
*/

View File

@ -88,6 +88,9 @@ struct vmbus_chanpkt_rxbuf {
#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 @@ int vmbus_chan_send_prplist(struct hv_vmbus_channel *chan,
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_ */

View File

@ -641,9 +641,9 @@ hv_nv_disconnect_from_vsp(netvsc_dev *net_dev)
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 @@ hv_nv_on_device_add(struct hn_softc *sc, void *additional_info,
/*
* 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);

View File

@ -791,9 +791,8 @@ hn_tx_done(struct hv_vmbus_channel *chan, void *xpkt)
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 @@ hn_channel_attach(struct hn_softc *sc, struct hv_vmbus_channel *chan)
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 @@ hn_channel_attach(struct hn_softc *sc, struct hv_vmbus_channel *chan)
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 @@ hn_channel_attach(struct hn_softc *sc, struct hv_vmbus_channel *chan)
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 @@ static void
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 @@ hn_subchan_setup(struct hn_softc *sc)
/* 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 */

View File

@ -876,7 +876,7 @@ storvsc_create_cpu2chan(struct storvsc_softc *sc)
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]));
}
}
}

View File

@ -342,7 +342,8 @@ hv_kvp_convert_utf16_ipinfo_to_utf8(struct hv_kvp_ip_msg *host_ip_msg,
* 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 @@ static void
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;

View File

@ -37,7 +37,7 @@
#include <sys/sema.h>
#include <sys/_iovec.h>
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/vmbus/vmbus_chanvar.h>
struct vmbus_softc;

View File

@ -1378,3 +1378,30 @@ vmbus_chan_set_readbatch(struct hv_vmbus_channel *chan, bool on)
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;
}

View File

@ -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 <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/sysctl.h>
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/include/hyperv_busdma.h>
#include <dev/hyperv/include/vmbus.h>
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_ */