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