vmbus_ic.c revision 303069
1250199Sgrehan/*-
2298446Ssephe * Copyright (c) 2014,2016 Microsoft Corp.
3250199Sgrehan * All rights reserved.
4250199Sgrehan *
5250199Sgrehan * Redistribution and use in source and binary forms, with or without
6250199Sgrehan * modification, are permitted provided that the following conditions
7250199Sgrehan * are met:
8250199Sgrehan * 1. Redistributions of source code must retain the above copyright
9250199Sgrehan *    notice unmodified, this list of conditions, and the following
10250199Sgrehan *    disclaimer.
11250199Sgrehan * 2. Redistributions in binary form must reproduce the above copyright
12250199Sgrehan *    notice, this list of conditions and the following disclaimer in the
13250199Sgrehan *    documentation and/or other materials provided with the distribution.
14250199Sgrehan *
15250199Sgrehan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16250199Sgrehan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17250199Sgrehan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18250199Sgrehan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19250199Sgrehan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20250199Sgrehan * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21250199Sgrehan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22250199Sgrehan * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23250199Sgrehan * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24250199Sgrehan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25271493Sdelphij *
26271493Sdelphij * $FreeBSD: head/sys/dev/hyperv/utilities/hv_util.c 303069 2016-07-20 05:34:28Z sephe $
27250199Sgrehan */
28250199Sgrehan
29271493Sdelphij/*
30250199Sgrehan * A common driver for all hyper-V util services.
31250199Sgrehan */
32250199Sgrehan
33250199Sgrehan#include <sys/param.h>
34250199Sgrehan#include <sys/kernel.h>
35250199Sgrehan#include <sys/bus.h>
36250199Sgrehan#include <sys/malloc.h>
37250199Sgrehan#include <sys/module.h>
38250199Sgrehan#include <sys/reboot.h>
39250199Sgrehan#include <sys/timetc.h>
40255414Sgrehan#include <sys/syscallsubr.h>
41250199Sgrehan
42250199Sgrehan#include <dev/hyperv/include/hyperv.h>
43303021Ssephe#include <dev/hyperv/include/vmbus.h>
44303067Ssephe#include <dev/hyperv/utilities/hv_utilreg.h>
45295958Ssephe#include "hv_util.h"
46250199Sgrehan
47295958Ssephevoid
48250199Sgrehanhv_negotiate_version(
49250199Sgrehan	struct hv_vmbus_icmsg_hdr*		icmsghdrp,
50250199Sgrehan	struct hv_vmbus_icmsg_negotiate*	negop,
51250199Sgrehan	uint8_t*				buf)
52255414Sgrehan{
53250199Sgrehan	icmsghdrp->icmsgsize = 0x10;
54250199Sgrehan
55250199Sgrehan	negop = (struct hv_vmbus_icmsg_negotiate *)&buf[
56250199Sgrehan		sizeof(struct hv_vmbus_pipe_hdr) +
57250199Sgrehan		sizeof(struct hv_vmbus_icmsg_hdr)];
58250199Sgrehan
59255414Sgrehan	if (negop->icframe_vercnt >= 2 &&
60250199Sgrehan	    negop->icversion_data[1].major == 3) {
61250199Sgrehan		negop->icversion_data[0].major = 3;
62250199Sgrehan		negop->icversion_data[0].minor = 0;
63250199Sgrehan		negop->icversion_data[1].major = 3;
64250199Sgrehan		negop->icversion_data[1].minor = 0;
65250199Sgrehan	} else {
66250199Sgrehan		negop->icversion_data[0].major = 1;
67250199Sgrehan		negop->icversion_data[0].minor = 0;
68250199Sgrehan		negop->icversion_data[1].major = 1;
69250199Sgrehan		negop->icversion_data[1].minor = 0;
70250199Sgrehan	}
71250199Sgrehan
72250199Sgrehan	negop->icframe_vercnt = 1;
73250199Sgrehan	negop->icmsg_vercnt = 1;
74250199Sgrehan}
75250199Sgrehan
76295958Ssepheint
77295958Ssephehv_util_attach(device_t dev)
78250199Sgrehan{
79295958Ssephe	struct hv_util_sc*	softc;
80303069Ssephe	struct hv_vmbus_channel *chan;
81250199Sgrehan	int			ret;
82250199Sgrehan
83295958Ssephe	softc = device_get_softc(dev);
84295958Ssephe	softc->receive_buffer =
85255414Sgrehan		malloc(4 * PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO);
86303069Ssephe	chan = vmbus_get_channel(dev);
87250199Sgrehan
88282212Swhu	/*
89282212Swhu	 * These services are not performance critical and do not need
90282212Swhu	 * batched reading. Furthermore, some services such as KVP can
91282212Swhu	 * only handle one message from the host at a time.
92282212Swhu	 * Turn off batched reading for all util drivers before we open the
93282212Swhu	 * channel.
94282212Swhu	 */
95303069Ssephe	vmbus_chan_set_readbatch(chan, false);
96282212Swhu
97303069Ssephe	ret = vmbus_chan_open(chan, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0,
98303069Ssephe	    softc->callback, softc);
99250199Sgrehan
100250199Sgrehan	if (ret)
101295958Ssephe		goto error0;
102250199Sgrehan
103250199Sgrehan	return (0);
104250199Sgrehan
105295958Ssepheerror0:
106295958Ssephe	free(softc->receive_buffer, M_DEVBUF);
107250199Sgrehan	return (ret);
108250199Sgrehan}
109250199Sgrehan
110295958Ssepheint
111250199Sgrehanhv_util_detach(device_t dev)
112250199Sgrehan{
113302702Ssephe	struct hv_util_sc *sc = device_get_softc(dev);
114250199Sgrehan
115303069Ssephe	vmbus_chan_close(vmbus_get_channel(dev));
116302702Ssephe	free(sc->receive_buffer, M_DEVBUF);
117250199Sgrehan
118250199Sgrehan	return (0);
119250199Sgrehan}
120