]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/hyperv/vmbus/vmbus.c
MFC 302636-302638,302692
[FreeBSD/stable/10.git] / sys / dev / hyperv / vmbus / vmbus.c
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/proc.h>
42 #include <sys/sysctl.h>
43 #include <sys/syslog.h>
44 #include <sys/systm.h>
45 #include <sys/rtprio.h>
46 #include <sys/interrupt.h>
47 #include <sys/sx.h>
48 #include <sys/taskqueue.h>
49 #include <sys/mutex.h>
50 #include <sys/smp.h>
51
52 #include <machine/resource.h>
53 #include <sys/rman.h>
54
55 #include <machine/stdarg.h>
56 #include <machine/intr_machdep.h>
57 #include <machine/md_var.h>
58 #include <machine/segments.h>
59 #include <sys/pcpu.h>
60 #include <machine/apicvar.h>
61
62 #include <dev/hyperv/include/hyperv.h>
63 #include <dev/hyperv/vmbus/hv_vmbus_priv.h>
64 #include <dev/hyperv/vmbus/hyperv_reg.h>
65 #include <dev/hyperv/vmbus/hyperv_var.h>
66 #include <dev/hyperv/vmbus/vmbus_reg.h>
67 #include <dev/hyperv/vmbus/vmbus_var.h>
68
69 #include <contrib/dev/acpica/include/acpi.h>
70 #include "acpi_if.h"
71 #include "vmbus_if.h"
72
73 #define VMBUS_GPADL_START               0xe1e10
74
75 struct vmbus_msghc {
76         struct hypercall_postmsg_in     *mh_inprm;
77         struct hypercall_postmsg_in     mh_inprm_save;
78         struct hyperv_dma               mh_inprm_dma;
79
80         struct vmbus_message            *mh_resp;
81         struct vmbus_message            mh_resp0;
82 };
83
84 struct vmbus_msghc_ctx {
85         struct vmbus_msghc              *mhc_free;
86         struct mtx                      mhc_free_lock;
87         uint32_t                        mhc_flags;
88
89         struct vmbus_msghc              *mhc_active;
90         struct mtx                      mhc_active_lock;
91 };
92
93 #define VMBUS_MSGHC_CTXF_DESTROY        0x0001
94
95 static int                      vmbus_init(struct vmbus_softc *);
96 static int                      vmbus_connect(struct vmbus_softc *, uint32_t);
97 static int                      vmbus_req_channels(struct vmbus_softc *sc);
98 static void                     vmbus_disconnect(struct vmbus_softc *);
99 static int                      vmbus_scan(struct vmbus_softc *);
100 static void                     vmbus_scan_wait(struct vmbus_softc *);
101 static void                     vmbus_scan_newdev(struct vmbus_softc *);
102
103 static int                      vmbus_sysctl_version(SYSCTL_HANDLER_ARGS);
104
105 static struct vmbus_msghc_ctx   *vmbus_msghc_ctx_create(bus_dma_tag_t);
106 static void                     vmbus_msghc_ctx_destroy(
107                                     struct vmbus_msghc_ctx *);
108 static void                     vmbus_msghc_ctx_free(struct vmbus_msghc_ctx *);
109 static struct vmbus_msghc       *vmbus_msghc_alloc(bus_dma_tag_t);
110 static void                     vmbus_msghc_free(struct vmbus_msghc *);
111 static struct vmbus_msghc       *vmbus_msghc_get1(struct vmbus_msghc_ctx *,
112                                     uint32_t);
113
114 struct vmbus_softc      *vmbus_sc;
115
116 extern inthand_t IDTVEC(rsvd), IDTVEC(vmbus_isr);
117
118 static const uint32_t           vmbus_version[] = {
119         VMBUS_VERSION_WIN8_1,
120         VMBUS_VERSION_WIN8,
121         VMBUS_VERSION_WIN7,
122         VMBUS_VERSION_WS2008
123 };
124
125 static struct vmbus_msghc *
126 vmbus_msghc_alloc(bus_dma_tag_t parent_dtag)
127 {
128         struct vmbus_msghc *mh;
129
130         mh = malloc(sizeof(*mh), M_DEVBUF, M_WAITOK | M_ZERO);
131
132         mh->mh_inprm = hyperv_dmamem_alloc(parent_dtag,
133             HYPERCALL_POSTMSGIN_ALIGN, 0, HYPERCALL_POSTMSGIN_SIZE,
134             &mh->mh_inprm_dma, BUS_DMA_WAITOK);
135         if (mh->mh_inprm == NULL) {
136                 free(mh, M_DEVBUF);
137                 return NULL;
138         }
139         return mh;
140 }
141
142 static void
143 vmbus_msghc_free(struct vmbus_msghc *mh)
144 {
145         hyperv_dmamem_free(&mh->mh_inprm_dma, mh->mh_inprm);
146         free(mh, M_DEVBUF);
147 }
148
149 static void
150 vmbus_msghc_ctx_free(struct vmbus_msghc_ctx *mhc)
151 {
152         KASSERT(mhc->mhc_active == NULL, ("still have active msg hypercall"));
153         KASSERT(mhc->mhc_free == NULL, ("still have hypercall msg"));
154
155         mtx_destroy(&mhc->mhc_free_lock);
156         mtx_destroy(&mhc->mhc_active_lock);
157         free(mhc, M_DEVBUF);
158 }
159
160 static struct vmbus_msghc_ctx *
161 vmbus_msghc_ctx_create(bus_dma_tag_t parent_dtag)
162 {
163         struct vmbus_msghc_ctx *mhc;
164
165         mhc = malloc(sizeof(*mhc), M_DEVBUF, M_WAITOK | M_ZERO);
166         mtx_init(&mhc->mhc_free_lock, "vmbus msghc free", NULL, MTX_DEF);
167         mtx_init(&mhc->mhc_active_lock, "vmbus msghc act", NULL, MTX_DEF);
168
169         mhc->mhc_free = vmbus_msghc_alloc(parent_dtag);
170         if (mhc->mhc_free == NULL) {
171                 vmbus_msghc_ctx_free(mhc);
172                 return NULL;
173         }
174         return mhc;
175 }
176
177 static struct vmbus_msghc *
178 vmbus_msghc_get1(struct vmbus_msghc_ctx *mhc, uint32_t dtor_flag)
179 {
180         struct vmbus_msghc *mh;
181
182         mtx_lock(&mhc->mhc_free_lock);
183
184         while ((mhc->mhc_flags & dtor_flag) == 0 && mhc->mhc_free == NULL) {
185                 mtx_sleep(&mhc->mhc_free, &mhc->mhc_free_lock, 0,
186                     "gmsghc", 0);
187         }
188         if (mhc->mhc_flags & dtor_flag) {
189                 /* Being destroyed */
190                 mh = NULL;
191         } else {
192                 mh = mhc->mhc_free;
193                 KASSERT(mh != NULL, ("no free hypercall msg"));
194                 KASSERT(mh->mh_resp == NULL,
195                     ("hypercall msg has pending response"));
196                 mhc->mhc_free = NULL;
197         }
198
199         mtx_unlock(&mhc->mhc_free_lock);
200
201         return mh;
202 }
203
204 void
205 vmbus_msghc_reset(struct vmbus_msghc *mh, size_t dsize)
206 {
207         struct hypercall_postmsg_in *inprm;
208
209         if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX)
210                 panic("invalid data size %zu", dsize);
211
212         inprm = mh->mh_inprm;
213         memset(inprm, 0, HYPERCALL_POSTMSGIN_SIZE);
214         inprm->hc_connid = VMBUS_CONNID_MESSAGE;
215         inprm->hc_msgtype = HYPERV_MSGTYPE_CHANNEL;
216         inprm->hc_dsize = dsize;
217 }
218
219 struct vmbus_msghc *
220 vmbus_msghc_get(struct vmbus_softc *sc, size_t dsize)
221 {
222         struct vmbus_msghc *mh;
223
224         if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX)
225                 panic("invalid data size %zu", dsize);
226
227         mh = vmbus_msghc_get1(sc->vmbus_msg_hc, VMBUS_MSGHC_CTXF_DESTROY);
228         if (mh == NULL)
229                 return NULL;
230
231         vmbus_msghc_reset(mh, dsize);
232         return mh;
233 }
234
235 void
236 vmbus_msghc_put(struct vmbus_softc *sc, struct vmbus_msghc *mh)
237 {
238         struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc;
239
240         KASSERT(mhc->mhc_active == NULL, ("msg hypercall is active"));
241         mh->mh_resp = NULL;
242
243         mtx_lock(&mhc->mhc_free_lock);
244         KASSERT(mhc->mhc_free == NULL, ("has free hypercall msg"));
245         mhc->mhc_free = mh;
246         mtx_unlock(&mhc->mhc_free_lock);
247         wakeup(&mhc->mhc_free);
248 }
249
250 void *
251 vmbus_msghc_dataptr(struct vmbus_msghc *mh)
252 {
253         return mh->mh_inprm->hc_data;
254 }
255
256 static void
257 vmbus_msghc_ctx_destroy(struct vmbus_msghc_ctx *mhc)
258 {
259         struct vmbus_msghc *mh;
260
261         mtx_lock(&mhc->mhc_free_lock);
262         mhc->mhc_flags |= VMBUS_MSGHC_CTXF_DESTROY;
263         mtx_unlock(&mhc->mhc_free_lock);
264         wakeup(&mhc->mhc_free);
265
266         mh = vmbus_msghc_get1(mhc, 0);
267         if (mh == NULL)
268                 panic("can't get msghc");
269
270         vmbus_msghc_free(mh);
271         vmbus_msghc_ctx_free(mhc);
272 }
273
274 int
275 vmbus_msghc_exec_noresult(struct vmbus_msghc *mh)
276 {
277         sbintime_t time = SBT_1MS;
278         int i;
279
280         /*
281          * Save the input parameter so that we could restore the input
282          * parameter if the Hypercall failed.
283          *
284          * XXX
285          * Is this really necessary?!  i.e. Will the Hypercall ever
286          * overwrite the input parameter?
287          */
288         memcpy(&mh->mh_inprm_save, mh->mh_inprm, HYPERCALL_POSTMSGIN_SIZE);
289
290         /*
291          * In order to cope with transient failures, e.g. insufficient
292          * resources on host side, we retry the post message Hypercall
293          * several times.  20 retries seem sufficient.
294          */
295 #define HC_RETRY_MAX    20
296
297         for (i = 0; i < HC_RETRY_MAX; ++i) {
298                 uint64_t status;
299
300                 status = hypercall_post_message(mh->mh_inprm_dma.hv_paddr);
301                 if (status == HYPERCALL_STATUS_SUCCESS)
302                         return 0;
303
304                 pause_sbt("hcpmsg", time, 0, C_HARDCLOCK);
305                 if (time < SBT_1S * 2)
306                         time *= 2;
307
308                 /* Restore input parameter and try again */
309                 memcpy(mh->mh_inprm, &mh->mh_inprm_save,
310                     HYPERCALL_POSTMSGIN_SIZE);
311         }
312
313 #undef HC_RETRY_MAX
314
315         return EIO;
316 }
317
318 int
319 vmbus_msghc_exec(struct vmbus_softc *sc, struct vmbus_msghc *mh)
320 {
321         struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc;
322         int error;
323
324         KASSERT(mh->mh_resp == NULL, ("hypercall msg has pending response"));
325
326         mtx_lock(&mhc->mhc_active_lock);
327         KASSERT(mhc->mhc_active == NULL, ("pending active msg hypercall"));
328         mhc->mhc_active = mh;
329         mtx_unlock(&mhc->mhc_active_lock);
330
331         error = vmbus_msghc_exec_noresult(mh);
332         if (error) {
333                 mtx_lock(&mhc->mhc_active_lock);
334                 KASSERT(mhc->mhc_active == mh, ("msghc mismatch"));
335                 mhc->mhc_active = NULL;
336                 mtx_unlock(&mhc->mhc_active_lock);
337         }
338         return error;
339 }
340
341 const struct vmbus_message *
342 vmbus_msghc_wait_result(struct vmbus_softc *sc, struct vmbus_msghc *mh)
343 {
344         struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc;
345
346         mtx_lock(&mhc->mhc_active_lock);
347
348         KASSERT(mhc->mhc_active == mh, ("msghc mismatch"));
349         while (mh->mh_resp == NULL) {
350                 mtx_sleep(&mhc->mhc_active, &mhc->mhc_active_lock, 0,
351                     "wmsghc", 0);
352         }
353         mhc->mhc_active = NULL;
354
355         mtx_unlock(&mhc->mhc_active_lock);
356
357         return mh->mh_resp;
358 }
359
360 void
361 vmbus_msghc_wakeup(struct vmbus_softc *sc, const struct vmbus_message *msg)
362 {
363         struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc;
364         struct vmbus_msghc *mh;
365
366         mtx_lock(&mhc->mhc_active_lock);
367
368         mh = mhc->mhc_active;
369         KASSERT(mh != NULL, ("no pending msg hypercall"));
370         memcpy(&mh->mh_resp0, msg, sizeof(mh->mh_resp0));
371         mh->mh_resp = &mh->mh_resp0;
372
373         mtx_unlock(&mhc->mhc_active_lock);
374         wakeup(&mhc->mhc_active);
375 }
376
377 uint32_t
378 vmbus_gpadl_alloc(struct vmbus_softc *sc)
379 {
380         return atomic_fetchadd_int(&sc->vmbus_gpadl, 1);
381 }
382
383 static int
384 vmbus_connect(struct vmbus_softc *sc, uint32_t version)
385 {
386         struct vmbus_chanmsg_connect *req;
387         const struct vmbus_message *msg;
388         struct vmbus_msghc *mh;
389         int error, done = 0;
390
391         mh = vmbus_msghc_get(sc, sizeof(*req));
392         if (mh == NULL)
393                 return ENXIO;
394
395         req = vmbus_msghc_dataptr(mh);
396         req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CONNECT;
397         req->chm_ver = version;
398         req->chm_evtflags = sc->vmbus_evtflags_dma.hv_paddr;
399         req->chm_mnf1 = sc->vmbus_mnf1_dma.hv_paddr;
400         req->chm_mnf2 = sc->vmbus_mnf2_dma.hv_paddr;
401
402         error = vmbus_msghc_exec(sc, mh);
403         if (error) {
404                 vmbus_msghc_put(sc, mh);
405                 return error;
406         }
407
408         msg = vmbus_msghc_wait_result(sc, mh);
409         done = ((const struct vmbus_chanmsg_connect_resp *)
410             msg->msg_data)->chm_done;
411
412         vmbus_msghc_put(sc, mh);
413
414         return (done ? 0 : EOPNOTSUPP);
415 }
416
417 static int
418 vmbus_init(struct vmbus_softc *sc)
419 {
420         int i;
421
422         for (i = 0; i < nitems(vmbus_version); ++i) {
423                 int error;
424
425                 error = vmbus_connect(sc, vmbus_version[i]);
426                 if (!error) {
427                         sc->vmbus_version = vmbus_version[i];
428                         device_printf(sc->vmbus_dev, "version %u.%u\n",
429                             VMBUS_VERSION_MAJOR(sc->vmbus_version),
430                             VMBUS_VERSION_MINOR(sc->vmbus_version));
431                         return 0;
432                 }
433         }
434         return ENXIO;
435 }
436
437 static void
438 vmbus_disconnect(struct vmbus_softc *sc)
439 {
440         struct vmbus_chanmsg_disconnect *req;
441         struct vmbus_msghc *mh;
442         int error;
443
444         mh = vmbus_msghc_get(sc, sizeof(*req));
445         if (mh == NULL) {
446                 device_printf(sc->vmbus_dev,
447                     "can not get msg hypercall for disconnect\n");
448                 return;
449         }
450
451         req = vmbus_msghc_dataptr(mh);
452         req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_DISCONNECT;
453
454         error = vmbus_msghc_exec_noresult(mh);
455         vmbus_msghc_put(sc, mh);
456
457         if (error) {
458                 device_printf(sc->vmbus_dev,
459                     "disconnect msg hypercall failed\n");
460         }
461 }
462
463 static int
464 vmbus_req_channels(struct vmbus_softc *sc)
465 {
466         struct vmbus_chanmsg_chrequest *req;
467         struct vmbus_msghc *mh;
468         int error;
469
470         mh = vmbus_msghc_get(sc, sizeof(*req));
471         if (mh == NULL)
472                 return ENXIO;
473
474         req = vmbus_msghc_dataptr(mh);
475         req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHREQUEST;
476
477         error = vmbus_msghc_exec_noresult(mh);
478         vmbus_msghc_put(sc, mh);
479
480         return error;
481 }
482
483 void
484 vmbus_scan_newchan(struct vmbus_softc *sc)
485 {
486         mtx_lock(&sc->vmbus_scan_lock);
487         if ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0)
488                 sc->vmbus_scan_chcnt++;
489         mtx_unlock(&sc->vmbus_scan_lock);
490 }
491
492 void
493 vmbus_scan_done(struct vmbus_softc *sc)
494 {
495         mtx_lock(&sc->vmbus_scan_lock);
496         sc->vmbus_scan_chcnt |= VMBUS_SCAN_CHCNT_DONE;
497         mtx_unlock(&sc->vmbus_scan_lock);
498         wakeup(&sc->vmbus_scan_chcnt);
499 }
500
501 static void
502 vmbus_scan_newdev(struct vmbus_softc *sc)
503 {
504         mtx_lock(&sc->vmbus_scan_lock);
505         sc->vmbus_scan_devcnt++;
506         mtx_unlock(&sc->vmbus_scan_lock);
507         wakeup(&sc->vmbus_scan_devcnt);
508 }
509
510 static void
511 vmbus_scan_wait(struct vmbus_softc *sc)
512 {
513         uint32_t chancnt;
514
515         mtx_lock(&sc->vmbus_scan_lock);
516         while ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0) {
517                 mtx_sleep(&sc->vmbus_scan_chcnt, &sc->vmbus_scan_lock, 0,
518                     "waitch", 0);
519         }
520         chancnt = sc->vmbus_scan_chcnt & ~VMBUS_SCAN_CHCNT_DONE;
521
522         while (sc->vmbus_scan_devcnt != chancnt) {
523                 mtx_sleep(&sc->vmbus_scan_devcnt, &sc->vmbus_scan_lock, 0,
524                     "waitdev", 0);
525         }
526         mtx_unlock(&sc->vmbus_scan_lock);
527 }
528
529 static int
530 vmbus_scan(struct vmbus_softc *sc)
531 {
532         int error;
533
534         /*
535          * Start vmbus scanning.
536          */
537         error = vmbus_req_channels(sc);
538         if (error) {
539                 device_printf(sc->vmbus_dev, "channel request failed: %d\n",
540                     error);
541                 return error;
542         }
543
544         /*
545          * Wait for all devices are added to vmbus.
546          */
547         vmbus_scan_wait(sc);
548
549         /*
550          * Identify, probe and attach.
551          */
552         bus_generic_probe(sc->vmbus_dev);
553         bus_generic_attach(sc->vmbus_dev);
554
555         if (bootverbose) {
556                 device_printf(sc->vmbus_dev, "device scan, probe and attach "
557                     "done\n");
558         }
559         return 0;
560 }
561
562 static void
563 vmbus_msg_task(void *xsc, int pending __unused)
564 {
565         struct vmbus_softc *sc = xsc;
566         volatile struct vmbus_message *msg;
567
568         msg = VMBUS_PCPU_GET(sc, message, curcpu) + VMBUS_SINT_MESSAGE;
569         for (;;) {
570                 if (msg->msg_type == HYPERV_MSGTYPE_NONE) {
571                         /* No message */
572                         break;
573                 } else if (msg->msg_type == HYPERV_MSGTYPE_CHANNEL) {
574                         /* Channel message */
575                         vmbus_chan_msgproc(sc,
576                             __DEVOLATILE(const struct vmbus_message *, msg));
577                 }
578
579                 msg->msg_type = HYPERV_MSGTYPE_NONE;
580                 /*
581                  * Make sure the write to msg_type (i.e. set to
582                  * HYPERV_MSGTYPE_NONE) happens before we read the
583                  * msg_flags and EOMing. Otherwise, the EOMing will
584                  * not deliver any more messages since there is no
585                  * empty slot
586                  *
587                  * NOTE:
588                  * mb() is used here, since atomic_thread_fence_seq_cst()
589                  * will become compiler fence on UP kernel.
590                  */
591                 mb();
592                 if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
593                         /*
594                          * This will cause message queue rescan to possibly
595                          * deliver another msg from the hypervisor
596                          */
597                         wrmsr(MSR_HV_EOM, 0);
598                 }
599         }
600 }
601
602 static __inline int
603 vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
604 {
605         volatile struct vmbus_message *msg;
606         struct vmbus_message *msg_base;
607
608         msg_base = VMBUS_PCPU_GET(sc, message, cpu);
609
610         /*
611          * Check event timer.
612          *
613          * TODO: move this to independent IDT vector.
614          */
615         msg = msg_base + VMBUS_SINT_TIMER;
616         if (msg->msg_type == HYPERV_MSGTYPE_TIMER_EXPIRED) {
617                 msg->msg_type = HYPERV_MSGTYPE_NONE;
618
619                 vmbus_et_intr(frame);
620
621                 /*
622                  * Make sure the write to msg_type (i.e. set to
623                  * HYPERV_MSGTYPE_NONE) happens before we read the
624                  * msg_flags and EOMing. Otherwise, the EOMing will
625                  * not deliver any more messages since there is no
626                  * empty slot
627                  *
628                  * NOTE:
629                  * mb() is used here, since atomic_thread_fence_seq_cst()
630                  * will become compiler fence on UP kernel.
631                  */
632                 mb();
633                 if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
634                         /*
635                          * This will cause message queue rescan to possibly
636                          * deliver another msg from the hypervisor
637                          */
638                         wrmsr(MSR_HV_EOM, 0);
639                 }
640         }
641
642         /*
643          * Check events.  Hot path for network and storage I/O data; high rate.
644          *
645          * NOTE:
646          * As recommended by the Windows guest fellows, we check events before
647          * checking messages.
648          */
649         sc->vmbus_event_proc(sc, cpu);
650
651         /*
652          * Check messages.  Mainly management stuffs; ultra low rate.
653          */
654         msg = msg_base + VMBUS_SINT_MESSAGE;
655         if (__predict_false(msg->msg_type != HYPERV_MSGTYPE_NONE)) {
656                 taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu),
657                     VMBUS_PCPU_PTR(sc, message_task, cpu));
658         }
659
660         return (FILTER_HANDLED);
661 }
662
663 void
664 vmbus_handle_intr(struct trapframe *trap_frame)
665 {
666         struct vmbus_softc *sc = vmbus_get_softc();
667         int cpu = curcpu;
668
669         /*
670          * Disable preemption.
671          */
672         critical_enter();
673
674         /*
675          * Do a little interrupt counting.
676          */
677         (*VMBUS_PCPU_GET(sc, intr_cnt, cpu))++;
678
679         vmbus_handle_intr1(sc, trap_frame, cpu);
680
681         /*
682          * Enable preemption.
683          */
684         critical_exit();
685 }
686
687 static void
688 vmbus_synic_setup(void *xsc)
689 {
690         struct vmbus_softc *sc = xsc;
691         int cpu = curcpu;
692         uint64_t val, orig;
693         uint32_t sint;
694
695         if (hyperv_features & CPUID_HV_MSR_VP_INDEX) {
696                 /*
697                  * Save virtual processor id.
698                  */
699                 VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
700         } else {
701                 /*
702                  * XXX
703                  * Virtual processoor id is only used by a pretty broken
704                  * channel selection code from storvsc.  It's nothing
705                  * critical even if CPUID_HV_MSR_VP_INDEX is not set; keep
706                  * moving on.
707                  */
708                 VMBUS_PCPU_GET(sc, vcpuid, cpu) = cpu;
709         }
710
711         /*
712          * Setup the SynIC message.
713          */
714         orig = rdmsr(MSR_HV_SIMP);
715         val = MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK) |
716             ((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
717              MSR_HV_SIMP_PGSHIFT);
718         wrmsr(MSR_HV_SIMP, val);
719
720         /*
721          * Setup the SynIC event flags.
722          */
723         orig = rdmsr(MSR_HV_SIEFP);
724         val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
725             ((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu)
726               >> PAGE_SHIFT) << MSR_HV_SIEFP_PGSHIFT);
727         wrmsr(MSR_HV_SIEFP, val);
728
729
730         /*
731          * Configure and unmask SINT for message and event flags.
732          */
733         sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
734         orig = rdmsr(sint);
735         val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
736             (orig & MSR_HV_SINT_RSVD_MASK);
737         wrmsr(sint, val);
738
739         /*
740          * Configure and unmask SINT for timer.
741          */
742         sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
743         orig = rdmsr(sint);
744         val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
745             (orig & MSR_HV_SINT_RSVD_MASK);
746         wrmsr(sint, val);
747
748         /*
749          * All done; enable SynIC.
750          */
751         orig = rdmsr(MSR_HV_SCONTROL);
752         val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK);
753         wrmsr(MSR_HV_SCONTROL, val);
754 }
755
756 static void
757 vmbus_synic_teardown(void *arg)
758 {
759         uint64_t orig;
760         uint32_t sint;
761
762         /*
763          * Disable SynIC.
764          */
765         orig = rdmsr(MSR_HV_SCONTROL);
766         wrmsr(MSR_HV_SCONTROL, (orig & MSR_HV_SCTRL_RSVD_MASK));
767
768         /*
769          * Mask message and event flags SINT.
770          */
771         sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
772         orig = rdmsr(sint);
773         wrmsr(sint, orig | MSR_HV_SINT_MASKED);
774
775         /*
776          * Mask timer SINT.
777          */
778         sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
779         orig = rdmsr(sint);
780         wrmsr(sint, orig | MSR_HV_SINT_MASKED);
781
782         /*
783          * Teardown SynIC message.
784          */
785         orig = rdmsr(MSR_HV_SIMP);
786         wrmsr(MSR_HV_SIMP, (orig & MSR_HV_SIMP_RSVD_MASK));
787
788         /*
789          * Teardown SynIC event flags.
790          */
791         orig = rdmsr(MSR_HV_SIEFP);
792         wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
793 }
794
795 static int
796 vmbus_dma_alloc(struct vmbus_softc *sc)
797 {
798         bus_dma_tag_t parent_dtag;
799         uint8_t *evtflags;
800         int cpu;
801
802         parent_dtag = bus_get_dma_tag(sc->vmbus_dev);
803         CPU_FOREACH(cpu) {
804                 void *ptr;
805
806                 /*
807                  * Per-cpu messages and event flags.
808                  */
809                 ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
810                     PAGE_SIZE, VMBUS_PCPU_PTR(sc, message_dma, cpu),
811                     BUS_DMA_WAITOK | BUS_DMA_ZERO);
812                 if (ptr == NULL)
813                         return ENOMEM;
814                 VMBUS_PCPU_GET(sc, message, cpu) = ptr;
815
816                 ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
817                     PAGE_SIZE, VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
818                     BUS_DMA_WAITOK | BUS_DMA_ZERO);
819                 if (ptr == NULL)
820                         return ENOMEM;
821                 VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
822         }
823
824         evtflags = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
825             PAGE_SIZE, &sc->vmbus_evtflags_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
826         if (evtflags == NULL)
827                 return ENOMEM;
828         sc->vmbus_rx_evtflags = (u_long *)evtflags;
829         sc->vmbus_tx_evtflags = (u_long *)(evtflags + (PAGE_SIZE / 2));
830         sc->vmbus_evtflags = evtflags;
831
832         sc->vmbus_mnf1 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
833             PAGE_SIZE, &sc->vmbus_mnf1_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
834         if (sc->vmbus_mnf1 == NULL)
835                 return ENOMEM;
836
837         sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
838             PAGE_SIZE, &sc->vmbus_mnf2_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
839         if (sc->vmbus_mnf2 == NULL)
840                 return ENOMEM;
841
842         return 0;
843 }
844
845 static void
846 vmbus_dma_free(struct vmbus_softc *sc)
847 {
848         int cpu;
849
850         if (sc->vmbus_evtflags != NULL) {
851                 hyperv_dmamem_free(&sc->vmbus_evtflags_dma, sc->vmbus_evtflags);
852                 sc->vmbus_evtflags = NULL;
853                 sc->vmbus_rx_evtflags = NULL;
854                 sc->vmbus_tx_evtflags = NULL;
855         }
856         if (sc->vmbus_mnf1 != NULL) {
857                 hyperv_dmamem_free(&sc->vmbus_mnf1_dma, sc->vmbus_mnf1);
858                 sc->vmbus_mnf1 = NULL;
859         }
860         if (sc->vmbus_mnf2 != NULL) {
861                 hyperv_dmamem_free(&sc->vmbus_mnf2_dma, sc->vmbus_mnf2);
862                 sc->vmbus_mnf2 = NULL;
863         }
864
865         CPU_FOREACH(cpu) {
866                 if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) {
867                         hyperv_dmamem_free(
868                             VMBUS_PCPU_PTR(sc, message_dma, cpu),
869                             VMBUS_PCPU_GET(sc, message, cpu));
870                         VMBUS_PCPU_GET(sc, message, cpu) = NULL;
871                 }
872                 if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) {
873                         hyperv_dmamem_free(
874                             VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
875                             VMBUS_PCPU_GET(sc, event_flags, cpu));
876                         VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL;
877                 }
878         }
879 }
880
881 /**
882  * @brief Find a free IDT slot and setup the interrupt handler.
883  */
884 static int
885 vmbus_vector_alloc(void)
886 {
887         int vector;
888         uintptr_t func;
889         struct gate_descriptor *ip;
890
891         /*
892          * Search backwards form the highest IDT vector available for use
893          * as vmbus channel callback vector. We install 'vmbus_isr'
894          * handler at that vector and use it to interrupt vcpus.
895          */
896         vector = APIC_SPURIOUS_INT;
897         while (--vector >= APIC_IPI_INTS) {
898                 ip = &idt[vector];
899                 func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset);
900                 if (func == (uintptr_t)&IDTVEC(rsvd)) {
901 #ifdef __i386__
902                         setidt(vector , IDTVEC(vmbus_isr), SDT_SYS386IGT,
903                             SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
904 #else
905                         setidt(vector , IDTVEC(vmbus_isr), SDT_SYSIGT,
906                             SEL_KPL, 0);
907 #endif
908
909                         return (vector);
910                 }
911         }
912         return (0);
913 }
914
915 /**
916  * @brief Restore the IDT slot to rsvd.
917  */
918 static void
919 vmbus_vector_free(int vector)
920 {
921         uintptr_t func;
922         struct gate_descriptor *ip;
923
924         if (vector == 0)
925                 return;
926
927         KASSERT(vector >= APIC_IPI_INTS && vector < APIC_SPURIOUS_INT,
928             ("invalid vector %d", vector));
929
930         ip = &idt[vector];
931         func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset);
932         KASSERT(func == (uintptr_t)&IDTVEC(vmbus_isr),
933             ("invalid vector %d", vector));
934
935         setidt(vector, IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0);
936 }
937
938 static void
939 vmbus_cpuset_setthread_task(void *xmask, int pending __unused)
940 {
941         cpuset_t *mask = xmask;
942         int error;
943
944         error = cpuset_setthread(curthread->td_tid, mask);
945         if (error) {
946                 panic("curthread=%ju: can't pin; error=%d",
947                     (uintmax_t)curthread->td_tid, error);
948         }
949 }
950
951 static int
952 vmbus_intr_setup(struct vmbus_softc *sc)
953 {
954         int cpu;
955
956         CPU_FOREACH(cpu) {
957                 struct task cpuset_task;
958                 char buf[MAXCOMLEN + 1];
959                 cpuset_t cpu_mask;
960
961                 /* Allocate an interrupt counter for Hyper-V interrupt */
962                 snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
963                 intrcnt_add(buf, VMBUS_PCPU_PTR(sc, intr_cnt, cpu));
964
965                 /*
966                  * Setup taskqueue to handle events.  Task will be per-
967                  * channel.
968                  */
969                 VMBUS_PCPU_GET(sc, event_tq, cpu) = taskqueue_create_fast(
970                     "hyperv event", M_WAITOK, taskqueue_thread_enqueue,
971                     VMBUS_PCPU_PTR(sc, event_tq, cpu));
972                 taskqueue_start_threads(VMBUS_PCPU_PTR(sc, event_tq, cpu),
973                     1, PI_NET, "hvevent%d", cpu);
974
975                 CPU_SETOF(cpu, &cpu_mask);
976                 TASK_INIT(&cpuset_task, 0, vmbus_cpuset_setthread_task,
977                     &cpu_mask);
978                 taskqueue_enqueue(VMBUS_PCPU_GET(sc, event_tq, cpu),
979                     &cpuset_task);
980                 taskqueue_drain(VMBUS_PCPU_GET(sc, event_tq, cpu),
981                     &cpuset_task);
982
983                 /*
984                  * Setup tasks and taskqueues to handle messages.
985                  */
986                 VMBUS_PCPU_GET(sc, message_tq, cpu) = taskqueue_create_fast(
987                     "hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
988                     VMBUS_PCPU_PTR(sc, message_tq, cpu));
989                 taskqueue_start_threads(VMBUS_PCPU_PTR(sc, message_tq, cpu), 1,
990                     PI_NET, "hvmsg%d", cpu);
991                 TASK_INIT(VMBUS_PCPU_PTR(sc, message_task, cpu), 0,
992                     vmbus_msg_task, sc);
993
994                 CPU_SETOF(cpu, &cpu_mask);
995                 TASK_INIT(&cpuset_task, 0, vmbus_cpuset_setthread_task,
996                     &cpu_mask);
997                 taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu),
998                     &cpuset_task);
999                 taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu),
1000                     &cpuset_task);
1001         }
1002
1003         /*
1004          * All Hyper-V ISR required resources are setup, now let's find a
1005          * free IDT vector for Hyper-V ISR and set it up.
1006          */
1007         sc->vmbus_idtvec = vmbus_vector_alloc();
1008         if (sc->vmbus_idtvec == 0) {
1009                 device_printf(sc->vmbus_dev, "cannot find free IDT vector\n");
1010                 return ENXIO;
1011         }
1012         if(bootverbose) {
1013                 device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n",
1014                     sc->vmbus_idtvec);
1015         }
1016         return 0;
1017 }
1018
1019 static void
1020 vmbus_intr_teardown(struct vmbus_softc *sc)
1021 {
1022         int cpu;
1023
1024         vmbus_vector_free(sc->vmbus_idtvec);
1025
1026         CPU_FOREACH(cpu) {
1027                 if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) {
1028                         taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu));
1029                         VMBUS_PCPU_GET(sc, event_tq, cpu) = NULL;
1030                 }
1031                 if (VMBUS_PCPU_GET(sc, message_tq, cpu) != NULL) {
1032                         taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu),
1033                             VMBUS_PCPU_PTR(sc, message_task, cpu));
1034                         taskqueue_free(VMBUS_PCPU_GET(sc, message_tq, cpu));
1035                         VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL;
1036                 }
1037         }
1038 }
1039
1040 static int
1041 vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
1042 {
1043         struct hv_device *child_dev_ctx = device_get_ivars(child);
1044
1045         switch (index) {
1046         case HV_VMBUS_IVAR_TYPE:
1047                 *result = (uintptr_t)&child_dev_ctx->class_id;
1048                 return (0);
1049
1050         case HV_VMBUS_IVAR_INSTANCE:
1051                 *result = (uintptr_t)&child_dev_ctx->device_id;
1052                 return (0);
1053
1054         case HV_VMBUS_IVAR_DEVCTX:
1055                 *result = (uintptr_t)child_dev_ctx;
1056                 return (0);
1057
1058         case HV_VMBUS_IVAR_NODE:
1059                 *result = (uintptr_t)child_dev_ctx->device;
1060                 return (0);
1061         }
1062         return (ENOENT);
1063 }
1064
1065 static int
1066 vmbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
1067 {
1068         switch (index) {
1069         case HV_VMBUS_IVAR_TYPE:
1070         case HV_VMBUS_IVAR_INSTANCE:
1071         case HV_VMBUS_IVAR_DEVCTX:
1072         case HV_VMBUS_IVAR_NODE:
1073                 /* read-only */
1074                 return (EINVAL);
1075         }
1076         return (ENOENT);
1077 }
1078
1079 static int
1080 vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen)
1081 {
1082         struct hv_device *dev_ctx = device_get_ivars(child);
1083         char guidbuf[HYPERV_GUID_STRLEN];
1084
1085         if (dev_ctx == NULL)
1086                 return (0);
1087
1088         strlcat(buf, "classid=", buflen);
1089         hyperv_guid2str(&dev_ctx->class_id, guidbuf, sizeof(guidbuf));
1090         strlcat(buf, guidbuf, buflen);
1091
1092         strlcat(buf, " deviceid=", buflen);
1093         hyperv_guid2str(&dev_ctx->device_id, guidbuf, sizeof(guidbuf));
1094         strlcat(buf, guidbuf, buflen);
1095
1096         return (0);
1097 }
1098
1099 struct hv_device *
1100 hv_vmbus_child_device_create(hv_guid type, hv_guid instance,
1101     hv_vmbus_channel *channel)
1102 {
1103         hv_device *child_dev;
1104
1105         /*
1106          * Allocate the new child device
1107          */
1108         child_dev = malloc(sizeof(hv_device), M_DEVBUF, M_WAITOK | M_ZERO);
1109
1110         child_dev->channel = channel;
1111         memcpy(&child_dev->class_id, &type, sizeof(hv_guid));
1112         memcpy(&child_dev->device_id, &instance, sizeof(hv_guid));
1113
1114         return (child_dev);
1115 }
1116
1117 void
1118 hv_vmbus_child_device_register(struct vmbus_softc *sc,
1119     struct hv_device *child_dev)
1120 {
1121         device_t child, parent;
1122
1123         parent = sc->vmbus_dev;
1124         if (bootverbose) {
1125                 char name[HYPERV_GUID_STRLEN];
1126
1127                 hyperv_guid2str(&child_dev->class_id, name, sizeof(name));
1128                 device_printf(parent, "add device, classid: %s\n", name);
1129         }
1130
1131         child = device_add_child(parent, NULL, -1);
1132         child_dev->device = child;
1133         device_set_ivars(child, child_dev);
1134
1135         /* New device was added to vmbus */
1136         vmbus_scan_newdev(sc);
1137 }
1138
1139 int
1140 hv_vmbus_child_device_unregister(struct hv_device *child_dev)
1141 {
1142         int ret = 0;
1143         /*
1144          * XXXKYS: Ensure that this is the opposite of
1145          * device_add_child()
1146          */
1147         mtx_lock(&Giant);
1148         ret = device_delete_child(vmbus_get_device(), child_dev->device);
1149         mtx_unlock(&Giant);
1150         return(ret);
1151 }
1152
1153 static int
1154 vmbus_sysctl_version(SYSCTL_HANDLER_ARGS)
1155 {
1156         struct vmbus_softc *sc = arg1;
1157         char verstr[16];
1158
1159         snprintf(verstr, sizeof(verstr), "%u.%u",
1160             VMBUS_VERSION_MAJOR(sc->vmbus_version),
1161             VMBUS_VERSION_MINOR(sc->vmbus_version));
1162         return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
1163 }
1164
1165 static uint32_t
1166 vmbus_get_version_method(device_t bus, device_t dev)
1167 {
1168         struct vmbus_softc *sc = device_get_softc(bus);
1169
1170         return sc->vmbus_version;
1171 }
1172
1173 static int
1174 vmbus_probe(device_t dev)
1175 {
1176         char *id[] = { "VMBUS", NULL };
1177
1178         if (ACPI_ID_PROBE(device_get_parent(dev), dev, id) == NULL ||
1179             device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV ||
1180             (hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
1181                 return (ENXIO);
1182
1183         device_set_desc(dev, "Hyper-V Vmbus");
1184
1185         return (BUS_PROBE_DEFAULT);
1186 }
1187
1188 /**
1189  * @brief Main vmbus driver initialization routine.
1190  *
1191  * Here, we
1192  * - initialize the vmbus driver context
1193  * - setup various driver entry points
1194  * - invoke the vmbus hv main init routine
1195  * - get the irq resource
1196  * - invoke the vmbus to add the vmbus root device
1197  * - setup the vmbus root device
1198  * - retrieve the channel offers
1199  */
1200 static int
1201 vmbus_doattach(struct vmbus_softc *sc)
1202 {
1203         struct sysctl_oid_list *child;
1204         struct sysctl_ctx_list *ctx;
1205         int ret;
1206
1207         if (sc->vmbus_flags & VMBUS_FLAG_ATTACHED)
1208                 return (0);
1209         sc->vmbus_flags |= VMBUS_FLAG_ATTACHED;
1210
1211         mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF);
1212         sc->vmbus_gpadl = VMBUS_GPADL_START;
1213         mtx_init(&sc->vmbus_chlist_lock, "vmbus chlist", NULL, MTX_DEF);
1214         TAILQ_INIT(&sc->vmbus_chlist);
1215         sc->vmbus_chmap = malloc(
1216             sizeof(struct hv_vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF,
1217             M_WAITOK | M_ZERO);
1218
1219         /*
1220          * Create context for "post message" Hypercalls
1221          */
1222         sc->vmbus_msg_hc = vmbus_msghc_ctx_create(
1223             bus_get_dma_tag(sc->vmbus_dev));
1224         if (sc->vmbus_msg_hc == NULL) {
1225                 ret = ENXIO;
1226                 goto cleanup;
1227         }
1228
1229         /*
1230          * Allocate DMA stuffs.
1231          */
1232         ret = vmbus_dma_alloc(sc);
1233         if (ret != 0)
1234                 goto cleanup;
1235
1236         /*
1237          * Setup interrupt.
1238          */
1239         ret = vmbus_intr_setup(sc);
1240         if (ret != 0)
1241                 goto cleanup;
1242
1243         /*
1244          * Setup SynIC.
1245          */
1246         if (bootverbose)
1247                 device_printf(sc->vmbus_dev, "smp_started = %d\n", smp_started);
1248         smp_rendezvous(NULL, vmbus_synic_setup, NULL, sc);
1249         sc->vmbus_flags |= VMBUS_FLAG_SYNIC;
1250
1251         /*
1252          * Initialize vmbus, e.g. connect to Hypervisor.
1253          */
1254         ret = vmbus_init(sc);
1255         if (ret != 0)
1256                 goto cleanup;
1257
1258         if (sc->vmbus_version == VMBUS_VERSION_WS2008 ||
1259             sc->vmbus_version == VMBUS_VERSION_WIN7)
1260                 sc->vmbus_event_proc = vmbus_event_proc_compat;
1261         else
1262                 sc->vmbus_event_proc = vmbus_event_proc;
1263
1264         ret = vmbus_scan(sc);
1265         if (ret != 0)
1266                 goto cleanup;
1267
1268         ctx = device_get_sysctl_ctx(sc->vmbus_dev);
1269         child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vmbus_dev));
1270         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "version",
1271             CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
1272             vmbus_sysctl_version, "A", "vmbus version");
1273
1274         return (ret);
1275
1276 cleanup:
1277         vmbus_intr_teardown(sc);
1278         vmbus_dma_free(sc);
1279         if (sc->vmbus_msg_hc != NULL) {
1280                 vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc);
1281                 sc->vmbus_msg_hc = NULL;
1282         }
1283         free(sc->vmbus_chmap, M_DEVBUF);
1284         mtx_destroy(&sc->vmbus_scan_lock);
1285         mtx_destroy(&sc->vmbus_chlist_lock);
1286
1287         return (ret);
1288 }
1289
1290 static void
1291 vmbus_event_proc_dummy(struct vmbus_softc *sc __unused, int cpu __unused)
1292 {
1293 }
1294
1295 static int
1296 vmbus_attach(device_t dev)
1297 {
1298         vmbus_sc = device_get_softc(dev);
1299         vmbus_sc->vmbus_dev = dev;
1300
1301         /*
1302          * Event processing logic will be configured:
1303          * - After the vmbus protocol version negotiation.
1304          * - Before we request channel offers.
1305          */
1306         vmbus_sc->vmbus_event_proc = vmbus_event_proc_dummy;
1307
1308         /* 
1309          * If the system has already booted and thread
1310          * scheduling is possible indicated by the global
1311          * cold set to zero, we just call the driver
1312          * initialization directly.
1313          */
1314         if (!cold)
1315                 vmbus_doattach(vmbus_sc);
1316
1317         return (0);
1318 }
1319
1320 static void
1321 vmbus_sysinit(void *arg __unused)
1322 {
1323         struct vmbus_softc *sc = vmbus_get_softc();
1324
1325         if (vm_guest != VM_GUEST_HV || sc == NULL)
1326                 return;
1327
1328         /* 
1329          * If the system has already booted and thread
1330          * scheduling is possible, as indicated by the
1331          * global cold set to zero, we just call the driver
1332          * initialization directly.
1333          */
1334         if (!cold) 
1335                 vmbus_doattach(sc);
1336 }
1337
1338 static int
1339 vmbus_detach(device_t dev)
1340 {
1341         struct vmbus_softc *sc = device_get_softc(dev);
1342
1343         hv_vmbus_release_unattached_channels(sc);
1344
1345         vmbus_disconnect(sc);
1346
1347         if (sc->vmbus_flags & VMBUS_FLAG_SYNIC) {
1348                 sc->vmbus_flags &= ~VMBUS_FLAG_SYNIC;
1349                 smp_rendezvous(NULL, vmbus_synic_teardown, NULL, NULL);
1350         }
1351
1352         vmbus_intr_teardown(sc);
1353         vmbus_dma_free(sc);
1354
1355         if (sc->vmbus_msg_hc != NULL) {
1356                 vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc);
1357                 sc->vmbus_msg_hc = NULL;
1358         }
1359
1360         free(sc->vmbus_chmap, M_DEVBUF);
1361         mtx_destroy(&sc->vmbus_scan_lock);
1362         mtx_destroy(&sc->vmbus_chlist_lock);
1363
1364         return (0);
1365 }
1366
1367 static device_method_t vmbus_methods[] = {
1368         /* Device interface */
1369         DEVMETHOD(device_probe,                 vmbus_probe),
1370         DEVMETHOD(device_attach,                vmbus_attach),
1371         DEVMETHOD(device_detach,                vmbus_detach),
1372         DEVMETHOD(device_shutdown,              bus_generic_shutdown),
1373         DEVMETHOD(device_suspend,               bus_generic_suspend),
1374         DEVMETHOD(device_resume,                bus_generic_resume),
1375
1376         /* Bus interface */
1377         DEVMETHOD(bus_add_child,                bus_generic_add_child),
1378         DEVMETHOD(bus_print_child,              bus_generic_print_child),
1379         DEVMETHOD(bus_read_ivar,                vmbus_read_ivar),
1380         DEVMETHOD(bus_write_ivar,               vmbus_write_ivar),
1381         DEVMETHOD(bus_child_pnpinfo_str,        vmbus_child_pnpinfo_str),
1382
1383         /* Vmbus interface */
1384         DEVMETHOD(vmbus_get_version,            vmbus_get_version_method),
1385
1386         DEVMETHOD_END
1387 };
1388
1389 static driver_t vmbus_driver = {
1390         "vmbus",
1391         vmbus_methods,
1392         sizeof(struct vmbus_softc)
1393 };
1394
1395 static devclass_t vmbus_devclass;
1396
1397 DRIVER_MODULE(vmbus, acpi, vmbus_driver, vmbus_devclass, NULL, NULL);
1398 MODULE_DEPEND(vmbus, acpi, 1, 1, 1);
1399 MODULE_VERSION(vmbus, 1);
1400
1401 /*
1402  * NOTE:
1403  * We have to start as the last step of SI_SUB_SMP, i.e. after SMP is
1404  * initialized.
1405  */
1406 SYSINIT(vmbus_initialize, SI_SUB_SMP, SI_ORDER_ANY, vmbus_sysinit, NULL);
1407