xref: /freebsd/sys/dev/hyperv/vmbus/vmbus.c (revision 7f9dff23d3092aa33ad45b2b63e52469b3c13a6e)
1 /*-
2  * Copyright (c) 2009-2012,2016 Microsoft Corp.
3  * Copyright (c) 2012 NetApp Inc.
4  * Copyright (c) 2012 Citrix Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * VM Bus Driver Implementation
31  */
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34 
35 #include <sys/param.h>
36 #include <sys/bus.h>
37 #include <sys/kernel.h>
38 #include <sys/lock.h>
39 #include <sys/malloc.h>
40 #include <sys/module.h>
41 #include <sys/mutex.h>
42 #include <sys/smp.h>
43 #include <sys/sysctl.h>
44 #include <sys/systm.h>
45 #include <sys/taskqueue.h>
46 
47 #include <machine/bus.h>
48 #include <machine/intr_machdep.h>
49 #include <machine/resource.h>
50 #include <x86/include/apicvar.h>
51 
52 #include <contrib/dev/acpica/include/acpi.h>
53 #include <dev/acpica/acpivar.h>
54 
55 #include <dev/hyperv/include/hyperv.h>
56 #include <dev/hyperv/include/vmbus_xact.h>
57 #include <dev/hyperv/vmbus/hyperv_reg.h>
58 #include <dev/hyperv/vmbus/hyperv_var.h>
59 #include <dev/hyperv/vmbus/vmbus_reg.h>
60 #include <dev/hyperv/vmbus/vmbus_var.h>
61 #include <dev/hyperv/vmbus/vmbus_chanvar.h>
62 
63 #include "acpi_if.h"
64 #include "pcib_if.h"
65 #include "vmbus_if.h"
66 
67 #define VMBUS_GPADL_START		0xe1e10
68 
69 struct vmbus_msghc {
70 	struct vmbus_xact		*mh_xact;
71 	struct hypercall_postmsg_in	mh_inprm_save;
72 };
73 
74 static int			vmbus_probe(device_t);
75 static int			vmbus_attach(device_t);
76 static int			vmbus_detach(device_t);
77 static int			vmbus_read_ivar(device_t, device_t, int,
78 				    uintptr_t *);
79 static int			vmbus_child_pnpinfo_str(device_t, device_t,
80 				    char *, size_t);
81 static struct resource		*vmbus_alloc_resource(device_t dev,
82 				    device_t child, int type, int *rid,
83 				    rman_res_t start, rman_res_t end,
84 				    rman_res_t count, u_int flags);
85 static int			vmbus_alloc_msi(device_t bus, device_t dev,
86 				    int count, int maxcount, int *irqs);
87 static int			vmbus_release_msi(device_t bus, device_t dev,
88 				    int count, int *irqs);
89 static int			vmbus_alloc_msix(device_t bus, device_t dev,
90 				    int *irq);
91 static int			vmbus_release_msix(device_t bus, device_t dev,
92 				    int irq);
93 static int			vmbus_map_msi(device_t bus, device_t dev,
94 				    int irq, uint64_t *addr, uint32_t *data);
95 static uint32_t			vmbus_get_version_method(device_t, device_t);
96 static int			vmbus_probe_guid_method(device_t, device_t,
97 				    const struct hyperv_guid *);
98 static uint32_t			vmbus_get_vcpu_id_method(device_t bus,
99 				    device_t dev, int cpu);
100 static struct taskqueue		*vmbus_get_eventtq_method(device_t, device_t,
101 				    int);
102 
103 static int			vmbus_init(struct vmbus_softc *);
104 static int			vmbus_connect(struct vmbus_softc *, uint32_t);
105 static int			vmbus_req_channels(struct vmbus_softc *sc);
106 static void			vmbus_disconnect(struct vmbus_softc *);
107 static int			vmbus_scan(struct vmbus_softc *);
108 static void			vmbus_scan_teardown(struct vmbus_softc *);
109 static void			vmbus_scan_done(struct vmbus_softc *,
110 				    const struct vmbus_message *);
111 static void			vmbus_chanmsg_handle(struct vmbus_softc *,
112 				    const struct vmbus_message *);
113 static void			vmbus_msg_task(void *, int);
114 static void			vmbus_synic_setup(void *);
115 static void			vmbus_synic_teardown(void *);
116 static int			vmbus_sysctl_version(SYSCTL_HANDLER_ARGS);
117 static int			vmbus_dma_alloc(struct vmbus_softc *);
118 static void			vmbus_dma_free(struct vmbus_softc *);
119 static int			vmbus_intr_setup(struct vmbus_softc *);
120 static void			vmbus_intr_teardown(struct vmbus_softc *);
121 static int			vmbus_doattach(struct vmbus_softc *);
122 static void			vmbus_event_proc_dummy(struct vmbus_softc *,
123 				    int);
124 
125 static struct vmbus_softc	*vmbus_sc;
126 
127 extern inthand_t IDTVEC(vmbus_isr);
128 
129 static const uint32_t		vmbus_version[] = {
130 	VMBUS_VERSION_WIN8_1,
131 	VMBUS_VERSION_WIN8,
132 	VMBUS_VERSION_WIN7,
133 	VMBUS_VERSION_WS2008
134 };
135 
136 static const vmbus_chanmsg_proc_t
137 vmbus_chanmsg_handlers[VMBUS_CHANMSG_TYPE_MAX] = {
138 	VMBUS_CHANMSG_PROC(CHOFFER_DONE, vmbus_scan_done),
139 	VMBUS_CHANMSG_PROC_WAKEUP(CONNECT_RESP)
140 };
141 
142 static device_method_t vmbus_methods[] = {
143 	/* Device interface */
144 	DEVMETHOD(device_probe,			vmbus_probe),
145 	DEVMETHOD(device_attach,		vmbus_attach),
146 	DEVMETHOD(device_detach,		vmbus_detach),
147 	DEVMETHOD(device_shutdown,		bus_generic_shutdown),
148 	DEVMETHOD(device_suspend,		bus_generic_suspend),
149 	DEVMETHOD(device_resume,		bus_generic_resume),
150 
151 	/* Bus interface */
152 	DEVMETHOD(bus_add_child,		bus_generic_add_child),
153 	DEVMETHOD(bus_print_child,		bus_generic_print_child),
154 	DEVMETHOD(bus_read_ivar,		vmbus_read_ivar),
155 	DEVMETHOD(bus_child_pnpinfo_str,	vmbus_child_pnpinfo_str),
156 	DEVMETHOD(bus_alloc_resource,		vmbus_alloc_resource),
157 	DEVMETHOD(bus_release_resource,		bus_generic_release_resource),
158 	DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
159 	DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
160 	DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
161 	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
162 #if __FreeBSD_version >= 1100000
163 	DEVMETHOD(bus_get_cpus,			bus_generic_get_cpus),
164 #endif
165 
166 	/* pcib interface */
167 	DEVMETHOD(pcib_alloc_msi,		vmbus_alloc_msi),
168 	DEVMETHOD(pcib_release_msi,		vmbus_release_msi),
169 	DEVMETHOD(pcib_alloc_msix,		vmbus_alloc_msix),
170 	DEVMETHOD(pcib_release_msix,		vmbus_release_msix),
171 	DEVMETHOD(pcib_map_msi,			vmbus_map_msi),
172 
173 	/* Vmbus interface */
174 	DEVMETHOD(vmbus_get_version,		vmbus_get_version_method),
175 	DEVMETHOD(vmbus_probe_guid,		vmbus_probe_guid_method),
176 	DEVMETHOD(vmbus_get_vcpu_id,		vmbus_get_vcpu_id_method),
177 	DEVMETHOD(vmbus_get_event_taskq,	vmbus_get_eventtq_method),
178 
179 	DEVMETHOD_END
180 };
181 
182 static driver_t vmbus_driver = {
183 	"vmbus",
184 	vmbus_methods,
185 	sizeof(struct vmbus_softc)
186 };
187 
188 static devclass_t vmbus_devclass;
189 
190 DRIVER_MODULE(vmbus, acpi, vmbus_driver, vmbus_devclass, NULL, NULL);
191 MODULE_DEPEND(vmbus, acpi, 1, 1, 1);
192 MODULE_DEPEND(vmbus, pci, 1, 1, 1);
193 MODULE_VERSION(vmbus, 1);
194 
195 static __inline struct vmbus_softc *
196 vmbus_get_softc(void)
197 {
198 	return vmbus_sc;
199 }
200 
201 void
202 vmbus_msghc_reset(struct vmbus_msghc *mh, size_t dsize)
203 {
204 	struct hypercall_postmsg_in *inprm;
205 
206 	if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX)
207 		panic("invalid data size %zu", dsize);
208 
209 	inprm = vmbus_xact_req_data(mh->mh_xact);
210 	memset(inprm, 0, HYPERCALL_POSTMSGIN_SIZE);
211 	inprm->hc_connid = VMBUS_CONNID_MESSAGE;
212 	inprm->hc_msgtype = HYPERV_MSGTYPE_CHANNEL;
213 	inprm->hc_dsize = dsize;
214 }
215 
216 struct vmbus_msghc *
217 vmbus_msghc_get(struct vmbus_softc *sc, size_t dsize)
218 {
219 	struct vmbus_msghc *mh;
220 	struct vmbus_xact *xact;
221 
222 	if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX)
223 		panic("invalid data size %zu", dsize);
224 
225 	xact = vmbus_xact_get(sc->vmbus_xc,
226 	    dsize + __offsetof(struct hypercall_postmsg_in, hc_data[0]));
227 	if (xact == NULL)
228 		return (NULL);
229 
230 	mh = vmbus_xact_priv(xact, sizeof(*mh));
231 	mh->mh_xact = xact;
232 
233 	vmbus_msghc_reset(mh, dsize);
234 	return (mh);
235 }
236 
237 void
238 vmbus_msghc_put(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
239 {
240 
241 	vmbus_xact_put(mh->mh_xact);
242 }
243 
244 void *
245 vmbus_msghc_dataptr(struct vmbus_msghc *mh)
246 {
247 	struct hypercall_postmsg_in *inprm;
248 
249 	inprm = vmbus_xact_req_data(mh->mh_xact);
250 	return (inprm->hc_data);
251 }
252 
253 int
254 vmbus_msghc_exec_noresult(struct vmbus_msghc *mh)
255 {
256 	sbintime_t time = SBT_1MS;
257 	struct hypercall_postmsg_in *inprm;
258 	bus_addr_t inprm_paddr;
259 	int i;
260 
261 	inprm = vmbus_xact_req_data(mh->mh_xact);
262 	inprm_paddr = vmbus_xact_req_paddr(mh->mh_xact);
263 
264 	/*
265 	 * Save the input parameter so that we could restore the input
266 	 * parameter if the Hypercall failed.
267 	 *
268 	 * XXX
269 	 * Is this really necessary?!  i.e. Will the Hypercall ever
270 	 * overwrite the input parameter?
271 	 */
272 	memcpy(&mh->mh_inprm_save, inprm, HYPERCALL_POSTMSGIN_SIZE);
273 
274 	/*
275 	 * In order to cope with transient failures, e.g. insufficient
276 	 * resources on host side, we retry the post message Hypercall
277 	 * several times.  20 retries seem sufficient.
278 	 */
279 #define HC_RETRY_MAX	20
280 
281 	for (i = 0; i < HC_RETRY_MAX; ++i) {
282 		uint64_t status;
283 
284 		status = hypercall_post_message(inprm_paddr);
285 		if (status == HYPERCALL_STATUS_SUCCESS)
286 			return 0;
287 
288 		pause_sbt("hcpmsg", time, 0, C_HARDCLOCK);
289 		if (time < SBT_1S * 2)
290 			time *= 2;
291 
292 		/* Restore input parameter and try again */
293 		memcpy(inprm, &mh->mh_inprm_save, HYPERCALL_POSTMSGIN_SIZE);
294 	}
295 
296 #undef HC_RETRY_MAX
297 
298 	return EIO;
299 }
300 
301 int
302 vmbus_msghc_exec(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
303 {
304 	int error;
305 
306 	vmbus_xact_activate(mh->mh_xact);
307 	error = vmbus_msghc_exec_noresult(mh);
308 	if (error)
309 		vmbus_xact_deactivate(mh->mh_xact);
310 	return error;
311 }
312 
313 void
314 vmbus_msghc_exec_cancel(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
315 {
316 
317 	vmbus_xact_deactivate(mh->mh_xact);
318 }
319 
320 const struct vmbus_message *
321 vmbus_msghc_wait_result(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
322 {
323 	size_t resp_len;
324 
325 	return (vmbus_xact_wait(mh->mh_xact, &resp_len));
326 }
327 
328 const struct vmbus_message *
329 vmbus_msghc_poll_result(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
330 {
331 	size_t resp_len;
332 
333 	return (vmbus_xact_poll(mh->mh_xact, &resp_len));
334 }
335 
336 void
337 vmbus_msghc_wakeup(struct vmbus_softc *sc, const struct vmbus_message *msg)
338 {
339 
340 	vmbus_xact_ctx_wakeup(sc->vmbus_xc, msg, sizeof(*msg));
341 }
342 
343 uint32_t
344 vmbus_gpadl_alloc(struct vmbus_softc *sc)
345 {
346 	uint32_t gpadl;
347 
348 again:
349 	gpadl = atomic_fetchadd_int(&sc->vmbus_gpadl, 1);
350 	if (gpadl == 0)
351 		goto again;
352 	return (gpadl);
353 }
354 
355 static int
356 vmbus_connect(struct vmbus_softc *sc, uint32_t version)
357 {
358 	struct vmbus_chanmsg_connect *req;
359 	const struct vmbus_message *msg;
360 	struct vmbus_msghc *mh;
361 	int error, done = 0;
362 
363 	mh = vmbus_msghc_get(sc, sizeof(*req));
364 	if (mh == NULL)
365 		return ENXIO;
366 
367 	req = vmbus_msghc_dataptr(mh);
368 	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CONNECT;
369 	req->chm_ver = version;
370 	req->chm_evtflags = sc->vmbus_evtflags_dma.hv_paddr;
371 	req->chm_mnf1 = sc->vmbus_mnf1_dma.hv_paddr;
372 	req->chm_mnf2 = sc->vmbus_mnf2_dma.hv_paddr;
373 
374 	error = vmbus_msghc_exec(sc, mh);
375 	if (error) {
376 		vmbus_msghc_put(sc, mh);
377 		return error;
378 	}
379 
380 	msg = vmbus_msghc_wait_result(sc, mh);
381 	done = ((const struct vmbus_chanmsg_connect_resp *)
382 	    msg->msg_data)->chm_done;
383 
384 	vmbus_msghc_put(sc, mh);
385 
386 	return (done ? 0 : EOPNOTSUPP);
387 }
388 
389 static int
390 vmbus_init(struct vmbus_softc *sc)
391 {
392 	int i;
393 
394 	for (i = 0; i < nitems(vmbus_version); ++i) {
395 		int error;
396 
397 		error = vmbus_connect(sc, vmbus_version[i]);
398 		if (!error) {
399 			sc->vmbus_version = vmbus_version[i];
400 			device_printf(sc->vmbus_dev, "version %u.%u\n",
401 			    VMBUS_VERSION_MAJOR(sc->vmbus_version),
402 			    VMBUS_VERSION_MINOR(sc->vmbus_version));
403 			return 0;
404 		}
405 	}
406 	return ENXIO;
407 }
408 
409 static void
410 vmbus_disconnect(struct vmbus_softc *sc)
411 {
412 	struct vmbus_chanmsg_disconnect *req;
413 	struct vmbus_msghc *mh;
414 	int error;
415 
416 	mh = vmbus_msghc_get(sc, sizeof(*req));
417 	if (mh == NULL) {
418 		device_printf(sc->vmbus_dev,
419 		    "can not get msg hypercall for disconnect\n");
420 		return;
421 	}
422 
423 	req = vmbus_msghc_dataptr(mh);
424 	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_DISCONNECT;
425 
426 	error = vmbus_msghc_exec_noresult(mh);
427 	vmbus_msghc_put(sc, mh);
428 
429 	if (error) {
430 		device_printf(sc->vmbus_dev,
431 		    "disconnect msg hypercall failed\n");
432 	}
433 }
434 
435 static int
436 vmbus_req_channels(struct vmbus_softc *sc)
437 {
438 	struct vmbus_chanmsg_chrequest *req;
439 	struct vmbus_msghc *mh;
440 	int error;
441 
442 	mh = vmbus_msghc_get(sc, sizeof(*req));
443 	if (mh == NULL)
444 		return ENXIO;
445 
446 	req = vmbus_msghc_dataptr(mh);
447 	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHREQUEST;
448 
449 	error = vmbus_msghc_exec_noresult(mh);
450 	vmbus_msghc_put(sc, mh);
451 
452 	return error;
453 }
454 
455 static void
456 vmbus_scan_done_task(void *xsc, int pending __unused)
457 {
458 	struct vmbus_softc *sc = xsc;
459 
460 	mtx_lock(&Giant);
461 	sc->vmbus_scandone = true;
462 	mtx_unlock(&Giant);
463 	wakeup(&sc->vmbus_scandone);
464 }
465 
466 static void
467 vmbus_scan_done(struct vmbus_softc *sc,
468     const struct vmbus_message *msg __unused)
469 {
470 
471 	taskqueue_enqueue(sc->vmbus_devtq, &sc->vmbus_scandone_task);
472 }
473 
474 static int
475 vmbus_scan(struct vmbus_softc *sc)
476 {
477 	int error;
478 
479 	/*
480 	 * Identify, probe and attach for non-channel devices.
481 	 */
482 	bus_generic_probe(sc->vmbus_dev);
483 	bus_generic_attach(sc->vmbus_dev);
484 
485 	/*
486 	 * This taskqueue serializes vmbus devices' attach and detach
487 	 * for channel offer and rescind messages.
488 	 */
489 	sc->vmbus_devtq = taskqueue_create("vmbus dev", M_WAITOK,
490 	    taskqueue_thread_enqueue, &sc->vmbus_devtq);
491 	taskqueue_start_threads(&sc->vmbus_devtq, 1, PI_NET, "vmbusdev");
492 	TASK_INIT(&sc->vmbus_scandone_task, 0, vmbus_scan_done_task, sc);
493 
494 	/*
495 	 * This taskqueue handles sub-channel detach, so that vmbus
496 	 * device's detach running in vmbus_devtq can drain its sub-
497 	 * channels.
498 	 */
499 	sc->vmbus_subchtq = taskqueue_create("vmbus subch", M_WAITOK,
500 	    taskqueue_thread_enqueue, &sc->vmbus_subchtq);
501 	taskqueue_start_threads(&sc->vmbus_subchtq, 1, PI_NET, "vmbussch");
502 
503 	/*
504 	 * Start vmbus scanning.
505 	 */
506 	error = vmbus_req_channels(sc);
507 	if (error) {
508 		device_printf(sc->vmbus_dev, "channel request failed: %d\n",
509 		    error);
510 		return (error);
511 	}
512 
513 	/*
514 	 * Wait for all vmbus devices from the initial channel offers to be
515 	 * attached.
516 	 */
517 	GIANT_REQUIRED;
518 	while (!sc->vmbus_scandone)
519 		mtx_sleep(&sc->vmbus_scandone, &Giant, 0, "vmbusdev", 0);
520 
521 	if (bootverbose) {
522 		device_printf(sc->vmbus_dev, "device scan, probe and attach "
523 		    "done\n");
524 	}
525 	return (0);
526 }
527 
528 static void
529 vmbus_scan_teardown(struct vmbus_softc *sc)
530 {
531 
532 	GIANT_REQUIRED;
533 	if (sc->vmbus_devtq != NULL) {
534 		mtx_unlock(&Giant);
535 		taskqueue_free(sc->vmbus_devtq);
536 		mtx_lock(&Giant);
537 		sc->vmbus_devtq = NULL;
538 	}
539 	if (sc->vmbus_subchtq != NULL) {
540 		mtx_unlock(&Giant);
541 		taskqueue_free(sc->vmbus_subchtq);
542 		mtx_lock(&Giant);
543 		sc->vmbus_subchtq = NULL;
544 	}
545 }
546 
547 static void
548 vmbus_chanmsg_handle(struct vmbus_softc *sc, const struct vmbus_message *msg)
549 {
550 	vmbus_chanmsg_proc_t msg_proc;
551 	uint32_t msg_type;
552 
553 	msg_type = ((const struct vmbus_chanmsg_hdr *)msg->msg_data)->chm_type;
554 	if (msg_type >= VMBUS_CHANMSG_TYPE_MAX) {
555 		device_printf(sc->vmbus_dev, "unknown message type 0x%x\n",
556 		    msg_type);
557 		return;
558 	}
559 
560 	msg_proc = vmbus_chanmsg_handlers[msg_type];
561 	if (msg_proc != NULL)
562 		msg_proc(sc, msg);
563 
564 	/* Channel specific processing */
565 	vmbus_chan_msgproc(sc, msg);
566 }
567 
568 static void
569 vmbus_msg_task(void *xsc, int pending __unused)
570 {
571 	struct vmbus_softc *sc = xsc;
572 	volatile struct vmbus_message *msg;
573 
574 	msg = VMBUS_PCPU_GET(sc, message, curcpu) + VMBUS_SINT_MESSAGE;
575 	for (;;) {
576 		if (msg->msg_type == HYPERV_MSGTYPE_NONE) {
577 			/* No message */
578 			break;
579 		} else if (msg->msg_type == HYPERV_MSGTYPE_CHANNEL) {
580 			/* Channel message */
581 			vmbus_chanmsg_handle(sc,
582 			    __DEVOLATILE(const struct vmbus_message *, msg));
583 		}
584 
585 		msg->msg_type = HYPERV_MSGTYPE_NONE;
586 		/*
587 		 * Make sure the write to msg_type (i.e. set to
588 		 * HYPERV_MSGTYPE_NONE) happens before we read the
589 		 * msg_flags and EOMing. Otherwise, the EOMing will
590 		 * not deliver any more messages since there is no
591 		 * empty slot
592 		 *
593 		 * NOTE:
594 		 * mb() is used here, since atomic_thread_fence_seq_cst()
595 		 * will become compiler fence on UP kernel.
596 		 */
597 		mb();
598 		if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
599 			/*
600 			 * This will cause message queue rescan to possibly
601 			 * deliver another msg from the hypervisor
602 			 */
603 			wrmsr(MSR_HV_EOM, 0);
604 		}
605 	}
606 }
607 
608 static __inline int
609 vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
610 {
611 	volatile struct vmbus_message *msg;
612 	struct vmbus_message *msg_base;
613 
614 	msg_base = VMBUS_PCPU_GET(sc, message, cpu);
615 
616 	/*
617 	 * Check event timer.
618 	 *
619 	 * TODO: move this to independent IDT vector.
620 	 */
621 	msg = msg_base + VMBUS_SINT_TIMER;
622 	if (msg->msg_type == HYPERV_MSGTYPE_TIMER_EXPIRED) {
623 		msg->msg_type = HYPERV_MSGTYPE_NONE;
624 
625 		vmbus_et_intr(frame);
626 
627 		/*
628 		 * Make sure the write to msg_type (i.e. set to
629 		 * HYPERV_MSGTYPE_NONE) happens before we read the
630 		 * msg_flags and EOMing. Otherwise, the EOMing will
631 		 * not deliver any more messages since there is no
632 		 * empty slot
633 		 *
634 		 * NOTE:
635 		 * mb() is used here, since atomic_thread_fence_seq_cst()
636 		 * will become compiler fence on UP kernel.
637 		 */
638 		mb();
639 		if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
640 			/*
641 			 * This will cause message queue rescan to possibly
642 			 * deliver another msg from the hypervisor
643 			 */
644 			wrmsr(MSR_HV_EOM, 0);
645 		}
646 	}
647 
648 	/*
649 	 * Check events.  Hot path for network and storage I/O data; high rate.
650 	 *
651 	 * NOTE:
652 	 * As recommended by the Windows guest fellows, we check events before
653 	 * checking messages.
654 	 */
655 	sc->vmbus_event_proc(sc, cpu);
656 
657 	/*
658 	 * Check messages.  Mainly management stuffs; ultra low rate.
659 	 */
660 	msg = msg_base + VMBUS_SINT_MESSAGE;
661 	if (__predict_false(msg->msg_type != HYPERV_MSGTYPE_NONE)) {
662 		taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu),
663 		    VMBUS_PCPU_PTR(sc, message_task, cpu));
664 	}
665 
666 	return (FILTER_HANDLED);
667 }
668 
669 void
670 vmbus_handle_intr(struct trapframe *trap_frame)
671 {
672 	struct vmbus_softc *sc = vmbus_get_softc();
673 	int cpu = curcpu;
674 
675 	/*
676 	 * Disable preemption.
677 	 */
678 	critical_enter();
679 
680 	/*
681 	 * Do a little interrupt counting.
682 	 */
683 	(*VMBUS_PCPU_GET(sc, intr_cnt, cpu))++;
684 
685 	vmbus_handle_intr1(sc, trap_frame, cpu);
686 
687 	/*
688 	 * Enable preemption.
689 	 */
690 	critical_exit();
691 }
692 
693 static void
694 vmbus_synic_setup(void *xsc)
695 {
696 	struct vmbus_softc *sc = xsc;
697 	int cpu = curcpu;
698 	uint64_t val, orig;
699 	uint32_t sint;
700 
701 	if (hyperv_features & CPUID_HV_MSR_VP_INDEX) {
702 		/* Save virtual processor id. */
703 		VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
704 	} else {
705 		/* Set virtual processor id to 0 for compatibility. */
706 		VMBUS_PCPU_GET(sc, vcpuid, cpu) = 0;
707 	}
708 
709 	/*
710 	 * Setup the SynIC message.
711 	 */
712 	orig = rdmsr(MSR_HV_SIMP);
713 	val = MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK) |
714 	    ((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
715 	     MSR_HV_SIMP_PGSHIFT);
716 	wrmsr(MSR_HV_SIMP, val);
717 
718 	/*
719 	 * Setup the SynIC event flags.
720 	 */
721 	orig = rdmsr(MSR_HV_SIEFP);
722 	val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
723 	    ((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu)
724 	      >> PAGE_SHIFT) << MSR_HV_SIEFP_PGSHIFT);
725 	wrmsr(MSR_HV_SIEFP, val);
726 
727 
728 	/*
729 	 * Configure and unmask SINT for message and event flags.
730 	 */
731 	sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
732 	orig = rdmsr(sint);
733 	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
734 	    (orig & MSR_HV_SINT_RSVD_MASK);
735 	wrmsr(sint, val);
736 
737 	/*
738 	 * Configure and unmask SINT for timer.
739 	 */
740 	sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
741 	orig = rdmsr(sint);
742 	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
743 	    (orig & MSR_HV_SINT_RSVD_MASK);
744 	wrmsr(sint, val);
745 
746 	/*
747 	 * All done; enable SynIC.
748 	 */
749 	orig = rdmsr(MSR_HV_SCONTROL);
750 	val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK);
751 	wrmsr(MSR_HV_SCONTROL, val);
752 }
753 
754 static void
755 vmbus_synic_teardown(void *arg)
756 {
757 	uint64_t orig;
758 	uint32_t sint;
759 
760 	/*
761 	 * Disable SynIC.
762 	 */
763 	orig = rdmsr(MSR_HV_SCONTROL);
764 	wrmsr(MSR_HV_SCONTROL, (orig & MSR_HV_SCTRL_RSVD_MASK));
765 
766 	/*
767 	 * Mask message and event flags SINT.
768 	 */
769 	sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
770 	orig = rdmsr(sint);
771 	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
772 
773 	/*
774 	 * Mask timer SINT.
775 	 */
776 	sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
777 	orig = rdmsr(sint);
778 	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
779 
780 	/*
781 	 * Teardown SynIC message.
782 	 */
783 	orig = rdmsr(MSR_HV_SIMP);
784 	wrmsr(MSR_HV_SIMP, (orig & MSR_HV_SIMP_RSVD_MASK));
785 
786 	/*
787 	 * Teardown SynIC event flags.
788 	 */
789 	orig = rdmsr(MSR_HV_SIEFP);
790 	wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
791 }
792 
793 static int
794 vmbus_dma_alloc(struct vmbus_softc *sc)
795 {
796 	bus_dma_tag_t parent_dtag;
797 	uint8_t *evtflags;
798 	int cpu;
799 
800 	parent_dtag = bus_get_dma_tag(sc->vmbus_dev);
801 	CPU_FOREACH(cpu) {
802 		void *ptr;
803 
804 		/*
805 		 * Per-cpu messages and event flags.
806 		 */
807 		ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
808 		    PAGE_SIZE, VMBUS_PCPU_PTR(sc, message_dma, cpu),
809 		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
810 		if (ptr == NULL)
811 			return ENOMEM;
812 		VMBUS_PCPU_GET(sc, message, cpu) = ptr;
813 
814 		ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
815 		    PAGE_SIZE, VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
816 		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
817 		if (ptr == NULL)
818 			return ENOMEM;
819 		VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
820 	}
821 
822 	evtflags = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
823 	    PAGE_SIZE, &sc->vmbus_evtflags_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
824 	if (evtflags == NULL)
825 		return ENOMEM;
826 	sc->vmbus_rx_evtflags = (u_long *)evtflags;
827 	sc->vmbus_tx_evtflags = (u_long *)(evtflags + (PAGE_SIZE / 2));
828 	sc->vmbus_evtflags = evtflags;
829 
830 	sc->vmbus_mnf1 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
831 	    PAGE_SIZE, &sc->vmbus_mnf1_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
832 	if (sc->vmbus_mnf1 == NULL)
833 		return ENOMEM;
834 
835 	sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
836 	    sizeof(struct vmbus_mnf), &sc->vmbus_mnf2_dma,
837 	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
838 	if (sc->vmbus_mnf2 == NULL)
839 		return ENOMEM;
840 
841 	return 0;
842 }
843 
844 static void
845 vmbus_dma_free(struct vmbus_softc *sc)
846 {
847 	int cpu;
848 
849 	if (sc->vmbus_evtflags != NULL) {
850 		hyperv_dmamem_free(&sc->vmbus_evtflags_dma, sc->vmbus_evtflags);
851 		sc->vmbus_evtflags = NULL;
852 		sc->vmbus_rx_evtflags = NULL;
853 		sc->vmbus_tx_evtflags = NULL;
854 	}
855 	if (sc->vmbus_mnf1 != NULL) {
856 		hyperv_dmamem_free(&sc->vmbus_mnf1_dma, sc->vmbus_mnf1);
857 		sc->vmbus_mnf1 = NULL;
858 	}
859 	if (sc->vmbus_mnf2 != NULL) {
860 		hyperv_dmamem_free(&sc->vmbus_mnf2_dma, sc->vmbus_mnf2);
861 		sc->vmbus_mnf2 = NULL;
862 	}
863 
864 	CPU_FOREACH(cpu) {
865 		if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) {
866 			hyperv_dmamem_free(
867 			    VMBUS_PCPU_PTR(sc, message_dma, cpu),
868 			    VMBUS_PCPU_GET(sc, message, cpu));
869 			VMBUS_PCPU_GET(sc, message, cpu) = NULL;
870 		}
871 		if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) {
872 			hyperv_dmamem_free(
873 			    VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
874 			    VMBUS_PCPU_GET(sc, event_flags, cpu));
875 			VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL;
876 		}
877 	}
878 }
879 
880 static int
881 vmbus_intr_setup(struct vmbus_softc *sc)
882 {
883 	int cpu;
884 
885 	CPU_FOREACH(cpu) {
886 		char buf[MAXCOMLEN + 1];
887 		cpuset_t cpu_mask;
888 
889 		/* Allocate an interrupt counter for Hyper-V interrupt */
890 		snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
891 		intrcnt_add(buf, VMBUS_PCPU_PTR(sc, intr_cnt, cpu));
892 
893 		/*
894 		 * Setup taskqueue to handle events.  Task will be per-
895 		 * channel.
896 		 */
897 		VMBUS_PCPU_GET(sc, event_tq, cpu) = taskqueue_create_fast(
898 		    "hyperv event", M_WAITOK, taskqueue_thread_enqueue,
899 		    VMBUS_PCPU_PTR(sc, event_tq, cpu));
900 		CPU_SETOF(cpu, &cpu_mask);
901 		taskqueue_start_threads_cpuset(
902 		    VMBUS_PCPU_PTR(sc, event_tq, cpu), 1, PI_NET, &cpu_mask,
903 		    "hvevent%d", cpu);
904 
905 		/*
906 		 * Setup tasks and taskqueues to handle messages.
907 		 */
908 		VMBUS_PCPU_GET(sc, message_tq, cpu) = taskqueue_create_fast(
909 		    "hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
910 		    VMBUS_PCPU_PTR(sc, message_tq, cpu));
911 		CPU_SETOF(cpu, &cpu_mask);
912 		taskqueue_start_threads_cpuset(
913 		    VMBUS_PCPU_PTR(sc, message_tq, cpu), 1, PI_NET, &cpu_mask,
914 		    "hvmsg%d", cpu);
915 		TASK_INIT(VMBUS_PCPU_PTR(sc, message_task, cpu), 0,
916 		    vmbus_msg_task, sc);
917 	}
918 
919 	/*
920 	 * All Hyper-V ISR required resources are setup, now let's find a
921 	 * free IDT vector for Hyper-V ISR and set it up.
922 	 */
923 	sc->vmbus_idtvec = lapic_ipi_alloc(IDTVEC(vmbus_isr));
924 	if (sc->vmbus_idtvec < 0) {
925 		device_printf(sc->vmbus_dev, "cannot find free IDT vector\n");
926 		return ENXIO;
927 	}
928 	if (bootverbose) {
929 		device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n",
930 		    sc->vmbus_idtvec);
931 	}
932 	return 0;
933 }
934 
935 static void
936 vmbus_intr_teardown(struct vmbus_softc *sc)
937 {
938 	int cpu;
939 
940 	if (sc->vmbus_idtvec >= 0) {
941 		lapic_ipi_free(sc->vmbus_idtvec);
942 		sc->vmbus_idtvec = -1;
943 	}
944 
945 	CPU_FOREACH(cpu) {
946 		if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) {
947 			taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu));
948 			VMBUS_PCPU_GET(sc, event_tq, cpu) = NULL;
949 		}
950 		if (VMBUS_PCPU_GET(sc, message_tq, cpu) != NULL) {
951 			taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu),
952 			    VMBUS_PCPU_PTR(sc, message_task, cpu));
953 			taskqueue_free(VMBUS_PCPU_GET(sc, message_tq, cpu));
954 			VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL;
955 		}
956 	}
957 }
958 
959 static int
960 vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
961 {
962 	return (ENOENT);
963 }
964 
965 static int
966 vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen)
967 {
968 	const struct vmbus_channel *chan;
969 	char guidbuf[HYPERV_GUID_STRLEN];
970 
971 	chan = vmbus_get_channel(child);
972 	if (chan == NULL) {
973 		/* Event timer device, which does not belong to a channel */
974 		return (0);
975 	}
976 
977 	strlcat(buf, "classid=", buflen);
978 	hyperv_guid2str(&chan->ch_guid_type, guidbuf, sizeof(guidbuf));
979 	strlcat(buf, guidbuf, buflen);
980 
981 	strlcat(buf, " deviceid=", buflen);
982 	hyperv_guid2str(&chan->ch_guid_inst, guidbuf, sizeof(guidbuf));
983 	strlcat(buf, guidbuf, buflen);
984 
985 	return (0);
986 }
987 
988 int
989 vmbus_add_child(struct vmbus_channel *chan)
990 {
991 	struct vmbus_softc *sc = chan->ch_vmbus;
992 	device_t parent = sc->vmbus_dev;
993 
994 	mtx_lock(&Giant);
995 
996 	chan->ch_dev = device_add_child(parent, NULL, -1);
997 	if (chan->ch_dev == NULL) {
998 		mtx_unlock(&Giant);
999 		device_printf(parent, "device_add_child for chan%u failed\n",
1000 		    chan->ch_id);
1001 		return (ENXIO);
1002 	}
1003 	device_set_ivars(chan->ch_dev, chan);
1004 	device_probe_and_attach(chan->ch_dev);
1005 
1006 	mtx_unlock(&Giant);
1007 	return (0);
1008 }
1009 
1010 int
1011 vmbus_delete_child(struct vmbus_channel *chan)
1012 {
1013 	int error = 0;
1014 
1015 	mtx_lock(&Giant);
1016 	if (chan->ch_dev != NULL) {
1017 		error = device_delete_child(chan->ch_vmbus->vmbus_dev,
1018 		    chan->ch_dev);
1019 		chan->ch_dev = NULL;
1020 	}
1021 	mtx_unlock(&Giant);
1022 	return (error);
1023 }
1024 
1025 static int
1026 vmbus_sysctl_version(SYSCTL_HANDLER_ARGS)
1027 {
1028 	struct vmbus_softc *sc = arg1;
1029 	char verstr[16];
1030 
1031 	snprintf(verstr, sizeof(verstr), "%u.%u",
1032 	    VMBUS_VERSION_MAJOR(sc->vmbus_version),
1033 	    VMBUS_VERSION_MINOR(sc->vmbus_version));
1034 	return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
1035 }
1036 
1037 /*
1038  * We need the function to make sure the MMIO resource is allocated from the
1039  * ranges found in _CRS.
1040  *
1041  * For the release function, we can use bus_generic_release_resource().
1042  */
1043 static struct resource *
1044 vmbus_alloc_resource(device_t dev, device_t child, int type, int *rid,
1045     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
1046 {
1047 	device_t parent = device_get_parent(dev);
1048 	struct resource *res;
1049 
1050 #ifdef NEW_PCIB
1051 	if (type == SYS_RES_MEMORY) {
1052 		struct vmbus_softc *sc = device_get_softc(dev);
1053 
1054 		res = pcib_host_res_alloc(&sc->vmbus_mmio_res, child, type,
1055 		    rid, start, end, count, flags);
1056 	} else
1057 #endif
1058 	{
1059 		res = BUS_ALLOC_RESOURCE(parent, child, type, rid, start,
1060 		    end, count, flags);
1061 	}
1062 
1063 	return (res);
1064 }
1065 
1066 static device_t
1067 get_nexus(device_t vmbus)
1068 {
1069 	device_t acpi = device_get_parent(vmbus);
1070 	device_t nexus = device_get_parent(acpi);
1071 	return (nexus);
1072 }
1073 
1074 static int
1075 vmbus_alloc_msi(device_t bus, device_t dev, int count, int maxcount, int *irqs)
1076 {
1077 	return (PCIB_ALLOC_MSI(get_nexus(bus), dev, count, maxcount, irqs));
1078 }
1079 
1080 static int
1081 vmbus_release_msi(device_t bus, device_t dev, int count, int *irqs)
1082 {
1083 	return (PCIB_RELEASE_MSI(get_nexus(bus), dev, count, irqs));
1084 }
1085 
1086 static int
1087 vmbus_alloc_msix(device_t bus, device_t dev, int *irq)
1088 {
1089 	return (PCIB_ALLOC_MSIX(get_nexus(bus), dev, irq));
1090 }
1091 
1092 static int
1093 vmbus_release_msix(device_t bus, device_t dev, int irq)
1094 {
1095 	return (PCIB_RELEASE_MSIX(get_nexus(bus), dev, irq));
1096 }
1097 
1098 static int
1099 vmbus_map_msi(device_t bus, device_t dev, int irq, uint64_t *addr,
1100 	uint32_t *data)
1101 {
1102 	return (PCIB_MAP_MSI(get_nexus(bus), dev, irq, addr, data));
1103 }
1104 
1105 static uint32_t
1106 vmbus_get_version_method(device_t bus, device_t dev)
1107 {
1108 	struct vmbus_softc *sc = device_get_softc(bus);
1109 
1110 	return sc->vmbus_version;
1111 }
1112 
1113 static int
1114 vmbus_probe_guid_method(device_t bus, device_t dev,
1115     const struct hyperv_guid *guid)
1116 {
1117 	const struct vmbus_channel *chan = vmbus_get_channel(dev);
1118 
1119 	if (memcmp(&chan->ch_guid_type, guid, sizeof(struct hyperv_guid)) == 0)
1120 		return 0;
1121 	return ENXIO;
1122 }
1123 
1124 static uint32_t
1125 vmbus_get_vcpu_id_method(device_t bus, device_t dev, int cpu)
1126 {
1127 	const struct vmbus_softc *sc = device_get_softc(bus);
1128 
1129 	return (VMBUS_PCPU_GET(sc, vcpuid, cpu));
1130 }
1131 
1132 static struct taskqueue *
1133 vmbus_get_eventtq_method(device_t bus, device_t dev __unused, int cpu)
1134 {
1135 	const struct vmbus_softc *sc = device_get_softc(bus);
1136 
1137 	KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpu%d", cpu));
1138 	return (VMBUS_PCPU_GET(sc, event_tq, cpu));
1139 }
1140 
1141 #ifdef NEW_PCIB
1142 #define VTPM_BASE_ADDR 0xfed40000
1143 #define FOUR_GB (1ULL << 32)
1144 
1145 enum parse_pass { parse_64, parse_32 };
1146 
1147 struct parse_context {
1148 	device_t vmbus_dev;
1149 	enum parse_pass pass;
1150 };
1151 
1152 static ACPI_STATUS
1153 parse_crs(ACPI_RESOURCE *res, void *ctx)
1154 {
1155 	const struct parse_context *pc = ctx;
1156 	device_t vmbus_dev = pc->vmbus_dev;
1157 
1158 	struct vmbus_softc *sc = device_get_softc(vmbus_dev);
1159 	UINT64 start, end;
1160 
1161 	switch (res->Type) {
1162 	case ACPI_RESOURCE_TYPE_ADDRESS32:
1163 		start = res->Data.Address32.Address.Minimum;
1164 		end = res->Data.Address32.Address.Maximum;
1165 		break;
1166 
1167 	case ACPI_RESOURCE_TYPE_ADDRESS64:
1168 		start = res->Data.Address64.Address.Minimum;
1169 		end = res->Data.Address64.Address.Maximum;
1170 		break;
1171 
1172 	default:
1173 		/* Unused types. */
1174 		return (AE_OK);
1175 	}
1176 
1177 	/*
1178 	 * We don't use <1MB addresses.
1179 	 */
1180 	if (end < 0x100000)
1181 		return (AE_OK);
1182 
1183 	/* Don't conflict with vTPM. */
1184 	if (end >= VTPM_BASE_ADDR && start < VTPM_BASE_ADDR)
1185 		end = VTPM_BASE_ADDR - 1;
1186 
1187 	if ((pc->pass == parse_32 && start < FOUR_GB) ||
1188 	    (pc->pass == parse_64 && start >= FOUR_GB))
1189 		pcib_host_res_decodes(&sc->vmbus_mmio_res, SYS_RES_MEMORY,
1190 		    start, end, 0);
1191 
1192 	return (AE_OK);
1193 }
1194 
1195 static void
1196 vmbus_get_crs(device_t dev, device_t vmbus_dev, enum parse_pass pass)
1197 {
1198 	struct parse_context pc;
1199 	ACPI_STATUS status;
1200 
1201 	if (bootverbose)
1202 		device_printf(dev, "walking _CRS, pass=%d\n", pass);
1203 
1204 	pc.vmbus_dev = vmbus_dev;
1205 	pc.pass = pass;
1206 	status = AcpiWalkResources(acpi_get_handle(dev), "_CRS",
1207 			parse_crs, &pc);
1208 
1209 	if (bootverbose && ACPI_FAILURE(status))
1210 		device_printf(dev, "_CRS: not found, pass=%d\n", pass);
1211 }
1212 
1213 static void
1214 vmbus_get_mmio_res_pass(device_t dev, enum parse_pass pass)
1215 {
1216 	device_t acpi0, pcib0 = NULL;
1217 	device_t *children;
1218 	int i, count;
1219 
1220 	/* Try to find _CRS on VMBus device */
1221 	vmbus_get_crs(dev, dev, pass);
1222 
1223 	/* Try to find _CRS on VMBus device's parent */
1224 	acpi0 = device_get_parent(dev);
1225 	vmbus_get_crs(acpi0, dev, pass);
1226 
1227 	/* Try to locate pcib0 and find _CRS on it */
1228 	if (device_get_children(acpi0, &children, &count) != 0)
1229 		return;
1230 
1231 	for (i = 0; i < count; i++) {
1232 		if (!device_is_attached(children[i]))
1233 			continue;
1234 
1235 		if (strcmp("pcib0", device_get_nameunit(children[i])))
1236 			continue;
1237 
1238 		pcib0 = children[i];
1239 		break;
1240 	}
1241 
1242 	if (pcib0)
1243 		vmbus_get_crs(pcib0, dev, pass);
1244 
1245 	free(children, M_TEMP);
1246 }
1247 
1248 static void
1249 vmbus_get_mmio_res(device_t dev)
1250 {
1251 	struct vmbus_softc *sc = device_get_softc(dev);
1252 	/*
1253 	 * We walk the resources twice to make sure that: in the resource
1254 	 * list, the 32-bit resources appear behind the 64-bit resources.
1255 	 * NB: resource_list_add() uses INSERT_TAIL. This way, when we
1256 	 * iterate through the list to find a range for a 64-bit BAR in
1257 	 * vmbus_alloc_resource(), we can make sure we try to use >4GB
1258 	 * ranges first.
1259 	 */
1260 	pcib_host_res_init(dev, &sc->vmbus_mmio_res);
1261 
1262 	vmbus_get_mmio_res_pass(dev, parse_64);
1263 	vmbus_get_mmio_res_pass(dev, parse_32);
1264 }
1265 
1266 static void
1267 vmbus_free_mmio_res(device_t dev)
1268 {
1269 	struct vmbus_softc *sc = device_get_softc(dev);
1270 
1271 	pcib_host_res_free(dev, &sc->vmbus_mmio_res);
1272 }
1273 #endif	/* NEW_PCIB */
1274 
1275 static int
1276 vmbus_probe(device_t dev)
1277 {
1278 	char *id[] = { "VMBUS", NULL };
1279 
1280 	if (ACPI_ID_PROBE(device_get_parent(dev), dev, id) == NULL ||
1281 	    device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV ||
1282 	    (hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
1283 		return (ENXIO);
1284 
1285 	device_set_desc(dev, "Hyper-V Vmbus");
1286 
1287 	return (BUS_PROBE_DEFAULT);
1288 }
1289 
1290 /**
1291  * @brief Main vmbus driver initialization routine.
1292  *
1293  * Here, we
1294  * - initialize the vmbus driver context
1295  * - setup various driver entry points
1296  * - invoke the vmbus hv main init routine
1297  * - get the irq resource
1298  * - invoke the vmbus to add the vmbus root device
1299  * - setup the vmbus root device
1300  * - retrieve the channel offers
1301  */
1302 static int
1303 vmbus_doattach(struct vmbus_softc *sc)
1304 {
1305 	struct sysctl_oid_list *child;
1306 	struct sysctl_ctx_list *ctx;
1307 	int ret;
1308 
1309 	if (sc->vmbus_flags & VMBUS_FLAG_ATTACHED)
1310 		return (0);
1311 
1312 #ifdef NEW_PCIB
1313 	vmbus_get_mmio_res(sc->vmbus_dev);
1314 #endif
1315 
1316 	sc->vmbus_flags |= VMBUS_FLAG_ATTACHED;
1317 
1318 	sc->vmbus_gpadl = VMBUS_GPADL_START;
1319 	mtx_init(&sc->vmbus_prichan_lock, "vmbus prichan", NULL, MTX_DEF);
1320 	TAILQ_INIT(&sc->vmbus_prichans);
1321 	mtx_init(&sc->vmbus_chan_lock, "vmbus channel", NULL, MTX_DEF);
1322 	TAILQ_INIT(&sc->vmbus_chans);
1323 	sc->vmbus_chmap = malloc(
1324 	    sizeof(struct vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF,
1325 	    M_WAITOK | M_ZERO);
1326 
1327 	/*
1328 	 * Create context for "post message" Hypercalls
1329 	 */
1330 	sc->vmbus_xc = vmbus_xact_ctx_create(bus_get_dma_tag(sc->vmbus_dev),
1331 	    HYPERCALL_POSTMSGIN_SIZE, VMBUS_MSG_SIZE,
1332 	    sizeof(struct vmbus_msghc));
1333 	if (sc->vmbus_xc == NULL) {
1334 		ret = ENXIO;
1335 		goto cleanup;
1336 	}
1337 
1338 	/*
1339 	 * Allocate DMA stuffs.
1340 	 */
1341 	ret = vmbus_dma_alloc(sc);
1342 	if (ret != 0)
1343 		goto cleanup;
1344 
1345 	/*
1346 	 * Setup interrupt.
1347 	 */
1348 	ret = vmbus_intr_setup(sc);
1349 	if (ret != 0)
1350 		goto cleanup;
1351 
1352 	/*
1353 	 * Setup SynIC.
1354 	 */
1355 	if (bootverbose)
1356 		device_printf(sc->vmbus_dev, "smp_started = %d\n", smp_started);
1357 	smp_rendezvous(NULL, vmbus_synic_setup, NULL, sc);
1358 	sc->vmbus_flags |= VMBUS_FLAG_SYNIC;
1359 
1360 	/*
1361 	 * Initialize vmbus, e.g. connect to Hypervisor.
1362 	 */
1363 	ret = vmbus_init(sc);
1364 	if (ret != 0)
1365 		goto cleanup;
1366 
1367 	if (sc->vmbus_version == VMBUS_VERSION_WS2008 ||
1368 	    sc->vmbus_version == VMBUS_VERSION_WIN7)
1369 		sc->vmbus_event_proc = vmbus_event_proc_compat;
1370 	else
1371 		sc->vmbus_event_proc = vmbus_event_proc;
1372 
1373 	ret = vmbus_scan(sc);
1374 	if (ret != 0)
1375 		goto cleanup;
1376 
1377 	ctx = device_get_sysctl_ctx(sc->vmbus_dev);
1378 	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vmbus_dev));
1379 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "version",
1380 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
1381 	    vmbus_sysctl_version, "A", "vmbus version");
1382 
1383 	return (ret);
1384 
1385 cleanup:
1386 	vmbus_scan_teardown(sc);
1387 	vmbus_intr_teardown(sc);
1388 	vmbus_dma_free(sc);
1389 	if (sc->vmbus_xc != NULL) {
1390 		vmbus_xact_ctx_destroy(sc->vmbus_xc);
1391 		sc->vmbus_xc = NULL;
1392 	}
1393 	free(sc->vmbus_chmap, M_DEVBUF);
1394 	mtx_destroy(&sc->vmbus_prichan_lock);
1395 	mtx_destroy(&sc->vmbus_chan_lock);
1396 
1397 	return (ret);
1398 }
1399 
1400 static void
1401 vmbus_event_proc_dummy(struct vmbus_softc *sc __unused, int cpu __unused)
1402 {
1403 }
1404 
1405 static int
1406 vmbus_attach(device_t dev)
1407 {
1408 	vmbus_sc = device_get_softc(dev);
1409 	vmbus_sc->vmbus_dev = dev;
1410 	vmbus_sc->vmbus_idtvec = -1;
1411 
1412 	/*
1413 	 * Event processing logic will be configured:
1414 	 * - After the vmbus protocol version negotiation.
1415 	 * - Before we request channel offers.
1416 	 */
1417 	vmbus_sc->vmbus_event_proc = vmbus_event_proc_dummy;
1418 
1419 #ifndef EARLY_AP_STARTUP
1420 	/*
1421 	 * If the system has already booted and thread
1422 	 * scheduling is possible indicated by the global
1423 	 * cold set to zero, we just call the driver
1424 	 * initialization directly.
1425 	 */
1426 	if (!cold)
1427 #endif
1428 		vmbus_doattach(vmbus_sc);
1429 
1430 	return (0);
1431 }
1432 
1433 static int
1434 vmbus_detach(device_t dev)
1435 {
1436 	struct vmbus_softc *sc = device_get_softc(dev);
1437 
1438 	bus_generic_detach(dev);
1439 	vmbus_chan_destroy_all(sc);
1440 
1441 	vmbus_scan_teardown(sc);
1442 
1443 	vmbus_disconnect(sc);
1444 
1445 	if (sc->vmbus_flags & VMBUS_FLAG_SYNIC) {
1446 		sc->vmbus_flags &= ~VMBUS_FLAG_SYNIC;
1447 		smp_rendezvous(NULL, vmbus_synic_teardown, NULL, NULL);
1448 	}
1449 
1450 	vmbus_intr_teardown(sc);
1451 	vmbus_dma_free(sc);
1452 
1453 	if (sc->vmbus_xc != NULL) {
1454 		vmbus_xact_ctx_destroy(sc->vmbus_xc);
1455 		sc->vmbus_xc = NULL;
1456 	}
1457 
1458 	free(sc->vmbus_chmap, M_DEVBUF);
1459 	mtx_destroy(&sc->vmbus_prichan_lock);
1460 	mtx_destroy(&sc->vmbus_chan_lock);
1461 
1462 #ifdef NEW_PCIB
1463 	vmbus_free_mmio_res(dev);
1464 #endif
1465 
1466 	return (0);
1467 }
1468 
1469 #ifndef EARLY_AP_STARTUP
1470 
1471 static void
1472 vmbus_sysinit(void *arg __unused)
1473 {
1474 	struct vmbus_softc *sc = vmbus_get_softc();
1475 
1476 	if (vm_guest != VM_GUEST_HV || sc == NULL)
1477 		return;
1478 
1479 	/*
1480 	 * If the system has already booted and thread
1481 	 * scheduling is possible, as indicated by the
1482 	 * global cold set to zero, we just call the driver
1483 	 * initialization directly.
1484 	 */
1485 	if (!cold)
1486 		vmbus_doattach(sc);
1487 }
1488 /*
1489  * NOTE:
1490  * We have to start as the last step of SI_SUB_SMP, i.e. after SMP is
1491  * initialized.
1492  */
1493 SYSINIT(vmbus_initialize, SI_SUB_SMP, SI_ORDER_ANY, vmbus_sysinit, NULL);
1494 
1495 #endif	/* !EARLY_AP_STARTUP */
1496