summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c')
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c110
1 files changed, 57 insertions, 53 deletions
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
index 4895f71..669a532 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/pcpu.h>
#include <x86/apicvar.h>
+#include <dev/hyperv/include/hyperv.h>
#include "hv_vmbus_priv.h"
#include <contrib/dev/acpica/include/acpi.h>
@@ -75,7 +76,7 @@ static char *vmbus_ids[] = { "VMBUS", NULL };
* the hypervisor.
*/
static void
-vmbus_msg_swintr(void *arg)
+vmbus_msg_swintr(void *arg, int pending __unused)
{
int cpu;
void* page_addr;
@@ -174,12 +175,15 @@ hv_vmbus_isr(struct trapframe *frame)
/* Check if there are actual msgs to be process */
page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu];
- msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT;
+ msg = (hv_vmbus_message*) page_addr + HV_VMBUS_TIMER_SINT;
/* we call eventtimer process the message */
if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) {
msg->header.message_type = HV_MESSAGE_TYPE_NONE;
+ /* call intrrupt handler of event timer */
+ hv_et_intr(frame);
+
/*
* Make sure the write to message_type (ie set to
* HV_MESSAGE_TYPE_NONE) happens before we read the
@@ -196,12 +200,12 @@ hv_vmbus_isr(struct trapframe *frame)
*/
wrmsr(HV_X64_MSR_EOM, 0);
}
- hv_et_intr(frame);
- return (FILTER_HANDLED);
}
+ msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT;
if (msg->header.message_type != HV_MESSAGE_TYPE_NONE) {
- swi_sched(hv_vmbus_g_context.msg_swintr[cpu], 0);
+ taskqueue_enqueue(hv_vmbus_g_context.hv_msg_tq[cpu],
+ &hv_vmbus_g_context.hv_msg_task[cpu]);
}
return (FILTER_HANDLED);
@@ -279,6 +283,23 @@ vmbus_write_ivar(
return (ENOENT);
}
+static int
+vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen)
+{
+ char guidbuf[40];
+ struct hv_device *dev_ctx = device_get_ivars(child);
+
+ strlcat(buf, "classid=", buflen);
+ snprintf_hv_guid(guidbuf, sizeof(guidbuf), &dev_ctx->class_id);
+ strlcat(buf, guidbuf, buflen);
+
+ strlcat(buf, " deviceid=", buflen);
+ snprintf_hv_guid(guidbuf, sizeof(guidbuf), &dev_ctx->device_id);
+ strlcat(buf, guidbuf, buflen);
+
+ return (0);
+}
+
struct hv_device*
hv_vmbus_child_device_create(
hv_guid type,
@@ -300,15 +321,17 @@ hv_vmbus_child_device_create(
return (child_dev);
}
-static void
-print_dev_guid(struct hv_device *dev)
+int
+snprintf_hv_guid(char *buf, size_t sz, const hv_guid *guid)
{
- int i;
- unsigned char guid_name[100];
- for (i = 0; i < 32; i += 2)
- sprintf(&guid_name[i], "%02x", dev->class_id.data[i / 2]);
- if(bootverbose)
- printf("VMBUS: Class ID: %s\n", guid_name);
+ int cnt;
+ const unsigned char *d = guid->data;
+
+ cnt = snprintf(buf, sz,
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ d[3], d[2], d[1], d[0], d[5], d[4], d[7], d[6],
+ d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+ return (cnt);
}
int
@@ -317,8 +340,11 @@ hv_vmbus_child_device_register(struct hv_device *child_dev)
device_t child;
int ret = 0;
- print_dev_guid(child_dev);
-
+ if (bootverbose) {
+ char name[40];
+ snprintf_hv_guid(name, sizeof(name), &child_dev->class_id);
+ printf("VMBUS: Class ID: %s\n", name);
+ }
child = device_add_child(vmbus_devp, NULL, -1);
child_dev->device = child;
@@ -485,9 +511,6 @@ vmbus_bus_init(void)
setup_args.vector = hv_vmbus_g_context.hv_cb_vector;
CPU_FOREACH(j) {
- hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
- hv_vmbus_g_context.msg_swintr[j] = NULL;
-
snprintf(buf, sizeof(buf), "cpu%d:hyperv", j);
intrcnt_add(buf, &hv_vmbus_intr_cpu[j]);
@@ -504,39 +527,21 @@ vmbus_bus_init(void)
*/
hv_vmbus_g_context.hv_event_queue[j] = taskqueue_create_fast("hyperv event", M_WAITOK,
taskqueue_thread_enqueue, &hv_vmbus_g_context.hv_event_queue[j]);
- if (hv_vmbus_g_context.hv_event_queue[j] == NULL) {
- if (bootverbose)
- printf("VMBUS: failed to setup taskqueue\n");
- goto cleanup1;
- }
CPU_SETOF(j, &cpu_mask);
taskqueue_start_threads_cpuset(&hv_vmbus_g_context.hv_event_queue[j], 1, PI_NET, &cpu_mask,
"hvevent%d", j);
/*
- * Setup software interrupt thread and handler for msg handling.
- */
- ret = swi_add(&hv_vmbus_g_context.hv_msg_intr_event[j],
- "hv_msg", vmbus_msg_swintr, (void *)(long)j, SWI_CLOCK, 0,
- &hv_vmbus_g_context.msg_swintr[j]);
- if (ret) {
- if(bootverbose)
- printf("VMBUS: failed to setup msg swi for "
- "cpu %d\n", j);
- goto cleanup1;
- }
-
- /*
- * Bind the swi thread to the cpu.
+ * Setup per-cpu tasks and taskqueues to handle msg.
*/
- ret = intr_event_bind(hv_vmbus_g_context.hv_msg_intr_event[j],
- j);
- if (ret) {
- if(bootverbose)
- printf("VMBUS: failed to bind msg swi thread "
- "to cpu %d\n", j);
- goto cleanup1;
- }
+ hv_vmbus_g_context.hv_msg_tq[j] = taskqueue_create_fast(
+ "hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
+ &hv_vmbus_g_context.hv_msg_tq[j]);
+ CPU_SETOF(j, &cpu_mask);
+ taskqueue_start_threads_cpuset(&hv_vmbus_g_context.hv_msg_tq[j],
+ 1, PI_NET, &cpu_mask, "hvmsg%d", j);
+ TASK_INIT(&hv_vmbus_g_context.hv_msg_task[j], 0,
+ vmbus_msg_swintr, (void *)(long)j);
/*
* Prepare the per cpu msg and event pages to be called on each cpu.
@@ -576,11 +581,10 @@ vmbus_bus_init(void)
* remove swi and vmbus callback vector;
*/
CPU_FOREACH(j) {
- if (hv_vmbus_g_context.hv_event_queue[j] != NULL)
+ if (hv_vmbus_g_context.hv_event_queue[j] != NULL) {
taskqueue_free(hv_vmbus_g_context.hv_event_queue[j]);
- if (hv_vmbus_g_context.msg_swintr[j] != NULL)
- swi_remove(hv_vmbus_g_context.msg_swintr[j]);
- hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
+ hv_vmbus_g_context.hv_event_queue[j] = NULL;
+ }
}
vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector);
@@ -645,11 +649,10 @@ vmbus_bus_exit(void)
/* remove swi */
CPU_FOREACH(i) {
- if (hv_vmbus_g_context.hv_event_queue[i] != NULL)
+ if (hv_vmbus_g_context.hv_event_queue[i] != NULL) {
taskqueue_free(hv_vmbus_g_context.hv_event_queue[i]);
- if (hv_vmbus_g_context.msg_swintr[i] != NULL)
- swi_remove(hv_vmbus_g_context.msg_swintr[i]);
- hv_vmbus_g_context.hv_msg_intr_event[i] = NULL;
+ hv_vmbus_g_context.hv_event_queue[i] = NULL;
+ }
}
vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector);
@@ -714,6 +717,7 @@ static device_method_t vmbus_methods[] = {
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),
{ 0, 0 } };
OpenPOWER on IntegriCloud