aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorSepherosa Ziehau <sephe@FreeBSD.org>2016-04-19 09:42:48 +0000
committerSepherosa Ziehau <sephe@FreeBSD.org>2016-04-19 09:42:48 +0000
commitadc9edf341bac75329792878ce8140db03badc48 (patch)
tree1db8c515ae0709378c930a1f7600ac02b0b13b22 /sys/dev
parent55a1cfa16bd99291906c899a7ed0154a45de4c76 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel_mgmt.c41
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c10
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_priv.h3
3 files changed, 49 insertions, 5 deletions
diff --git a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
index e7e77c21e7c1..a78940394410 100644
--- a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
+++ b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
@@ -27,7 +27,10 @@
*/
#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/mbuf.h>
+#include <sys/mutex.h>
#include "hv_vmbus_priv.h"
@@ -92,6 +95,14 @@ typedef struct hv_work_item {
void* context;
} hv_work_item;
+static struct mtx vmbus_chwait_lock;
+MTX_SYSINIT(vmbus_chwait_lk, &vmbus_chwait_lock, "vmbus primarych wait lock",
+ MTX_DEF);
+static uint32_t vmbus_chancnt;
+static uint32_t vmbus_devcnt;
+
+#define VMBUS_CHANCNT_DONE 0x80000000
+
/**
* Implementation of the work abstraction.
*/
@@ -276,6 +287,11 @@ vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
mtx_unlock(&hv_vmbus_g_connection.channel_lock);
hv_vmbus_free_vmbus_channel(new_channel);
}
+
+ mtx_lock(&vmbus_chwait_lock);
+ vmbus_devcnt++;
+ mtx_unlock(&vmbus_chwait_lock);
+ wakeup(&vmbus_devcnt);
}
void
@@ -377,6 +393,11 @@ vmbus_channel_on_offer(hv_vmbus_channel_msg_header* hdr)
memcpy(copied, hdr, sizeof(*copied));
hv_queue_work_item(vmbus_channel_on_offer_internal, copied);
+
+ mtx_lock(&vmbus_chwait_lock);
+ if ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0)
+ vmbus_chancnt++;
+ mtx_unlock(&vmbus_chwait_lock);
}
static void
@@ -468,6 +489,11 @@ vmbus_channel_on_offer_rescind_internal(void *context)
static void
vmbus_channel_on_offers_delivered(hv_vmbus_channel_msg_header* hdr)
{
+
+ mtx_lock(&vmbus_chwait_lock);
+ vmbus_chancnt |= VMBUS_CHANCNT_DONE;
+ mtx_unlock(&vmbus_chwait_lock);
+ wakeup(&vmbus_chancnt);
}
/**
@@ -745,3 +771,18 @@ vmbus_select_outgoing_channel(struct hv_vmbus_channel *primary)
return(outgoing_channel);
}
+
+void
+vmbus_scan(void)
+{
+ uint32_t chancnt;
+
+ mtx_lock(&vmbus_chwait_lock);
+ while ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0)
+ mtx_sleep(&vmbus_chancnt, &vmbus_chwait_lock, 0, "waitch", 0);
+ chancnt = vmbus_chancnt & ~VMBUS_CHANCNT_DONE;
+
+ while (vmbus_devcnt != chancnt)
+ mtx_sleep(&vmbus_devcnt, &vmbus_chwait_lock, 0, "waitdev", 0);
+ mtx_unlock(&vmbus_chwait_lock);
+}
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
index ec4b26fe6fe6..f7cbcefe8cef 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
@@ -326,7 +326,6 @@ int
hv_vmbus_child_device_register(struct hv_device *child_dev)
{
device_t child;
- int ret = 0;
if (bootverbose) {
char name[40];
@@ -338,10 +337,6 @@ hv_vmbus_child_device_register(struct hv_device *child_dev)
child_dev->device = child;
device_set_ivars(child, child_dev);
- mtx_lock(&Giant);
- ret = device_probe_and_attach(child);
- mtx_unlock(&Giant);
-
return (0);
}
@@ -481,6 +476,11 @@ vmbus_bus_init(void)
goto cleanup1;
hv_vmbus_request_channel_offers();
+
+ vmbus_scan();
+ bus_generic_attach(vmbus_devp);
+ device_printf(vmbus_devp, "device scan, probe and attach done\n");
+
return (ret);
cleanup1:
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
index 84104944d91d..028f3af93e09 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -751,6 +751,9 @@ void hv_vmbus_on_events(int cpu);
void hv_et_init(void);
void hv_et_intr(struct trapframe*);
+/* Wait for device creation */
+void vmbus_scan(void);
+
/*
* The guest OS needs to register the guest ID with the hypervisor.
* The guest ID is a 64 bit entity and the structure of this ID is