diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/hyperv/include/hyperv.h | 31 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hv_net_vsc.c | 148 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hv_net_vsc.h | 11 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 53 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hv_rndis_filter.c | 40 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hv_rndis_filter.h | 11 | ||||
-rw-r--r-- | sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c | 184 | ||||
-rw-r--r-- | sys/dev/hyperv/utilities/hv_heartbeat.c | 10 | ||||
-rw-r--r-- | sys/dev/hyperv/utilities/hv_kvp.c | 32 | ||||
-rw-r--r-- | sys/dev/hyperv/utilities/hv_shutdown.c | 10 | ||||
-rw-r--r-- | sys/dev/hyperv/utilities/hv_timesync.c | 10 | ||||
-rw-r--r-- | sys/dev/hyperv/utilities/hv_util.c | 18 | ||||
-rw-r--r-- | sys/dev/hyperv/utilities/hv_util.h | 2 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_channel.c | 4 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_channel_mgmt.c | 24 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_vmbus_priv.h | 9 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/vmbus.c | 120 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/vmbus_if.m | 10 | ||||
-rw-r--r-- | sys/modules/hyperv/utilities/Makefile | 2 |
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 |