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 "ring_buffer.h" 31#include "vmbus_channel_interface.h" 32#include "vmbus_packet_format.h" 33 34/* Version 1 messages */ 35enum vmbus_channel_message_type { 36 ChannelMessageInvalid = 0, 37 ChannelMessageOfferChannel = 1, 38 ChannelMessageRescindChannelOffer = 2, 39 ChannelMessageRequestOffers = 3, 40 ChannelMessageAllOffersDelivered = 4, 41 ChannelMessageOpenChannel = 5, 42 ChannelMessageOpenChannelResult = 6, 43 ChannelMessageCloseChannel = 7, 44 ChannelMessageGpadlHeader = 8, 45 ChannelMessageGpadlBody = 9, 46 ChannelMessageGpadlCreated = 10, 47 ChannelMessageGpadlTeardown = 11, 48 ChannelMessageGpadlTorndown = 12, 49 ChannelMessageRelIdReleased = 13, 50 ChannelMessageInitiateContact = 14, 51 ChannelMessageVersionResponse = 15, 52 ChannelMessageUnload = 16, 53#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD 54 ChannelMessageViewRangeAdd = 17, 55 ChannelMessageViewRangeRemove = 18, 56#endif 57 ChannelMessageCount 58}; 59 60struct vmbus_channel_message_header { 61 enum vmbus_channel_message_type MessageType; 62 u32 Padding; 63} __attribute__((packed)); 64 65/* Query VMBus Version parameters */ 66struct vmbus_channel_query_vmbus_version { 67 struct vmbus_channel_message_header Header; 68 u32 Version; 69} __attribute__((packed)); 70 71/* VMBus Version Supported parameters */ 72struct vmbus_channel_version_supported { 73 struct vmbus_channel_message_header Header; 74 bool VersionSupported; 75} __attribute__((packed)); 76 77/* Offer Channel parameters */ 78struct vmbus_channel_offer_channel { 79 struct vmbus_channel_message_header Header; 80 struct vmbus_channel_offer Offer; 81 u32 ChildRelId; 82 u8 MonitorId; 83 bool MonitorAllocated; 84} __attribute__((packed)); 85 86/* Rescind Offer parameters */ 87struct vmbus_channel_rescind_offer { 88 struct vmbus_channel_message_header Header; 89 u32 ChildRelId; 90} __attribute__((packed)); 91 92/* 93 * Request Offer -- no parameters, SynIC message contains the partition ID 94 * Set Snoop -- no parameters, SynIC message contains the partition ID 95 * Clear Snoop -- no parameters, SynIC message contains the partition ID 96 * All Offers Delivered -- no parameters, SynIC message contains the partition 97 * ID 98 * Flush Client -- no parameters, SynIC message contains the partition ID 99 */ 100 101/* Open Channel parameters */ 102struct vmbus_channel_open_channel { 103 struct vmbus_channel_message_header Header; 104 105 /* Identifies the specific VMBus channel that is being opened. */ 106 u32 ChildRelId; 107 108 /* ID making a particular open request at a channel offer unique. */ 109 u32 OpenId; 110 111 /* GPADL for the channel's ring buffer. */ 112 u32 RingBufferGpadlHandle; 113 114 /* GPADL for the channel's server context save area. */ 115 u32 ServerContextAreaGpadlHandle; 116 117 /* 118 * The upstream ring buffer begins at offset zero in the memory 119 * described by RingBufferGpadlHandle. The downstream ring buffer 120 * follows it at this offset (in pages). 121 */ 122 u32 DownstreamRingBufferPageOffset; 123 124 /* User-specific data to be passed along to the server endpoint. */ 125 unsigned char UserData[MAX_USER_DEFINED_BYTES]; 126} __attribute__((packed)); 127 128/* Open Channel Result parameters */ 129struct vmbus_channel_open_result { 130 struct vmbus_channel_message_header Header; 131 u32 ChildRelId; 132 u32 OpenId; 133 u32 Status; 134} __attribute__((packed)); 135 136/* Close channel parameters; */ 137struct vmbus_channel_close_channel { 138 struct vmbus_channel_message_header Header; 139 u32 ChildRelId; 140} __attribute__((packed)); 141 142/* Channel Message GPADL */ 143#define GPADL_TYPE_RING_BUFFER 1 144#define GPADL_TYPE_SERVER_SAVE_AREA 2 145#define GPADL_TYPE_TRANSACTION 8 146 147/* 148 * The number of PFNs in a GPADL message is defined by the number of 149 * pages that would be spanned by ByteCount and ByteOffset. If the 150 * implied number of PFNs won't fit in this packet, there will be a 151 * follow-up packet that contains more. 152 */ 153struct vmbus_channel_gpadl_header { 154 struct vmbus_channel_message_header Header; 155 u32 ChildRelId; 156 u32 Gpadl; 157 u16 RangeBufLen; 158 u16 RangeCount; 159 struct gpa_range Range[0]; 160} __attribute__((packed)); 161 162/* This is the followup packet that contains more PFNs. */ 163struct vmbus_channel_gpadl_body { 164 struct vmbus_channel_message_header Header; 165 u32 MessageNumber; 166 u32 Gpadl; 167 u64 Pfn[0]; 168} __attribute__((packed)); 169 170struct vmbus_channel_gpadl_created { 171 struct vmbus_channel_message_header Header; 172 u32 ChildRelId; 173 u32 Gpadl; 174 u32 CreationStatus; 175} __attribute__((packed)); 176 177struct vmbus_channel_gpadl_teardown { 178 struct vmbus_channel_message_header Header; 179 u32 ChildRelId; 180 u32 Gpadl; 181} __attribute__((packed)); 182 183struct vmbus_channel_gpadl_torndown { 184 struct vmbus_channel_message_header Header; 185 u32 Gpadl; 186} __attribute__((packed)); 187 188#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD 189struct vmbus_channel_view_range_add { 190 struct vmbus_channel_message_header Header; 191 PHYSICAL_ADDRESS ViewRangeBase; 192 u64 ViewRangeLength; 193 u32 ChildRelId; 194} __attribute__((packed)); 195 196struct vmbus_channel_view_range_remove { 197 struct vmbus_channel_message_header Header; 198 PHYSICAL_ADDRESS ViewRangeBase; 199 u32 ChildRelId; 200} __attribute__((packed)); 201#endif 202 203struct vmbus_channel_relid_released { 204 struct vmbus_channel_message_header Header; 205 u32 ChildRelId; 206} __attribute__((packed)); 207 208struct vmbus_channel_initiate_contact { 209 struct vmbus_channel_message_header Header; 210 u32 VMBusVersionRequested; 211 u32 Padding2; 212 u64 InterruptPage; 213 u64 MonitorPage1; 214 u64 MonitorPage2; 215} __attribute__((packed)); 216 217struct vmbus_channel_version_response { 218 struct vmbus_channel_message_header Header; 219 bool VersionSupported; 220} __attribute__((packed)); 221 222enum vmbus_channel_state { 223 CHANNEL_OFFER_STATE, 224 CHANNEL_OPENING_STATE, 225 CHANNEL_OPEN_STATE, 226}; 227 228struct vmbus_channel { 229 struct list_head ListEntry; 230 231 struct hv_device *DeviceObject; 232 233 struct timer_list poll_timer; 234 235 enum vmbus_channel_state State; 236 237 struct vmbus_channel_offer_channel OfferMsg; 238 /* 239 * These are based on the OfferMsg.MonitorId. 240 * Save it here for easy access. 241 */ 242 u8 MonitorGroup; 243 u8 MonitorBit; 244 245 u32 RingBufferGpadlHandle; 246 247 /* Allocated memory for ring buffer */ 248 void *RingBufferPages; 249 u32 RingBufferPageCount; 250 struct hv_ring_buffer_info Outbound; /* send to parent */ 251 struct hv_ring_buffer_info Inbound; /* receive from parent */ 252 spinlock_t inbound_lock; 253 struct workqueue_struct *ControlWQ; 254 255 /* Channel callback are invoked in this workqueue context */ 256 /* HANDLE dataWorkQueue; */ 257 258 void (*OnChannelCallback)(void *context); 259 void *ChannelCallbackContext; 260}; 261 262struct vmbus_channel_debug_info { 263 u32 RelId; 264 enum vmbus_channel_state State; 265 struct hv_guid InterfaceType; 266 struct hv_guid InterfaceInstance; 267 u32 MonitorId; 268 u32 ServerMonitorPending; 269 u32 ServerMonitorLatency; 270 u32 ServerMonitorConnectionId; 271 u32 ClientMonitorPending; 272 u32 ClientMonitorLatency; 273 u32 ClientMonitorConnectionId; 274 275 struct hv_ring_buffer_debug_info Inbound; 276 struct hv_ring_buffer_debug_info Outbound; 277}; 278 279/* 280 * Represents each channel msg on the vmbus connection This is a 281 * variable-size data structure depending on the msg type itself 282 */ 283struct vmbus_channel_msginfo { 284 /* Bookkeeping stuff */ 285 struct list_head MsgListEntry; 286 287 /* So far, this is only used to handle gpadl body message */ 288 struct list_head SubMsgList; 289 290 /* Synchronize the request/response if needed */ 291 struct osd_waitevent *WaitEvent; 292 293 union { 294 struct vmbus_channel_version_supported VersionSupported; 295 struct vmbus_channel_open_result OpenResult; 296 struct vmbus_channel_gpadl_torndown GpadlTorndown; 297 struct vmbus_channel_gpadl_created GpadlCreated; 298 struct vmbus_channel_version_response VersionResponse; 299 } Response; 300 301 u32 MessageSize; 302 /* 303 * The channel message that goes out on the "wire". 304 * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header 305 */ 306 unsigned char Msg[0]; 307}; 308 309 310struct vmbus_channel *AllocVmbusChannel(void); 311 312void FreeVmbusChannel(struct vmbus_channel *Channel); 313 314void VmbusOnChannelMessage(void *Context); 315 316int VmbusChannelRequestOffers(void); 317 318void VmbusChannelReleaseUnattachedChannels(void); 319 320#endif /* _CHANNEL_MGMT_H_ */ 321