summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/hyperv/include/hyperv.h31
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.c148
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.h11
-rw-r--r--sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c53
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis_filter.c40
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis_filter.h11
-rw-r--r--sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c184
-rw-r--r--sys/dev/hyperv/utilities/hv_heartbeat.c10
-rw-r--r--sys/dev/hyperv/utilities/hv_kvp.c32
-rw-r--r--sys/dev/hyperv/utilities/hv_shutdown.c10
-rw-r--r--sys/dev/hyperv/utilities/hv_timesync.c10
-rw-r--r--sys/dev/hyperv/utilities/hv_util.c18
-rw-r--r--sys/dev/hyperv/utilities/hv_util.h2
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel.c4
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel_mgmt.c24
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_priv.h9
-rw-r--r--sys/dev/hyperv/vmbus/vmbus.c120
-rw-r--r--sys/dev/hyperv/vmbus/vmbus_if.m10
-rw-r--r--sys/modules/hyperv/utilities/Makefile2
19 files changed, 259 insertions, 470 deletions
diff --git a/sys/dev/hyperv/include/hyperv.h b/sys/dev/hyperv/include/hyperv.h
index 2ebc608..41d9f59 100644
--- a/sys/dev/hyperv/include/hyperv.h
+++ b/sys/dev/hyperv/include/hyperv.h
@@ -399,20 +399,6 @@ typedef struct {
#define HW_MACADDR_LEN 6
-enum {
- HV_VMBUS_IVAR_TYPE,
- HV_VMBUS_IVAR_INSTANCE,
- HV_VMBUS_IVAR_NODE,
- HV_VMBUS_IVAR_DEVCTX
-};
-
-#define HV_VMBUS_ACCESSOR(var, ivar, type) \
- __BUS_ACCESSOR(vmbus, var, HV_VMBUS, ivar, type)
-
-HV_VMBUS_ACCESSOR(type, TYPE, const char *)
-HV_VMBUS_ACCESSOR(devctx, DEVCTX, struct hv_device *)
-
-
/*
* Common defines for Hyper-V ICs
*/
@@ -534,7 +520,7 @@ typedef union {
} __packed hv_vmbus_connection_id;
typedef struct hv_vmbus_channel {
- struct hv_device* device;
+ device_t ch_dev;
struct vmbus_softc *vmbus_sc;
hv_vmbus_channel_state state;
uint32_t ch_flags; /* VMBUS_CHAN_FLAG_ */
@@ -647,15 +633,6 @@ hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t state)
channel->batched_reading = state;
}
-typedef struct hv_device {
- hv_guid class_id;
- hv_guid device_id;
- device_t device;
- hv_vmbus_channel* channel;
-} hv_device;
-
-
-
int hv_vmbus_channel_recv_packet(
hv_vmbus_channel* channel,
void* buffer,
@@ -737,4 +714,10 @@ hv_get_phys_addr(void *virt)
return (ret);
}
+static __inline struct hv_vmbus_channel *
+vmbus_get_channel(device_t dev)
+{
+ return device_get_ivars(dev);
+}
+
#endif /* __HYPERV_H__ */
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c
index a62f450..a3fe0e2 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -57,31 +57,30 @@ MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
* Forward declarations
*/
static void hv_nv_on_channel_callback(void *xchan);
-static int hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device);
-static int hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device);
+static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc);
+static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *);
static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
-static int hv_nv_connect_to_vsp(struct hv_device *device);
+static int hv_nv_connect_to_vsp(struct hn_softc *sc);
static void hv_nv_on_send_completion(netvsc_dev *net_dev,
- struct hv_device *device, struct hv_vmbus_channel *, hv_vm_packet_descriptor *pkt);
+ struct hv_vmbus_channel *, hv_vm_packet_descriptor *pkt);
static void hv_nv_on_receive_completion(struct hv_vmbus_channel *chan,
uint64_t tid, uint32_t status);
static void hv_nv_on_receive(netvsc_dev *net_dev,
- struct hv_device *device, struct hv_vmbus_channel *chan,
+ struct hn_softc *sc, struct hv_vmbus_channel *chan,
hv_vm_packet_descriptor *pkt);
/*
*
*/
static inline netvsc_dev *
-hv_nv_alloc_net_device(struct hv_device *device)
+hv_nv_alloc_net_device(struct hn_softc *sc)
{
netvsc_dev *net_dev;
- hn_softc_t *sc = device_get_softc(device->device);
net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO);
- net_dev->dev = device;
+ net_dev->sc = sc;
net_dev->destroy = FALSE;
sc->net_dev = net_dev;
@@ -89,43 +88,21 @@ hv_nv_alloc_net_device(struct hv_device *device)
}
/*
- *
+ * XXX unnecessary; nuke it.
*/
static inline netvsc_dev *
-hv_nv_get_outbound_net_device(struct hv_device *device)
+hv_nv_get_outbound_net_device(struct hn_softc *sc)
{
- hn_softc_t *sc = device_get_softc(device->device);
- netvsc_dev *net_dev = sc->net_dev;;
-
- if ((net_dev != NULL) && net_dev->destroy) {
- return (NULL);
- }
-
- return (net_dev);
+ return sc->net_dev;
}
/*
- *
+ * XXX unnecessary; nuke it.
*/
static inline netvsc_dev *
-hv_nv_get_inbound_net_device(struct hv_device *device)
+hv_nv_get_inbound_net_device(struct hn_softc *sc)
{
- hn_softc_t *sc = device_get_softc(device->device);
- netvsc_dev *net_dev = sc->net_dev;;
-
- if (net_dev == NULL) {
- return (net_dev);
- }
- /*
- * When the device is being destroyed; we only
- * permit incoming packets if and only if there
- * are outstanding sends.
- */
- if (net_dev->destroy) {
- return (NULL);
- }
-
- return (net_dev);
+ return sc->net_dev;
}
int
@@ -163,13 +140,13 @@ hv_nv_get_next_send_section(netvsc_dev *net_dev)
* Hyper-V extensible switch and the synthetic data path.
*/
static int
-hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device)
+hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
{
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
int ret = 0;
- net_dev = hv_nv_get_outbound_net_device(device);
+ net_dev = hv_nv_get_outbound_net_device(sc);
if (!net_dev) {
return (ENODEV);
}
@@ -184,7 +161,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device)
* GPADL: Guest physical address descriptor list.
*/
ret = hv_vmbus_channel_establish_gpadl(
- device->channel, net_dev->rx_buf,
+ sc->hn_prichan, net_dev->rx_buf,
net_dev->rx_buf_size, &net_dev->rx_buf_gpadl_handle);
if (ret != 0) {
goto cleanup;
@@ -205,7 +182,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device)
/* Send the gpadl notification request */
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -255,13 +232,13 @@ exit:
* Net VSC initialize send buffer with net VSP
*/
static int
-hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device)
+hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
{
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
int ret = 0;
- net_dev = hv_nv_get_outbound_net_device(device);
+ net_dev = hv_nv_get_outbound_net_device(sc);
if (!net_dev) {
return (ENODEV);
}
@@ -278,7 +255,7 @@ hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device)
* Note: This call uses the vmbus connection rather than the
* channel to establish the gpadl handle.
*/
- ret = hv_vmbus_channel_establish_gpadl(device->channel,
+ ret = hv_vmbus_channel_establish_gpadl(sc->hn_prichan,
net_dev->send_buf, net_dev->send_buf_size,
&net_dev->send_buf_gpadl_handle);
if (ret != 0) {
@@ -299,7 +276,7 @@ hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device)
/* Send the gpadl notification request */
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -359,7 +336,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id =
NETVSC_RECEIVE_BUFFER_ID;
- ret = hv_vmbus_channel_send_packet(net_dev->dev->channel,
+ ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan,
revoke_pkt, sizeof(nvsp_msg),
(uint64_t)(uintptr_t)revoke_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
@@ -375,7 +352,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
/* Tear down the gpadl on the vsp end */
if (net_dev->rx_buf_gpadl_handle) {
- ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel,
+ ret = hv_vmbus_channel_teardown_gpdal(net_dev->sc->hn_prichan,
net_dev->rx_buf_gpadl_handle);
/*
* If we failed here, we might as well return and have a leak
@@ -427,7 +404,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id =
NETVSC_SEND_BUFFER_ID;
- ret = hv_vmbus_channel_send_packet(net_dev->dev->channel,
+ ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan,
revoke_pkt, sizeof(nvsp_msg),
(uint64_t)(uintptr_t)revoke_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
@@ -442,7 +419,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
/* Tear down the gpadl on the vsp end */
if (net_dev->send_buf_gpadl_handle) {
- ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel,
+ ret = hv_vmbus_channel_teardown_gpdal(net_dev->sc->hn_prichan,
net_dev->send_buf_gpadl_handle);
/*
@@ -477,7 +454,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
* to the negotiated version, so we cannot rely on that.
*/
static int
-hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
+hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
uint32_t nvsp_ver)
{
nvsp_msg *init_pkt;
@@ -494,7 +471,7 @@ hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;
/* Send the init request */
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -515,13 +492,13 @@ hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
* Not valid for NDIS version 1.
*/
static int
-hv_nv_send_ndis_config(struct hv_device *device, uint32_t mtu)
+hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu)
{
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
int ret;
- net_dev = hv_nv_get_outbound_net_device(device);
+ net_dev = hv_nv_get_outbound_net_device(sc);
if (!net_dev)
return (-ENODEV);
@@ -538,7 +515,7 @@ hv_nv_send_ndis_config(struct hv_device *device, uint32_t mtu)
= 1;
/* Send the configuration packet */
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
if (ret != 0)
@@ -551,7 +528,7 @@ hv_nv_send_ndis_config(struct hv_device *device, uint32_t mtu)
* Net VSC connect to VSP
*/
static int
-hv_nv_connect_to_vsp(struct hv_device *device)
+hv_nv_connect_to_vsp(struct hn_softc *sc)
{
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
@@ -563,20 +540,16 @@ hv_nv_connect_to_vsp(struct hv_device *device)
int i;
int protocol_number = nitems(protocol_list);
int ret = 0;
- device_t dev = device->device;
- hn_softc_t *sc = device_get_softc(dev);
+ device_t dev = sc->hn_dev;
struct ifnet *ifp = sc->arpcom.ac_ifp;
- net_dev = hv_nv_get_outbound_net_device(device);
- if (!net_dev) {
- return (ENODEV);
- }
+ net_dev = hv_nv_get_outbound_net_device(sc);
/*
* Negotiate the NVSP version. Try the latest NVSP first.
*/
for (i = protocol_number - 1; i >= 0; i--) {
- if (hv_nv_negotiate_nvsp_protocol(device, net_dev,
+ if (hv_nv_negotiate_nvsp_protocol(sc, net_dev,
protocol_list[i]) == 0) {
net_dev->nvsp_version = protocol_list[i];
if (bootverbose)
@@ -598,7 +571,7 @@ hv_nv_connect_to_vsp(struct hv_device *device)
* This needs to be right after the NVSP init message per Haiyang
*/
if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
- ret = hv_nv_send_ndis_config(device, ifp->if_mtu);
+ ret = hv_nv_send_ndis_config(sc, ifp->if_mtu);
/*
* Send the NDIS version
@@ -621,7 +594,7 @@ hv_nv_connect_to_vsp(struct hv_device *device)
/* Send the init request */
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
if (ret != 0) {
@@ -642,9 +615,9 @@ hv_nv_connect_to_vsp(struct hv_device *device)
net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
- ret = hv_nv_init_rx_buffer_with_net_vsp(device);
+ ret = hv_nv_init_rx_buffer_with_net_vsp(sc);
if (ret == 0)
- ret = hv_nv_init_send_buffer_with_net_vsp(device);
+ ret = hv_nv_init_send_buffer_with_net_vsp(sc);
cleanup:
return (ret);
@@ -676,13 +649,13 @@ hv_nv_subchan_attach(struct hv_vmbus_channel *chan)
* Callback when the device belonging to this driver is added
*/
netvsc_dev *
-hv_nv_on_device_add(struct hv_device *device, void *additional_info)
+hv_nv_on_device_add(struct hn_softc *sc, void *additional_info)
{
- struct hv_vmbus_channel *chan = device->channel;
+ struct hv_vmbus_channel *chan = sc->hn_prichan;
netvsc_dev *net_dev;
int ret = 0;
- net_dev = hv_nv_alloc_net_device(device);
+ net_dev = hv_nv_alloc_net_device(sc);
if (net_dev == NULL)
return NULL;
@@ -706,7 +679,7 @@ hv_nv_on_device_add(struct hv_device *device, void *additional_info)
/*
* Connect with the NetVsp
*/
- ret = hv_nv_connect_to_vsp(device);
+ ret = hv_nv_connect_to_vsp(sc);
if (ret != 0)
goto close;
@@ -732,9 +705,8 @@ cleanup:
* Net VSC on device remove
*/
int
-hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
+hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
{
- hn_softc_t *sc = device_get_softc(device->device);
netvsc_dev *net_dev = sc->net_dev;;
/* Stop outbound traffic ie sends and receives completions */
@@ -747,12 +719,12 @@ hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
/* Now, we can close the channel safely */
if (!destroy_channel) {
- device->channel->state =
+ sc->hn_prichan->state =
HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE;
}
- free(device->channel->hv_chan_rdbuf, M_NETVSC);
- hv_vmbus_channel_close(device->channel);
+ free(sc->hn_prichan->hv_chan_rdbuf, M_NETVSC);
+ hv_vmbus_channel_close(sc->hn_prichan);
sema_destroy(&net_dev->channel_init_sema);
free(net_dev, M_NETVSC);
@@ -764,8 +736,7 @@ hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
* Net VSC on send completion
*/
static void
-hv_nv_on_send_completion(netvsc_dev *net_dev,
- struct hv_device *device, struct hv_vmbus_channel *chan,
+hv_nv_on_send_completion(netvsc_dev *net_dev, struct hv_vmbus_channel *chan,
hv_vm_packet_descriptor *pkt)
{
nvsp_msg *nvsp_msg_pkt;
@@ -870,14 +841,14 @@ hv_nv_on_send(struct hv_vmbus_channel *chan, netvsc_packet *pkt)
* with virtual addresses.
*/
static void
-hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device,
+hv_nv_on_receive(netvsc_dev *net_dev, struct hn_softc *sc,
struct hv_vmbus_channel *chan, hv_vm_packet_descriptor *pkt)
{
hv_vm_transfer_page_packet_header *vm_xfer_page_pkt;
nvsp_msg *nvsp_msg_pkt;
netvsc_packet vsc_pkt;
netvsc_packet *net_vsc_pkt = &vsc_pkt;
- device_t dev = device->device;
+ device_t dev = sc->hn_dev;
int count = 0;
int i = 0;
int status = nvsp_status_success;
@@ -911,7 +882,6 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device,
}
count = vm_xfer_page_pkt->range_count;
- net_vsc_pkt->device = device;
/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
for (i = 0; i < count; i++) {
@@ -921,7 +891,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device,
net_vsc_pkt->tot_data_buf_len =
vm_xfer_page_pkt->ranges[i].byte_count;
- hv_rf_on_receive(net_dev, device, chan, net_vsc_pkt);
+ hv_rf_on_receive(net_dev, chan, net_vsc_pkt);
if (net_vsc_pkt->status != nvsp_status_success) {
status = nvsp_status_failure;
}
@@ -977,14 +947,14 @@ retry_send_cmplt:
* Net VSC receiving vRSS send table from VSP
*/
static void
-hv_nv_send_table(struct hv_device *device, hv_vm_packet_descriptor *pkt)
+hv_nv_send_table(struct hn_softc *sc, hv_vm_packet_descriptor *pkt)
{
netvsc_dev *net_dev;
nvsp_msg *nvsp_msg_pkt;
int i;
uint32_t count, *table;
- net_dev = hv_nv_get_inbound_net_device(device);
+ net_dev = hv_nv_get_inbound_net_device(sc);
if (!net_dev)
return;
@@ -1020,9 +990,9 @@ static void
hv_nv_on_channel_callback(void *xchan)
{
struct hv_vmbus_channel *chan = xchan;
- struct hv_device *device = chan->device;
+ device_t dev = chan->ch_dev;
+ struct hn_softc *sc = device_get_softc(dev);
netvsc_dev *net_dev;
- device_t dev = device->device;
uint32_t bytes_rxed;
uint64_t request_id;
hv_vm_packet_descriptor *desc;
@@ -1030,7 +1000,7 @@ hv_nv_on_channel_callback(void *xchan)
int bufferlen = NETVSC_PACKET_SIZE;
int ret = 0;
- net_dev = hv_nv_get_inbound_net_device(device);
+ net_dev = hv_nv_get_inbound_net_device(sc);
if (net_dev == NULL)
return;
@@ -1044,14 +1014,14 @@ hv_nv_on_channel_callback(void *xchan)
desc = (hv_vm_packet_descriptor *)buffer;
switch (desc->type) {
case HV_VMBUS_PACKET_TYPE_COMPLETION:
- hv_nv_on_send_completion(net_dev, device,
- chan, desc);
+ hv_nv_on_send_completion(net_dev, chan,
+ desc);
break;
case HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES:
- hv_nv_on_receive(net_dev, device, chan, desc);
+ hv_nv_on_receive(net_dev, sc, chan, desc);
break;
case HV_VMBUS_PACKET_TYPE_DATA_IN_BAND:
- hv_nv_send_table(device, desc);
+ hv_nv_send_table(sc, desc);
break;
default:
device_printf(dev,
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h
index 7c43f64..b41dced 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h
@@ -1040,7 +1040,7 @@ typedef struct nvsp_msg_ {
* Per netvsc channel-specific
*/
typedef struct netvsc_dev_ {
- struct hv_device *dev;
+ struct hn_softc *sc;
/* Send buffer allocated by us but manages by NetVSP */
void *send_buf;
@@ -1107,7 +1107,6 @@ typedef void (*pfn_on_send_rx_completion)(struct hv_vmbus_channel *, void *);
#endif
typedef struct netvsc_packet_ {
- struct hv_device *device;
hv_bool_uint8_t is_data_pkt; /* One byte */
uint16_t vlan_tci;
uint32_t status;
@@ -1240,8 +1239,8 @@ typedef struct hn_softc {
int hn_initdone;
/* See hv_netvsc_drv_freebsd.c for rules on how to use */
int temp_unusable;
- struct hv_device *hn_dev_obj;
netvsc_dev *net_dev;
+ struct hv_vmbus_channel *hn_prichan;
int hn_rx_ring_cnt;
int hn_rx_ring_inuse;
@@ -1263,10 +1262,10 @@ typedef struct hn_softc {
*/
extern int hv_promisc_mode;
-void netvsc_linkstatus_callback(struct hv_device *device_obj, uint32_t status);
-netvsc_dev *hv_nv_on_device_add(struct hv_device *device,
+void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status);
+netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc,
void *additional_info);
-int hv_nv_on_device_remove(struct hv_device *device,
+int hv_nv_on_device_remove(struct hn_softc *sc,
boolean_t destroy_channel);
int hv_nv_on_send(struct hv_vmbus_channel *chan, netvsc_packet *pkt);
int hv_nv_get_next_send_section(netvsc_dev *net_dev);
diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
index 8f1e1e7..f8b68cb 100644
--- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -415,18 +415,12 @@ static const hv_guid g_net_vsc_device_type = {
static int
netvsc_probe(device_t dev)
{
- const char *p;
-
- p = vmbus_get_type(dev);
- if (!memcmp(p, &g_net_vsc_device_type.data, sizeof(hv_guid))) {
+ if (VMBUS_PROBE_GUID(device_get_parent(dev), dev,
+ &g_net_vsc_device_type) == 0) {
device_set_desc(dev, "Hyper-V Network Interface");
- if (bootverbose)
- printf("Netvsc probe... DONE \n");
-
- return (BUS_PROBE_DEFAULT);
+ return BUS_PROBE_DEFAULT;
}
-
- return (ENXIO);
+ return ENXIO;
}
static void
@@ -451,8 +445,6 @@ hn_cpuset_setthread_task(void *xmask, int pending __unused)
static int
netvsc_attach(device_t dev)
{
- struct hv_device *device_ctx = vmbus_get_devctx(dev);
- struct hv_vmbus_channel *pri_chan;
netvsc_device_info device_info;
hn_softc_t *sc;
int unit = device_get_unit(dev);
@@ -464,6 +456,7 @@ netvsc_attach(device_t dev)
sc->hn_unit = unit;
sc->hn_dev = dev;
+ sc->hn_prichan = vmbus_get_channel(dev);
if (hn_tx_taskq == NULL) {
sc->hn_tx_taskq = taskqueue_create("hn_tx", M_WAITOK,
@@ -488,8 +481,6 @@ netvsc_attach(device_t dev)
}
NV_LOCK_INIT(sc, "NetVSCLock");
- sc->hn_dev_obj = device_ctx;
-
ifp = sc->hn_ifp = sc->arpcom.ac_ifp = if_alloc(IFT_ETHER);
ifp->if_softc = sc;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
@@ -532,12 +523,7 @@ netvsc_attach(device_t dev)
/*
* Associate the first TX/RX ring w/ the primary channel.
*/
- pri_chan = device_ctx->channel;
- KASSERT(HV_VMBUS_CHAN_ISPRIMARY(pri_chan), ("not primary channel"));
- KASSERT(pri_chan->ch_subidx == 0,
- ("primary channel subidx %u",
- pri_chan->ch_subidx));
- hn_channel_attach(sc, pri_chan);
+ hn_channel_attach(sc, sc->hn_prichan);
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = hn_ioctl;
@@ -574,7 +560,7 @@ netvsc_attach(device_t dev)
IFCAP_LRO;
ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO;
- error = hv_rf_on_device_add(device_ctx, &device_info, ring_cnt);
+ error = hv_rf_on_device_add(sc, &device_info, ring_cnt);
if (error)
goto failed;
KASSERT(sc->net_dev->num_channel > 0 &&
@@ -644,7 +630,6 @@ static int
netvsc_detach(device_t dev)
{
struct hn_softc *sc = device_get_softc(dev);
- struct hv_device *hv_device = vmbus_get_devctx(dev);
if (bootverbose)
printf("netvsc_detach\n");
@@ -660,7 +645,7 @@ netvsc_detach(device_t dev)
* the netdevice.
*/
- hv_rf_on_device_remove(hv_device, HV_RF_NV_DESTROY_CHANNEL);
+ hv_rf_on_device_remove(sc, HV_RF_NV_DESTROY_CHANNEL);
hn_stop_tx_tasks(sc);
@@ -1224,10 +1209,8 @@ hn_start_locked(struct hn_tx_ring *txr, int len)
* Link up/down notification
*/
void
-netvsc_linkstatus_callback(struct hv_device *device_obj, uint32_t status)
+netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status)
{
- hn_softc_t *sc = device_get_softc(device_obj->device);
-
if (status == 1) {
sc->hn_carrier = 1;
} else {
@@ -1548,7 +1531,6 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
struct ifaddr *ifa = (struct ifaddr *)data;
#endif
netvsc_device_info device_info;
- struct hv_device *hn_dev;
int mask, error = 0;
int retry_cnt = 500;
@@ -1566,8 +1548,6 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ether_ioctl(ifp, cmd, data);
break;
case SIOCSIFMTU:
- hn_dev = vmbus_get_devctx(sc->hn_dev);
-
/* Check MTU value change */
if (ifp->if_mtu == ifr->ifr_mtu)
break;
@@ -1614,7 +1594,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
* MTU to take effect. This includes tearing down, but not
* deleting the channel, then bringing it back up.
*/
- error = hv_rf_on_device_remove(hn_dev, HV_RF_NV_RETAIN_CHANNEL);
+ error = hv_rf_on_device_remove(sc, HV_RF_NV_RETAIN_CHANNEL);
if (error) {
NV_LOCK(sc);
sc->temp_unusable = FALSE;
@@ -1623,9 +1603,9 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
/* Wait for subchannels to be destroyed */
- vmbus_drain_subchan(hn_dev->channel);
+ vmbus_drain_subchan(sc->hn_prichan);
- error = hv_rf_on_device_add(hn_dev, &device_info,
+ error = hv_rf_on_device_add(sc, &device_info,
sc->hn_rx_ring_inuse);
if (error) {
NV_LOCK(sc);
@@ -1790,7 +1770,6 @@ hn_stop(hn_softc_t *sc)
{
struct ifnet *ifp;
int ret, i;
- struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
ifp = sc->hn_ifp;
@@ -1805,7 +1784,7 @@ hn_stop(hn_softc_t *sc)
if_link_state_change(ifp, LINK_STATE_DOWN);
sc->hn_initdone = 0;
- ret = hv_rf_on_close(device_ctx);
+ ret = hv_rf_on_close(sc);
}
/*
@@ -1873,7 +1852,6 @@ static void
hn_ifinit_locked(hn_softc_t *sc)
{
struct ifnet *ifp;
- struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
int ret, i;
ifp = sc->hn_ifp;
@@ -1884,7 +1862,7 @@ hn_ifinit_locked(hn_softc_t *sc)
hv_promisc_mode = 1;
- ret = hv_rf_on_open(device_ctx);
+ ret = hv_rf_on_open(sc);
if (ret != 0) {
return;
} else {
@@ -3046,13 +3024,12 @@ hn_subchan_attach(struct hn_softc *sc, struct hv_vmbus_channel *chan)
static void
hn_subchan_setup(struct hn_softc *sc)
{
- struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
struct hv_vmbus_channel **subchan;
int subchan_cnt = sc->net_dev->num_channel - 1;
int i;
/* Wait for sub-channels setup to complete. */
- subchan = vmbus_get_subchan(device_ctx->channel, subchan_cnt);
+ subchan = vmbus_get_subchan(sc->hn_prichan, subchan_cnt);
/* Attach the sub-channels. */
for (i = 0; i < subchan_cnt; ++i) {
diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
index 8e95510..3e2c9d9 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c
+++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
@@ -89,7 +89,7 @@ static int hv_rf_close_device(rndis_device *device);
static void hv_rf_on_send_request_completion(struct hv_vmbus_channel *, void *context);
static void hv_rf_on_send_request_halt_completion(struct hv_vmbus_channel *, void *context);
int
-hv_rf_send_offload_request(struct hv_device *device,
+hv_rf_send_offload_request(struct hn_softc *sc,
rndis_offload_params *offloads);
/*
* Set the Per-Packet-Info with the specified type
@@ -299,7 +299,7 @@ hv_rf_send_request(rndis_device *device, rndis_request *request,
packet->send_buf_section_size = 0;
sendit:
- ret = hv_nv_on_send(device->net_dev->dev->channel, packet);
+ ret = hv_nv_on_send(device->net_dev->sc->hn_prichan, packet);
return (ret);
}
@@ -351,7 +351,7 @@ hv_rf_receive_response(rndis_device *device, rndis_msg *response)
}
int
-hv_rf_send_offload_request(struct hv_device *device,
+hv_rf_send_offload_request(struct hn_softc *sc,
rndis_offload_params *offloads)
{
rndis_request *request;
@@ -359,8 +359,7 @@ hv_rf_send_offload_request(struct hv_device *device,
rndis_offload_params *offload_req;
rndis_set_complete *set_complete;
rndis_device *rndis_dev;
- hn_softc_t *sc = device_get_softc(device->device);
- device_t dev = device->device;
+ device_t dev = sc->hn_dev;
netvsc_dev *net_dev = sc->net_dev;
uint32_t vsp_version = net_dev->nvsp_version;
uint32_t extlen = sizeof(rndis_offload_params);
@@ -437,14 +436,14 @@ hv_rf_receive_indicate_status(rndis_device *device, rndis_msg *response)
switch(indicate->status) {
case RNDIS_STATUS_MEDIA_CONNECT:
- netvsc_linkstatus_callback(device->net_dev->dev, 1);
+ netvsc_linkstatus_callback(device->net_dev->sc, 1);
break;
case RNDIS_STATUS_MEDIA_DISCONNECT:
- netvsc_linkstatus_callback(device->net_dev->dev, 0);
+ netvsc_linkstatus_callback(device->net_dev->sc, 0);
break;
default:
/* TODO: */
- device_printf(device->net_dev->dev->device,
+ device_printf(device->net_dev->sc->hn_dev,
"unknown status %d received\n", indicate->status);
break;
}
@@ -537,7 +536,7 @@ hv_rf_receive_data(rndis_device *device, rndis_msg *message,
{
rndis_packet *rndis_pkt;
uint32_t data_offset;
- device_t dev = device->net_dev->dev->device;
+ device_t dev = device->net_dev->sc->hn_dev;
struct hv_rf_recvinfo info;
rndis_pkt = &message->msg.packet;
@@ -580,7 +579,7 @@ hv_rf_receive_data(rndis_device *device, rndis_msg *message,
* RNDIS filter on receive
*/
int
-hv_rf_on_receive(netvsc_dev *net_dev, struct hv_device *device,
+hv_rf_on_receive(netvsc_dev *net_dev,
struct hv_vmbus_channel *chan, netvsc_packet *pkt)
{
rndis_device *rndis_dev;
@@ -1062,7 +1061,7 @@ hv_rf_close_device(rndis_device *device)
* RNDIS filter on device add
*/
int
-hv_rf_on_device_add(struct hv_device *device, void *additl_info,
+hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
int nchan)
{
int ret;
@@ -1073,7 +1072,7 @@ hv_rf_on_device_add(struct hv_device *device, void *additl_info,
struct rndis_recv_scale_cap rsscaps;
uint32_t rsscaps_size = sizeof(struct rndis_recv_scale_cap);
netvsc_device_info *dev_info = (netvsc_device_info *)additl_info;
- device_t dev = device->device;
+ device_t dev = sc->hn_dev;
rndis_dev = hv_get_rndis_device();
if (rndis_dev == NULL) {
@@ -1086,7 +1085,7 @@ hv_rf_on_device_add(struct hv_device *device, void *additl_info,
* (hv_rf_on_receive()) before this call is completed.
* Note: Earlier code used a function pointer here.
*/
- net_dev = hv_nv_on_device_add(device, additl_info);
+ net_dev = hv_nv_on_device_add(sc, additl_info);
if (!net_dev) {
hv_put_rndis_device(rndis_dev);
@@ -1124,7 +1123,7 @@ hv_rf_on_device_add(struct hv_device *device, void *additl_info,
offloads.udp_ipv6_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
offloads.lso_v2_ipv4 = RNDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
- ret = hv_rf_send_offload_request(device, &offloads);
+ ret = hv_rf_send_offload_request(sc, &offloads);
if (ret != 0) {
/* TODO: shut down rndis device and the channel */
device_printf(dev,
@@ -1171,7 +1170,7 @@ hv_rf_on_device_add(struct hv_device *device, void *additl_info,
init_pkt->msgs.vers_5_msgs.subchannel_request.num_subchannels =
net_dev->num_channel - 1;
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -1205,9 +1204,8 @@ out:
* RNDIS filter on device remove
*/
int
-hv_rf_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
+hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
{
- hn_softc_t *sc = device_get_softc(device->device);
netvsc_dev *net_dev = sc->net_dev;
rndis_device *rndis_dev = (rndis_device *)net_dev->extension;
int ret;
@@ -1219,7 +1217,7 @@ hv_rf_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
net_dev->extension = NULL;
/* Pass control to inner driver to remove the device */
- ret |= hv_nv_on_device_remove(device, destroy_channel);
+ ret |= hv_nv_on_device_remove(sc, destroy_channel);
return (ret);
}
@@ -1228,9 +1226,8 @@ hv_rf_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
* RNDIS filter on open
*/
int
-hv_rf_on_open(struct hv_device *device)
+hv_rf_on_open(struct hn_softc *sc)
{
- hn_softc_t *sc = device_get_softc(device->device);
netvsc_dev *net_dev = sc->net_dev;
return (hv_rf_open_device((rndis_device *)net_dev->extension));
@@ -1240,9 +1237,8 @@ hv_rf_on_open(struct hv_device *device)
* RNDIS filter on close
*/
int
-hv_rf_on_close(struct hv_device *device)
+hv_rf_on_close(struct hn_softc *sc)
{
- hn_softc_t *sc = device_get_softc(device->device);
netvsc_dev *net_dev = sc->net_dev;
return (hv_rf_close_device((rndis_device *)net_dev->extension));
diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.h b/sys/dev/hyperv/netvsc/hv_rndis_filter.h
index dbaaa42..2d97a09 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis_filter.h
+++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.h
@@ -111,15 +111,16 @@ typedef struct rndis_device_ {
* Externs
*/
struct hv_vmbus_channel;
+struct hn_softc;
-int hv_rf_on_receive(netvsc_dev *net_dev, struct hv_device *device,
+int hv_rf_on_receive(netvsc_dev *net_dev,
struct hv_vmbus_channel *chan, netvsc_packet *pkt);
void hv_rf_receive_rollup(netvsc_dev *net_dev);
void hv_rf_channel_rollup(struct hv_vmbus_channel *chan);
-int hv_rf_on_device_add(struct hv_device *device, void *additl_info, int nchan);
-int hv_rf_on_device_remove(struct hv_device *device, boolean_t destroy_channel);
-int hv_rf_on_open(struct hv_device *device);
-int hv_rf_on_close(struct hv_device *device);
+int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int nchan);
+int hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel);
+int hv_rf_on_open(struct hn_softc *sc);
+int hv_rf_on_close(struct hn_softc *sc);
#endif /* __HV_RNDIS_FILTER_H__ */
diff --git a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
index fea4bfb..cae239e 100644
--- a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
@@ -125,7 +125,7 @@ struct hv_storvsc_request {
};
struct storvsc_softc {
- struct hv_device *hs_dev;
+ struct hv_vmbus_channel *hs_chan;
LIST_HEAD(, hv_storvsc_request) hs_free_list;
struct mtx hs_lock;
struct storvsc_driver_props *hs_drv_props;
@@ -139,6 +139,7 @@ struct storvsc_softc {
struct sema hs_drain_sema;
struct hv_storvsc_request hs_init_req;
struct hv_storvsc_request hs_reset_req;
+ device_t hs_dev;
};
@@ -264,11 +265,11 @@ static int create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *req
static void storvsc_free_request(struct storvsc_softc *sc, struct hv_storvsc_request *reqp);
static enum hv_storage_type storvsc_get_storage_type(device_t dev);
static void hv_storvsc_rescan_target(struct storvsc_softc *sc);
-static void hv_storvsc_on_channel_callback(void *context);
+static void hv_storvsc_on_channel_callback(void *xchan);
static void hv_storvsc_on_iocompletion( struct storvsc_softc *sc,
struct vstor_packet *vstor_packet,
struct hv_storvsc_request *request);
-static int hv_storvsc_connect_vsp(struct hv_device *device);
+static int hv_storvsc_connect_vsp(struct storvsc_softc *);
static void storvsc_io_done(struct hv_storvsc_request *reqp);
static void storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl,
bus_dma_segment_t *orig_sgl,
@@ -297,72 +298,16 @@ DRIVER_MODULE(storvsc, vmbus, storvsc_driver, storvsc_devclass, 0, 0);
MODULE_VERSION(storvsc, 1);
MODULE_DEPEND(storvsc, vmbus, 1, 1, 1);
-
-/**
- * The host is capable of sending messages to us that are
- * completely unsolicited. So, we need to address the race
- * condition where we may be in the process of unloading the
- * driver when the host may send us an unsolicited message.
- * We address this issue by implementing a sequentially
- * consistent protocol:
- *
- * 1. Channel callback is invoked while holding the the channel lock
- * and an unloading driver will reset the channel callback under
- * the protection of this channel lock.
- *
- * 2. To ensure bounded wait time for unloading a driver, we don't
- * permit outgoing traffic once the device is marked as being
- * destroyed.
- *
- * 3. Once the device is marked as being destroyed, we only
- * permit incoming traffic to properly account for
- * packets already sent out.
- */
-static inline struct storvsc_softc *
-get_stor_device(struct hv_device *device,
- boolean_t outbound)
-{
- struct storvsc_softc *sc;
-
- sc = device_get_softc(device->device);
-
- if (outbound) {
- /*
- * Here we permit outgoing I/O only
- * if the device is not being destroyed.
- */
-
- if (sc->hs_destroy) {
- sc = NULL;
- }
- } else {
- /*
- * inbound case; if being destroyed
- * only permit to account for
- * messages already sent out.
- */
- if (sc->hs_destroy && (sc->hs_num_out_reqs == 0)) {
- sc = NULL;
- }
- }
- return sc;
-}
-
static void
-storvsc_subchan_attach(struct hv_vmbus_channel *new_channel)
+storvsc_subchan_attach(struct storvsc_softc *sc,
+ struct hv_vmbus_channel *new_channel)
{
- struct hv_device *device;
- struct storvsc_softc *sc;
struct vmstor_chan_props props;
int ret = 0;
- device = new_channel->device;
- sc = get_stor_device(device, TRUE);
- if (sc == NULL)
- return;
-
memset(&props, 0, sizeof(props));
+ new_channel->hv_chan_priv1 = sc;
vmbus_channel_cpu_rr(new_channel);
ret = hv_vmbus_channel_open(new_channel,
sc->hs_drv_props->drv_ringbuffer_size,
@@ -371,8 +316,6 @@ storvsc_subchan_attach(struct hv_vmbus_channel *new_channel)
sizeof(struct vmstor_chan_props),
hv_storvsc_on_channel_callback,
new_channel);
-
- return;
}
/**
@@ -382,10 +325,9 @@ storvsc_subchan_attach(struct hv_vmbus_channel *new_channel)
* @param max_chans the max channels supported by vmbus
*/
static void
-storvsc_send_multichannel_request(struct hv_device *dev, int max_chans)
+storvsc_send_multichannel_request(struct storvsc_softc *sc, int max_chans)
{
struct hv_vmbus_channel **subchan;
- struct storvsc_softc *sc;
struct hv_storvsc_request *request;
struct vstor_packet *vstor_packet;
int request_channels_cnt = 0;
@@ -394,13 +336,6 @@ storvsc_send_multichannel_request(struct hv_device *dev, int max_chans)
/* get multichannels count that need to create */
request_channels_cnt = MIN(max_chans, mp_ncpus);
- sc = get_stor_device(dev, TRUE);
- if (sc == NULL) {
- printf("Storvsc_error: get sc failed while send mutilchannel "
- "request\n");
- return;
- }
-
request = &sc->hs_init_req;
/* request the host to create multi-channel */
@@ -415,7 +350,7 @@ storvsc_send_multichannel_request(struct hv_device *dev, int max_chans)
vstor_packet->u.multi_channels_cnt = request_channels_cnt;
ret = hv_vmbus_channel_send_packet(
- dev->channel,
+ sc->hs_chan,
vstor_packet,
VSTOR_PKT_SIZE,
(uint64_t)(uintptr_t)request,
@@ -439,11 +374,11 @@ storvsc_send_multichannel_request(struct hv_device *dev, int max_chans)
}
/* Wait for sub-channels setup to complete. */
- subchan = vmbus_get_subchan(dev->channel, request_channels_cnt);
+ subchan = vmbus_get_subchan(sc->hs_chan, request_channels_cnt);
/* Attach the sub-channels. */
for (i = 0; i < request_channels_cnt; ++i)
- storvsc_subchan_attach(subchan[i]);
+ storvsc_subchan_attach(sc, subchan[i]);
/* Release the sub-channels. */
vmbus_rel_subchan(subchan, request_channels_cnt);
@@ -459,12 +394,11 @@ storvsc_send_multichannel_request(struct hv_device *dev, int max_chans)
* @returns 0 on success, non-zero error on failure
*/
static int
-hv_storvsc_channel_init(struct hv_device *dev)
+hv_storvsc_channel_init(struct storvsc_softc *sc)
{
int ret = 0, i;
struct hv_storvsc_request *request;
struct vstor_packet *vstor_packet;
- struct storvsc_softc *sc;
uint16_t max_chans = 0;
boolean_t support_multichannel = FALSE;
uint32_t version;
@@ -472,10 +406,6 @@ hv_storvsc_channel_init(struct hv_device *dev)
max_chans = 0;
support_multichannel = FALSE;
- sc = get_stor_device(dev, TRUE);
- if (sc == NULL)
- return (ENODEV);
-
request = &sc->hs_init_req;
memset(request, 0, sizeof(struct hv_storvsc_request));
vstor_packet = &request->vstor_packet;
@@ -491,7 +421,7 @@ hv_storvsc_channel_init(struct hv_device *dev)
ret = hv_vmbus_channel_send_packet(
- dev->channel,
+ sc->hs_chan,
vstor_packet,
VSTOR_PKT_SIZE,
(uint64_t)(uintptr_t)request,
@@ -525,7 +455,7 @@ hv_storvsc_channel_init(struct hv_device *dev)
vstor_packet->u.version.revision = 0;
ret = hv_vmbus_channel_send_packet(
- dev->channel,
+ sc->hs_chan,
vstor_packet,
VSTOR_PKT_SIZE,
(uint64_t)(uintptr_t)request,
@@ -568,7 +498,7 @@ hv_storvsc_channel_init(struct hv_device *dev)
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
ret = hv_vmbus_channel_send_packet(
- dev->channel,
+ sc->hs_chan,
vstor_packet,
VSTOR_PKT_SIZE,
(uint64_t)(uintptr_t)request,
@@ -592,8 +522,7 @@ hv_storvsc_channel_init(struct hv_device *dev)
/* multi-channels feature is supported by WIN8 and above version */
max_chans = vstor_packet->u.chan_props.max_channel_cnt;
- version = VMBUS_GET_VERSION(device_get_parent(dev->device),
- dev->device);
+ version = VMBUS_GET_VERSION(device_get_parent(sc->hs_dev), sc->hs_dev);
if (version != VMBUS_VERSION_WIN7 && version != VMBUS_VERSION_WS2008 &&
(vstor_packet->u.chan_props.flags &
HV_STORAGE_SUPPORTS_MULTI_CHANNEL)) {
@@ -605,7 +534,7 @@ hv_storvsc_channel_init(struct hv_device *dev)
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
ret = hv_vmbus_channel_send_packet(
- dev->channel,
+ sc->hs_chan,
vstor_packet,
VSTOR_PKT_SIZE,
(uint64_t)(uintptr_t)request,
@@ -631,7 +560,7 @@ hv_storvsc_channel_init(struct hv_device *dev)
* request to host.
*/
if (support_multichannel)
- storvsc_send_multichannel_request(dev, max_chans);
+ storvsc_send_multichannel_request(sc, max_chans);
cleanup:
sema_destroy(&request->synch_sema);
@@ -647,53 +576,45 @@ cleanup:
* @returns 0 on success, non-zero error on failure
*/
static int
-hv_storvsc_connect_vsp(struct hv_device *dev)
+hv_storvsc_connect_vsp(struct storvsc_softc *sc)
{
int ret = 0;
struct vmstor_chan_props props;
- struct storvsc_softc *sc;
- sc = device_get_softc(dev->device);
-
memset(&props, 0, sizeof(struct vmstor_chan_props));
/*
* Open the channel
*/
- vmbus_channel_cpu_rr(dev->channel);
+ KASSERT(sc->hs_chan->hv_chan_priv1 == sc, ("invalid chan priv1"));
+ vmbus_channel_cpu_rr(sc->hs_chan);
ret = hv_vmbus_channel_open(
- dev->channel,
+ sc->hs_chan,
sc->hs_drv_props->drv_ringbuffer_size,
sc->hs_drv_props->drv_ringbuffer_size,
(void *)&props,
sizeof(struct vmstor_chan_props),
hv_storvsc_on_channel_callback,
- dev->channel);
+ sc->hs_chan);
if (ret != 0) {
return ret;
}
- ret = hv_storvsc_channel_init(dev);
+ ret = hv_storvsc_channel_init(sc);
return (ret);
}
#if HVS_HOST_RESET
static int
-hv_storvsc_host_reset(struct hv_device *dev)
+hv_storvsc_host_reset(struct storvsc_softc *sc)
{
int ret = 0;
- struct storvsc_softc *sc;
struct hv_storvsc_request *request;
struct vstor_packet *vstor_packet;
- sc = get_stor_device(dev, TRUE);
- if (sc == NULL) {
- return ENODEV;
- }
-
request = &sc->hs_reset_req;
request->softc = sc;
vstor_packet = &request->vstor_packet;
@@ -740,20 +661,13 @@ cleanup:
* @returns 0 on success, non-zero error on failure
*/
static int
-hv_storvsc_io_request(struct hv_device *device,
+hv_storvsc_io_request(struct storvsc_softc *sc,
struct hv_storvsc_request *request)
{
- struct storvsc_softc *sc;
struct vstor_packet *vstor_packet = &request->vstor_packet;
struct hv_vmbus_channel* outgoing_channel = NULL;
int ret = 0;
- sc = get_stor_device(device, TRUE);
-
- if (sc == NULL) {
- return ENODEV;
- }
-
vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
vstor_packet->u.vm_srb.length =
@@ -765,7 +679,7 @@ hv_storvsc_io_request(struct hv_device *device,
vstor_packet->operation = VSTOR_OPERATION_EXECUTESRB;
- outgoing_channel = vmbus_select_outgoing_channel(device->channel);
+ outgoing_channel = vmbus_select_outgoing_channel(sc->hs_chan);
mtx_unlock(&request->softc->hs_lock);
if (request->data_buf.length) {
@@ -877,27 +791,17 @@ hv_storvsc_rescan_target(struct storvsc_softc *sc)
}
static void
-hv_storvsc_on_channel_callback(void *context)
+hv_storvsc_on_channel_callback(void *xchan)
{
int ret = 0;
- hv_vmbus_channel *channel = (hv_vmbus_channel *)context;
- struct hv_device *device = NULL;
- struct storvsc_softc *sc;
+ hv_vmbus_channel *channel = xchan;
+ struct storvsc_softc *sc = channel->hv_chan_priv1;
uint32_t bytes_recvd;
uint64_t request_id;
uint8_t packet[roundup2(sizeof(struct vstor_packet), 8)];
struct hv_storvsc_request *request;
struct vstor_packet *vstor_packet;
- device = channel->device;
- KASSERT(device, ("device is NULL"));
-
- sc = get_stor_device(device, FALSE);
- if (sc == NULL) {
- printf("Storvsc_error: get stor device failed.\n");
- return;
- }
-
ret = hv_vmbus_channel_recv_packet(
channel,
packet,
@@ -1001,7 +905,6 @@ storvsc_probe(device_t dev)
static int
storvsc_attach(device_t dev)
{
- struct hv_device *hv_dev = vmbus_get_devctx(dev);
enum hv_storage_type stor_type;
struct storvsc_softc *sc;
struct cam_devq *devq;
@@ -1017,6 +920,8 @@ storvsc_attach(device_t dev)
root_mount_token = root_mount_hold("storvsc");
sc = device_get_softc(dev);
+ sc->hs_chan = vmbus_get_channel(dev);
+ sc->hs_chan->hv_chan_priv1 = sc;
stor_type = storvsc_get_storage_type(dev);
@@ -1030,7 +935,7 @@ storvsc_attach(device_t dev)
/* fill in device specific properties */
sc->hs_unit = device_get_unit(dev);
- sc->hs_dev = hv_dev;
+ sc->hs_dev = dev;
LIST_INIT(&sc->hs_free_list);
mtx_init(&sc->hs_lock, "hvslck", NULL, MTX_DEF);
@@ -1079,7 +984,7 @@ storvsc_attach(device_t dev)
sc->hs_drain_notify = FALSE;
sema_init(&sc->hs_drain_sema, 0, "Store Drain Sema");
- ret = hv_storvsc_connect_vsp(hv_dev);
+ ret = hv_storvsc_connect_vsp(sc);
if (ret != 0) {
goto cleanup;
}
@@ -1177,7 +1082,6 @@ storvsc_detach(device_t dev)
{
struct storvsc_softc *sc = device_get_softc(dev);
struct hv_storvsc_request *reqp = NULL;
- struct hv_device *hv_device = vmbus_get_devctx(dev);
struct hv_sgl_node *sgl_node = NULL;
int j = 0;
@@ -1199,7 +1103,7 @@ storvsc_detach(device_t dev)
* under the protection of the incoming channel lock.
*/
- hv_vmbus_channel_close(hv_device->channel);
+ hv_vmbus_channel_close(sc->hs_chan);
mtx_lock(&sc->hs_lock);
while (!LIST_EMPTY(&sc->hs_free_list)) {
@@ -1253,7 +1157,7 @@ storvsc_timeout_test(struct hv_storvsc_request *reqp,
if (wait) {
mtx_lock(&reqp->event.mtx);
}
- ret = hv_storvsc_io_request(sc->hs_dev, reqp);
+ ret = hv_storvsc_io_request(sc, reqp);
if (ret != 0) {
if (wait) {
mtx_unlock(&reqp->event.mtx);
@@ -1364,7 +1268,7 @@ storvsc_poll(struct cam_sim *sim)
mtx_assert(&sc->hs_lock, MA_OWNED);
mtx_unlock(&sc->hs_lock);
- hv_storvsc_on_channel_callback(sc->hs_dev->channel);
+ hv_storvsc_on_channel_callback(sc->hs_chan);
mtx_lock(&sc->hs_lock);
}
@@ -1449,7 +1353,7 @@ storvsc_action(struct cam_sim *sim, union ccb *ccb)
case XPT_RESET_BUS:
case XPT_RESET_DEV:{
#if HVS_HOST_RESET
- if ((res = hv_storvsc_host_reset(sc->hs_dev)) != 0) {
+ if ((res = hv_storvsc_host_reset(sc)) != 0) {
xpt_print(ccb->ccb_h.path,
"hv_storvsc_host_reset failed with %d\n", res);
ccb->ccb_h.status = CAM_PROVIDE_FAIL;
@@ -1522,7 +1426,7 @@ storvsc_action(struct cam_sim *sim, union ccb *ccb)
}
#endif
- if ((res = hv_storvsc_io_request(sc->hs_dev, reqp)) != 0) {
+ if ((res = hv_storvsc_io_request(sc, reqp)) != 0) {
xpt_print(ccb->ccb_h.path,
"hv_storvsc_io_request failed with %d\n", res);
ccb->ccb_h.status = CAM_PROVIDE_FAIL;
@@ -2148,13 +2052,11 @@ storvsc_free_request(struct storvsc_softc *sc, struct hv_storvsc_request *reqp)
static enum hv_storage_type
storvsc_get_storage_type(device_t dev)
{
- const char *p = vmbus_get_type(dev);
+ device_t parent = device_get_parent(dev);
- if (!memcmp(p, &gBlkVscDeviceType, sizeof(hv_guid))) {
+ if (VMBUS_PROBE_GUID(parent, dev, &gBlkVscDeviceType) == 0)
return DRIVER_BLKVSC;
- } else if (!memcmp(p, &gStorVscDeviceType, sizeof(hv_guid))) {
+ if (VMBUS_PROBE_GUID(parent, dev, &gStorVscDeviceType) == 0)
return DRIVER_STORVSC;
- }
- return (DRIVER_UNKNOWN);
+ return DRIVER_UNKNOWN;
}
-
diff --git a/sys/dev/hyperv/utilities/hv_heartbeat.c b/sys/dev/hyperv/utilities/hv_heartbeat.c
index 5f4fcf6..91561eb 100644
--- a/sys/dev/hyperv/utilities/hv_heartbeat.c
+++ b/sys/dev/hyperv/utilities/hv_heartbeat.c
@@ -36,9 +36,10 @@
#include <dev/hyperv/include/hyperv.h>
#include "hv_util.h"
+#include "vmbus_if.h"
/* Heartbeat Service */
-static hv_guid service_guid = { .data =
+static const hv_guid service_guid = { .data =
{0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d} };
@@ -60,7 +61,7 @@ hv_heartbeat_cb(void *context)
softc = (hv_util_sc*)context;
buf = softc->receive_buffer;;
- channel = softc->hv_dev->channel;
+ channel = softc->channel;
ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE, &recvlen,
&requestid);
@@ -93,16 +94,13 @@ hv_heartbeat_cb(void *context)
static int
hv_heartbeat_probe(device_t dev)
{
- const char *p = vmbus_get_type(dev);
-
if (resource_disabled("hvheartbeat", 0))
return ENXIO;
- if (!memcmp(p, &service_guid, sizeof(hv_guid))) {
+ if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, &service_guid) == 0) {
device_set_desc(dev, "Hyper-V Heartbeat Service");
return BUS_PROBE_DEFAULT;
}
-
return ENXIO;
}
diff --git a/sys/dev/hyperv/utilities/hv_kvp.c b/sys/dev/hyperv/utilities/hv_kvp.c
index ebf948c..9a6d1f8 100644
--- a/sys/dev/hyperv/utilities/hv_kvp.c
+++ b/sys/dev/hyperv/utilities/hv_kvp.c
@@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
#include "hv_util.h"
#include "unicode.h"
#include "hv_kvp.h"
+#include "vmbus_if.h"
/* hv_kvp defines */
#define BUFFERSIZE sizeof(struct hv_kvp_msg)
@@ -89,7 +90,7 @@ static int hv_kvp_log = 0;
log(LOG_INFO, "hv_kvp: " __VA_ARGS__); \
} while (0)
-static hv_guid service_guid = { .data =
+static const hv_guid service_guid = { .data =
{0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6} };
@@ -307,10 +308,6 @@ hv_kvp_convert_utf16_ipinfo_to_utf8(struct hv_kvp_ip_msg *host_ip_msg,
{
int err_ip, err_subnet, err_gway, err_dns, err_adap;
int UNUSED_FLAG = 1;
- struct hv_device *hv_dev; /* GUID Data Structure */
- hn_softc_t *sc; /* hn softc structure */
- char buf[HYPERV_GUID_STRLEN];
-
device_t *devs;
int devcnt;
@@ -332,12 +329,18 @@ hv_kvp_convert_utf16_ipinfo_to_utf8(struct hv_kvp_ip_msg *host_ip_msg,
if (devclass_get_devices(devclass_find("hn"), &devs, &devcnt) == 0) {
for (devcnt = devcnt - 1; devcnt >= 0; devcnt--) {
- sc = device_get_softc(devs[devcnt]);
-
- /* Trying to find GUID of Network Device */
- hv_dev = sc->hn_dev_obj;
+ /* XXX access other driver's softc? are you kidding? */
+ device_t dev = devs[devcnt];
+ struct hn_softc *sc = device_get_softc(dev);
+ struct hv_vmbus_channel *chan;
+ char buf[HYPERV_GUID_STRLEN];
- hyperv_guid2str(&hv_dev->device_id, buf, sizeof(buf));
+ /*
+ * Trying to find GUID of Network Device
+ * TODO: need vmbus interface.
+ */
+ chan = vmbus_get_channel(dev);
+ hyperv_guid2str(&chan->ch_guid_inst, buf, sizeof(buf));
if (strncmp(buf, (char *)umsg->body.kvp_ip_val.adapter_id,
HYPERV_GUID_STRLEN - 1) == 0) {
@@ -572,7 +575,7 @@ hv_kvp_respond_host(hv_kvp_sc *sc, int error)
hv_icmsg_hdrp->status = error;
hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE;
- error = hv_vmbus_channel_send_packet(sc->util_sc.hv_dev->channel,
+ error = hv_vmbus_channel_send_packet(sc->util_sc.channel,
sc->rcv_buf,
sc->host_msg_len, sc->host_msg_id,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
@@ -623,7 +626,7 @@ hv_kvp_process_request(void *context, int pending)
sc = (hv_kvp_sc*)context;
kvp_buf = sc->util_sc.receive_buffer;;
- channel = sc->util_sc.hv_dev->channel;
+ channel = sc->util_sc.channel;
ret = hv_vmbus_channel_recv_packet(channel, kvp_buf, 2 * PAGE_SIZE,
&recvlen, &requestid);
@@ -865,16 +868,13 @@ hv_kvp_dev_daemon_poll(struct cdev *dev, int events, struct thread *td)
static int
hv_kvp_probe(device_t dev)
{
- const char *p = vmbus_get_type(dev);
-
if (resource_disabled("hvkvp", 0))
return ENXIO;
- if (!memcmp(p, &service_guid, sizeof(hv_guid))) {
+ if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, &service_guid) == 0) {
device_set_desc(dev, "Hyper-V KVP Service");
return BUS_PROBE_DEFAULT;
}
-
return ENXIO;
}
diff --git a/sys/dev/hyperv/utilities/hv_shutdown.c b/sys/dev/hyperv/utilities/hv_shutdown.c
index 3dfbf13..336e911 100644
--- a/sys/dev/hyperv/utilities/hv_shutdown.c
+++ b/sys/dev/hyperv/utilities/hv_shutdown.c
@@ -41,8 +41,9 @@
#include <dev/hyperv/include/hyperv.h>
#include "hv_util.h"
+#include "vmbus_if.h"
-static hv_guid service_guid = { .data =
+static const hv_guid service_guid = { .data =
{0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB} };
@@ -64,7 +65,7 @@ hv_shutdown_cb(void *context)
softc = (hv_util_sc*)context;
buf = softc->receive_buffer;;
- channel = softc->hv_dev->channel;
+ channel = softc->channel;
ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE,
&recv_len, &request_id);
@@ -115,16 +116,13 @@ hv_shutdown_cb(void *context)
static int
hv_shutdown_probe(device_t dev)
{
- const char *p = vmbus_get_type(dev);
-
if (resource_disabled("hvshutdown", 0))
return ENXIO;
- if (!memcmp(p, &service_guid, sizeof(hv_guid))) {
+ if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, &service_guid) == 0) {
device_set_desc(dev, "Hyper-V Shutdown Service");
return BUS_PROBE_DEFAULT;
}
-
return ENXIO;
}
diff --git a/sys/dev/hyperv/utilities/hv_timesync.c b/sys/dev/hyperv/utilities/hv_timesync.c
index eeb0434..c114858 100644
--- a/sys/dev/hyperv/utilities/hv_timesync.c
+++ b/sys/dev/hyperv/utilities/hv_timesync.c
@@ -41,6 +41,7 @@
#include <dev/hyperv/include/hyperv.h>
#include "hv_util.h"
+#include "vmbus_if.h"
#define HV_WLTIMEDELTA 116444736000000000L /* in 100ns unit */
#define HV_ICTIMESYNCFLAG_PROBE 0
@@ -54,7 +55,7 @@ typedef struct {
} time_sync_data;
/* Time Synch Service */
-static hv_guid service_guid = {.data =
+static const hv_guid service_guid = {.data =
{0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf } };
@@ -139,7 +140,7 @@ hv_timesync_cb(void *context)
hv_timesync_sc *softc;
softc = (hv_timesync_sc*)context;
- channel = softc->util_sc.hv_dev->channel;
+ channel = softc->util_sc.channel;
time_buf = softc->util_sc.receive_buffer;
ret = hv_vmbus_channel_recv_packet(channel, time_buf,
@@ -170,16 +171,13 @@ hv_timesync_cb(void *context)
static int
hv_timesync_probe(device_t dev)
{
- const char *p = vmbus_get_type(dev);
-
if (resource_disabled("hvtimesync", 0))
return ENXIO;
- if (!memcmp(p, &service_guid, sizeof(hv_guid))) {
+ if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, &service_guid) == 0) {
device_set_desc(dev, "Hyper-V Time Synch Service");
return BUS_PROBE_DEFAULT;
}
-
return ENXIO;
}
diff --git a/sys/dev/hyperv/utilities/hv_util.c b/sys/dev/hyperv/utilities/hv_util.c
index 3119e3f..f7cbd3c 100644
--- a/sys/dev/hyperv/utilities/hv_util.c
+++ b/sys/dev/hyperv/utilities/hv_util.c
@@ -74,13 +74,11 @@ hv_negotiate_version(
int
hv_util_attach(device_t dev)
{
- struct hv_device* hv_dev;
struct hv_util_sc* softc;
int ret;
- hv_dev = vmbus_get_devctx(dev);
softc = device_get_softc(dev);
- softc->hv_dev = hv_dev;
+ softc->channel = vmbus_get_channel(dev);
softc->receive_buffer =
malloc(4 * PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO);
@@ -91,9 +89,9 @@ hv_util_attach(device_t dev)
* Turn off batched reading for all util drivers before we open the
* channel.
*/
- hv_set_channel_read_state(hv_dev->channel, FALSE);
+ hv_set_channel_read_state(softc->channel, FALSE);
- ret = hv_vmbus_channel_open(hv_dev->channel, 4 * PAGE_SIZE,
+ ret = hv_vmbus_channel_open(softc->channel, 4 * PAGE_SIZE,
4 * PAGE_SIZE, NULL, 0,
softc->callback, softc);
@@ -110,14 +108,10 @@ error0:
int
hv_util_detach(device_t dev)
{
- struct hv_device* hv_dev;
- struct hv_util_sc* softc;
-
- hv_dev = vmbus_get_devctx(dev);
+ struct hv_util_sc *sc = device_get_softc(dev);
- hv_vmbus_channel_close(hv_dev->channel);
- softc = device_get_softc(dev);
+ hv_vmbus_channel_close(sc->channel);
+ free(sc->receive_buffer, M_DEVBUF);
- free(softc->receive_buffer, M_DEVBUF);
return (0);
}
diff --git a/sys/dev/hyperv/utilities/hv_util.h b/sys/dev/hyperv/utilities/hv_util.h
index e202784..1be5a61 100644
--- a/sys/dev/hyperv/utilities/hv_util.h
+++ b/sys/dev/hyperv/utilities/hv_util.h
@@ -41,7 +41,7 @@ typedef struct hv_util_sc {
*/
void (*callback)(void *);
- struct hv_device* hv_dev;
+ struct hv_vmbus_channel *channel;
uint8_t *receive_buffer;
} hv_util_sc;
diff --git a/sys/dev/hyperv/vmbus/hv_channel.c b/sys/dev/hyperv/vmbus/hv_channel.c
index 9b9f684..a7d9de8 100644
--- a/sys/dev/hyperv/vmbus/hv_channel.c
+++ b/sys/dev/hyperv/vmbus/hv_channel.c
@@ -106,10 +106,10 @@ vmbus_channel_sysctl_create(hv_vmbus_channel* channel)
hv_vmbus_channel* primary_ch = channel->primary_channel;
if (primary_ch == NULL) {
- dev = channel->device->device;
+ dev = channel->ch_dev;
ch_id = channel->ch_id;
} else {
- dev = primary_ch->device->device;
+ dev = primary_ch->ch_dev;
ch_id = primary_ch->ch_id;
sub_ch_id = channel->ch_subidx;
}
diff --git a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
index b6d0eac..54a61c7 100644
--- a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
+++ b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
@@ -165,7 +165,7 @@ vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
* It is a sub channel offer, process it.
*/
new_channel->primary_channel = channel;
- new_channel->device = channel->device;
+ new_channel->ch_dev = channel->ch_dev;
mtx_lock(&channel->sc_lock);
TAILQ_INSERT_TAIL(&channel->sc_list_anchor,
new_channel, sc_list_entry);
@@ -209,19 +209,15 @@ vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
new_channel->state = HV_CHANNEL_OPEN_STATE;
/*
- * Start the process of binding this offer to the driver
- * (We need to set the device field before calling
- * hv_vmbus_child_device_add())
- */
- new_channel->device = hv_vmbus_child_device_create(new_channel);
-
- /*
* Add the new device to the bus. This will kick off device-driver
* binding which eventually invokes the device driver's AddDevice()
* method.
+ *
+ * NOTE:
+ * Error is ignored here; don't have much to do if error really
+ * happens.
*/
- hv_vmbus_child_device_register(new_channel->vmbus_sc,
- new_channel->device);
+ hv_vmbus_child_device_register(new_channel);
}
void
@@ -368,8 +364,8 @@ vmbus_chan_detach_task(void *xchan, int pending __unused)
struct hv_vmbus_channel *chan = xchan;
if (HV_VMBUS_CHAN_ISPRIMARY(chan)) {
- /* Only primary channel owns the hv_device */
- hv_vmbus_child_device_unregister(chan->device);
+ /* Only primary channel owns the device */
+ hv_vmbus_child_device_unregister(chan);
/* NOTE: DO NOT free primary channel for now */
} else {
struct vmbus_softc *sc = chan->vmbus_sc;
@@ -449,8 +445,8 @@ hv_vmbus_release_unattached_channels(struct vmbus_softc *sc)
TAILQ_REMOVE(&sc->vmbus_chlist, channel, ch_link);
if (HV_VMBUS_CHAN_ISPRIMARY(channel)) {
- /* Only primary channel owns the hv_device */
- hv_vmbus_child_device_unregister(channel->device);
+ /* Only primary channel owns the device */
+ hv_vmbus_child_device_unregister(channel);
}
hv_vmbus_free_vmbus_channel(channel);
}
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
index b6cb8f8..8997ae8 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -212,12 +212,9 @@ void hv_vmbus_free_vmbus_channel(hv_vmbus_channel *channel);
void hv_vmbus_release_unattached_channels(
struct vmbus_softc *);
-struct hv_device* hv_vmbus_child_device_create(
- struct hv_vmbus_channel *channel);
-
-void hv_vmbus_child_device_register(struct vmbus_softc *,
- struct hv_device *child_dev);
+int hv_vmbus_child_device_register(
+ struct hv_vmbus_channel *chan);
int hv_vmbus_child_device_unregister(
- struct hv_device *child_dev);
+ struct hv_vmbus_channel *chan);
#endif /* __HYPERV_PRIV_H__ */
diff --git a/sys/dev/hyperv/vmbus/vmbus.c b/sys/dev/hyperv/vmbus/vmbus.c
index 350e120..cd0fd24 100644
--- a/sys/dev/hyperv/vmbus/vmbus.c
+++ b/sys/dev/hyperv/vmbus/vmbus.c
@@ -1040,113 +1040,73 @@ vmbus_intr_teardown(struct vmbus_softc *sc)
static int
vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
{
- struct hv_device *child_dev_ctx = device_get_ivars(child);
-
- switch (index) {
- case HV_VMBUS_IVAR_TYPE:
- *result = (uintptr_t)&child_dev_ctx->class_id;
- return (0);
-
- case HV_VMBUS_IVAR_INSTANCE:
- *result = (uintptr_t)&child_dev_ctx->device_id;
- return (0);
-
- case HV_VMBUS_IVAR_DEVCTX:
- *result = (uintptr_t)child_dev_ctx;
- return (0);
-
- case HV_VMBUS_IVAR_NODE:
- *result = (uintptr_t)child_dev_ctx->device;
- return (0);
- }
- return (ENOENT);
-}
-
-static int
-vmbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
-{
- switch (index) {
- case HV_VMBUS_IVAR_TYPE:
- case HV_VMBUS_IVAR_INSTANCE:
- case HV_VMBUS_IVAR_DEVCTX:
- case HV_VMBUS_IVAR_NODE:
- /* read-only */
- return (EINVAL);
- }
return (ENOENT);
}
static int
vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen)
{
- struct hv_device *dev_ctx = device_get_ivars(child);
+ const struct hv_vmbus_channel *chan;
char guidbuf[HYPERV_GUID_STRLEN];
- if (dev_ctx == NULL)
+ chan = vmbus_get_channel(child);
+ if (chan == NULL) {
+ /* Event timer device, which does not belong to a channel */
return (0);
+ }
strlcat(buf, "classid=", buflen);
- hyperv_guid2str(&dev_ctx->class_id, guidbuf, sizeof(guidbuf));
+ hyperv_guid2str(&chan->ch_guid_type, guidbuf, sizeof(guidbuf));
strlcat(buf, guidbuf, buflen);
strlcat(buf, " deviceid=", buflen);
- hyperv_guid2str(&dev_ctx->device_id, guidbuf, sizeof(guidbuf));
+ hyperv_guid2str(&chan->ch_guid_inst, guidbuf, sizeof(guidbuf));
strlcat(buf, guidbuf, buflen);
return (0);
}
-struct hv_device *
-hv_vmbus_child_device_create(struct hv_vmbus_channel *channel)
-{
- hv_device *child_dev;
-
- /*
- * Allocate the new child device
- */
- child_dev = malloc(sizeof(hv_device), M_DEVBUF, M_WAITOK | M_ZERO);
-
- child_dev->channel = channel;
- child_dev->class_id = channel->ch_guid_type;
- child_dev->device_id = channel->ch_guid_inst;
-
- return (child_dev);
-}
-
-void
-hv_vmbus_child_device_register(struct vmbus_softc *sc,
- struct hv_device *child_dev)
+int
+hv_vmbus_child_device_register(struct hv_vmbus_channel *chan)
{
- device_t child, parent;
-
- parent = sc->vmbus_dev;
- if (bootverbose) {
- char name[HYPERV_GUID_STRLEN];
-
- hyperv_guid2str(&child_dev->class_id, name, sizeof(name));
- device_printf(parent, "add device, classid: %s\n", name);
+ struct vmbus_softc *sc = chan->vmbus_sc;
+ device_t parent = sc->vmbus_dev;
+ int error = 0;
+
+ chan->ch_dev = device_add_child(parent, NULL, -1);
+ if (chan->ch_dev == NULL) {
+ device_printf(parent, "device_add_child for chan%u failed\n",
+ chan->ch_id);
+ error = ENXIO;
+ goto done;
}
+ device_set_ivars(chan->ch_dev, chan);
- child = device_add_child(parent, NULL, -1);
- child_dev->device = child;
- device_set_ivars(child, child_dev);
-
- /* New device was added to vmbus */
+done:
+ /* New device has been/should be added to vmbus. */
vmbus_scan_newdev(sc);
+ return error;
}
int
-hv_vmbus_child_device_unregister(struct hv_device *child_dev)
+hv_vmbus_child_device_unregister(struct hv_vmbus_channel *chan)
{
- int ret = 0;
+ int error;
+
+ if (chan->ch_dev == NULL) {
+ /* Failed to add a device. */
+ return 0;
+ }
+
/*
* XXXKYS: Ensure that this is the opposite of
* device_add_child()
*/
mtx_lock(&Giant);
- ret = device_delete_child(vmbus_get_device(), child_dev->device);
+ error = device_delete_child(chan->vmbus_sc->vmbus_dev, chan->ch_dev);
mtx_unlock(&Giant);
- return(ret);
+
+ return error;
}
static int
@@ -1170,6 +1130,16 @@ vmbus_get_version_method(device_t bus, device_t dev)
}
static int
+vmbus_probe_guid_method(device_t bus, device_t dev, const struct hv_guid *guid)
+{
+ const struct hv_vmbus_channel *chan = vmbus_get_channel(dev);
+
+ if (memcmp(&chan->ch_guid_type, guid, sizeof(struct hv_guid)) == 0)
+ return 0;
+ return ENXIO;
+}
+
+static int
vmbus_probe(device_t dev)
{
char *id[] = { "VMBUS", NULL };
@@ -1376,11 +1346,11 @@ static device_method_t vmbus_methods[] = {
DEVMETHOD(bus_add_child, bus_generic_add_child),
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_read_ivar, vmbus_read_ivar),
- 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(vmbus_probe_guid, vmbus_probe_guid_method),
DEVMETHOD_END
};
diff --git a/sys/dev/hyperv/vmbus/vmbus_if.m b/sys/dev/hyperv/vmbus/vmbus_if.m
index 0782d00..3281ad2 100644
--- a/sys/dev/hyperv/vmbus/vmbus_if.m
+++ b/sys/dev/hyperv/vmbus/vmbus_if.m
@@ -31,7 +31,17 @@
INTERFACE vmbus;
+HEADER {
+ struct hv_guid;
+};
+
METHOD uint32_t get_version {
device_t bus;
device_t dev;
};
+
+METHOD int probe_guid {
+ device_t bus;
+ device_t dev;
+ const struct hv_guid *guid;
+};
diff --git a/sys/modules/hyperv/utilities/Makefile b/sys/modules/hyperv/utilities/Makefile
index c1b6d4f..290bd27 100644
--- a/sys/modules/hyperv/utilities/Makefile
+++ b/sys/modules/hyperv/utilities/Makefile
@@ -4,7 +4,7 @@
KMOD= hv_utils
SRCS= hv_util.c hv_kvp.c hv_timesync.c hv_shutdown.c hv_heartbeat.c
-SRCS+= bus_if.h device_if.h
+SRCS+= bus_if.h device_if.h vmbus_if.h
CFLAGS+= -I${.CURDIR}/../../../dev/hyperv/include \
-I${.CURDIR}/../../../dev/hyperv/vmbus
OpenPOWER on IntegriCloud