1 /*
2  *
3  * Copyright (c) 2009, Microsoft Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16  * Place - Suite 330, Boston, MA 02111-1307 USA.
17  *
18  * Authors:
19  *   Haiyang Zhang <haiyangz@microsoft.com>
20  *   Hank Janssen  <hjanssen@microsoft.com>
21  *
22  */
23 
24 
25 #ifndef _CHANNEL_MGMT_H_
26 #define _CHANNEL_MGMT_H_
27 
28 #include <linux/list.h>
29 #include <linux/timer.h>
30 #include <linux/workqueue.h>
31 #include "ring_buffer.h"
32 #include "vmbus_channel_interface.h"
33 #include "vmbus_packet_format.h"
34 
35 /* Version 1 messages */
36 enum vmbus_channel_message_type {
37 	CHANNELMSG_INVALID			=  0,
38 	CHANNELMSG_OFFERCHANNEL		=  1,
39 	CHANNELMSG_RESCIND_CHANNELOFFER	=  2,
40 	CHANNELMSG_REQUESTOFFERS		=  3,
41 	CHANNELMSG_ALLOFFERS_DELIVERED	=  4,
42 	CHANNELMSG_OPENCHANNEL		=  5,
43 	CHANNELMSG_OPENCHANNEL_RESULT		=  6,
44 	CHANNELMSG_CLOSECHANNEL		=  7,
45 	CHANNELMSG_GPADL_HEADER		=  8,
46 	CHANNELMSG_GPADL_BODY			=  9,
47 	CHANNELMSG_GPADL_CREATED		= 10,
48 	CHANNELMSG_GPADL_TEARDOWN		= 11,
49 	CHANNELMSG_GPADL_TORNDOWN		= 12,
50 	CHANNELMSG_RELID_RELEASED		= 13,
51 	CHANNELMSG_INITIATE_CONTACT		= 14,
52 	CHANNELMSG_VERSION_RESPONSE		= 15,
53 	CHANNELMSG_UNLOAD			= 16,
54 #ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
55 	CHANNELMSG_VIEWRANGE_ADD		= 17,
56 	CHANNELMSG_VIEWRANGE_REMOVE		= 18,
57 #endif
58 	CHANNELMSG_COUNT
59 };
60 
61 struct vmbus_channel_message_header {
62 	enum vmbus_channel_message_type msgtype;
63 	u32 padding;
64 } __packed;
65 
66 /* Query VMBus Version parameters */
67 struct vmbus_channel_query_vmbus_version {
68 	struct vmbus_channel_message_header header;
69 	u32 version;
70 } __packed;
71 
72 /* VMBus Version Supported parameters */
73 struct vmbus_channel_version_supported {
74 	struct vmbus_channel_message_header header;
75 	bool version_supported;
76 } __packed;
77 
78 /* Offer Channel parameters */
79 struct vmbus_channel_offer_channel {
80 	struct vmbus_channel_message_header header;
81 	struct vmbus_channel_offer offer;
82 	u32 child_relid;
83 	u8 monitorid;
84 	bool monitor_allocated;
85 } __packed;
86 
87 /* Rescind Offer parameters */
88 struct vmbus_channel_rescind_offer {
89 	struct vmbus_channel_message_header header;
90 	u32 child_relid;
91 } __packed;
92 
93 /*
94  * Request Offer -- no parameters, SynIC message contains the partition ID
95  * Set Snoop -- no parameters, SynIC message contains the partition ID
96  * Clear Snoop -- no parameters, SynIC message contains the partition ID
97  * All Offers Delivered -- no parameters, SynIC message contains the partition
98  *		           ID
99  * Flush Client -- no parameters, SynIC message contains the partition ID
100  */
101 
102 /* Open Channel parameters */
103 struct vmbus_channel_open_channel {
104 	struct vmbus_channel_message_header header;
105 
106 	/* Identifies the specific VMBus channel that is being opened. */
107 	u32 child_relid;
108 
109 	/* ID making a particular open request at a channel offer unique. */
110 	u32 openid;
111 
112 	/* GPADL for the channel's ring buffer. */
113 	u32 ringbuffer_gpadlhandle;
114 
115 	/* GPADL for the channel's server context save area. */
116 	u32 server_contextarea_gpadlhandle;
117 
118 	/*
119 	* The upstream ring buffer begins at offset zero in the memory
120 	* described by RingBufferGpadlHandle. The downstream ring buffer
121 	* follows it at this offset (in pages).
122 	*/
123 	u32 downstream_ringbuffer_pageoffset;
124 
125 	/* User-specific data to be passed along to the server endpoint. */
126 	unsigned char userdata[MAX_USER_DEFINED_BYTES];
127 } __packed;
128 
129 /* Open Channel Result parameters */
130 struct vmbus_channel_open_result {
131 	struct vmbus_channel_message_header header;
132 	u32 child_relid;
133 	u32 openid;
134 	u32 status;
135 } __packed;
136 
137 /* Close channel parameters; */
138 struct vmbus_channel_close_channel {
139 	struct vmbus_channel_message_header header;
140 	u32 child_relid;
141 } __packed;
142 
143 /* Channel Message GPADL */
144 #define GPADL_TYPE_RING_BUFFER		1
145 #define GPADL_TYPE_SERVER_SAVE_AREA	2
146 #define GPADL_TYPE_TRANSACTION		8
147 
148 /*
149  * The number of PFNs in a GPADL message is defined by the number of
150  * pages that would be spanned by ByteCount and ByteOffset.  If the
151  * implied number of PFNs won't fit in this packet, there will be a
152  * follow-up packet that contains more.
153  */
154 struct vmbus_channel_gpadl_header {
155 	struct vmbus_channel_message_header header;
156 	u32 child_relid;
157 	u32 gpadl;
158 	u16 range_buflen;
159 	u16 rangecount;
160 	struct gpa_range range[0];
161 } __packed;
162 
163 /* This is the followup packet that contains more PFNs. */
164 struct vmbus_channel_gpadl_body {
165 	struct vmbus_channel_message_header header;
166 	u32 msgnumber;
167 	u32 gpadl;
168 	u64 pfn[0];
169 } __packed;
170 
171 struct vmbus_channel_gpadl_created {
172 	struct vmbus_channel_message_header header;
173 	u32 child_relid;
174 	u32 gpadl;
175 	u32 creation_status;
176 } __packed;
177 
178 struct vmbus_channel_gpadl_teardown {
179 	struct vmbus_channel_message_header header;
180 	u32 child_relid;
181 	u32 gpadl;
182 } __packed;
183 
184 struct vmbus_channel_gpadl_torndown {
185 	struct vmbus_channel_message_header header;
186 	u32 gpadl;
187 } __packed;
188 
189 #ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
190 struct vmbus_channel_view_range_add {
191 	struct vmbus_channel_message_header header;
192 	PHYSICAL_ADDRESS viewrange_base;
193 	u64 viewrange_length;
194 	u32 child_relid;
195 } __packed;
196 
197 struct vmbus_channel_view_range_remove {
198 	struct vmbus_channel_message_header header;
199 	PHYSICAL_ADDRESS viewrange_base;
200 	u32 child_relid;
201 } __packed;
202 #endif
203 
204 struct vmbus_channel_relid_released {
205 	struct vmbus_channel_message_header header;
206 	u32 child_relid;
207 } __packed;
208 
209 struct vmbus_channel_initiate_contact {
210 	struct vmbus_channel_message_header header;
211 	u32 vmbus_version_requested;
212 	u32 padding2;
213 	u64 interrupt_page;
214 	u64 monitor_page1;
215 	u64 monitor_page2;
216 } __packed;
217 
218 struct vmbus_channel_version_response {
219 	struct vmbus_channel_message_header header;
220 	bool version_supported;
221 } __packed;
222 
223 enum vmbus_channel_state {
224 	CHANNEL_OFFER_STATE,
225 	CHANNEL_OPENING_STATE,
226 	CHANNEL_OPEN_STATE,
227 };
228 
229 struct vmbus_channel {
230 	struct list_head listentry;
231 
232 	struct hv_device *device_obj;
233 
234 	struct timer_list poll_timer; /* SA-111 workaround */
235 	struct work_struct work;
236 
237 	enum vmbus_channel_state state;
238 
239 	struct vmbus_channel_offer_channel offermsg;
240 	/*
241 	 * These are based on the OfferMsg.MonitorId.
242 	 * Save it here for easy access.
243 	 */
244 	u8 monitor_grp;
245 	u8 monitor_bit;
246 
247 	u32 ringbuffer_gpadlhandle;
248 
249 	/* Allocated memory for ring buffer */
250 	void *ringbuffer_pages;
251 	u32 ringbuffer_pagecount;
252 	struct hv_ring_buffer_info outbound;	/* send to parent */
253 	struct hv_ring_buffer_info inbound;	/* receive from parent */
254 	spinlock_t inbound_lock;
255 	struct workqueue_struct *controlwq;
256 
257 	/* Channel callback are invoked in this workqueue context */
258 	/* HANDLE dataWorkQueue; */
259 
260 	void (*onchannel_callback)(void *context);
261 	void *channel_callback_context;
262 };
263 
264 struct vmbus_channel_debug_info {
265 	u32 relid;
266 	enum vmbus_channel_state state;
267 	struct hv_guid interfacetype;
268 	struct hv_guid interface_instance;
269 	u32 monitorid;
270 	u32 servermonitor_pending;
271 	u32 servermonitor_latency;
272 	u32 servermonitor_connectionid;
273 	u32 clientmonitor_pending;
274 	u32 clientmonitor_latency;
275 	u32 clientmonitor_connectionid;
276 
277 	struct hv_ring_buffer_debug_info inbound;
278 	struct hv_ring_buffer_debug_info outbound;
279 };
280 
281 /*
282  * Represents each channel msg on the vmbus connection This is a
283  * variable-size data structure depending on the msg type itself
284  */
285 struct vmbus_channel_msginfo {
286 	/* Bookkeeping stuff */
287 	struct list_head msglistentry;
288 
289 	/* So far, this is only used to handle gpadl body message */
290 	struct list_head submsglist;
291 
292 	/* Synchronize the request/response if needed */
293 	int wait_condition;
294 	wait_queue_head_t waitevent;
295 	union {
296 		struct vmbus_channel_version_supported version_supported;
297 		struct vmbus_channel_open_result open_result;
298 		struct vmbus_channel_gpadl_torndown gpadl_torndown;
299 		struct vmbus_channel_gpadl_created gpadl_created;
300 		struct vmbus_channel_version_response version_response;
301 	} response;
302 
303 	u32 msgsize;
304 	/*
305 	 * The channel message that goes out on the "wire".
306 	 * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header
307 	 */
308 	unsigned char msg[0];
309 };
310 
311 
312 void free_channel(struct vmbus_channel *channel);
313 
314 void vmbus_onmessage(void *context);
315 
316 int vmbus_request_offers(void);
317 
318 void vmbus_release_unattached_channels(void);
319 
320 #endif /* _CHANNEL_MGMT_H_ */
321