2 * Copyright (c) 2009-2012 Microsoft Corp.
3 * Copyright (c) 2012 NetApp Inc.
4 * Copyright (c) 2012 Citrix Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice unmodified, this list of conditions, and the following
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.
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.
32 * HyperV definitions for messages that are sent between instances of the
33 * Channel Management Library in separate partitions, or in some cases,
40 #include <sys/param.h>
42 #include <sys/queue.h>
43 #include <sys/malloc.h>
44 #include <sys/kthread.h>
45 #include <sys/taskqueue.h>
46 #include <sys/systm.h>
50 #include <sys/mutex.h>
53 #include <vm/vm_param.h>
56 #include <amd64/include/xen/synch_bitops.h>
57 #include <amd64/include/atomic.h>
59 typedef uint8_t hv_bool_uint8_t;
61 #define HV_S_OK 0x00000000
62 #define HV_E_FAIL 0x80004005
63 #define HV_ERROR_NOT_SUPPORTED 0x80070032
64 #define HV_ERROR_MACHINE_LOCKED 0x800704F7
67 * VMBUS version is 32 bit, upper 16 bit for major_number and lower
68 * 16 bit for minor_number.
70 * 0.13 -- Windows Server 2008
75 #define HV_VMBUS_VERSION_WS2008 ((0 << 16) | (13))
76 #define HV_VMBUS_VERSION_WIN7 ((1 << 16) | (1))
77 #define HV_VMBUS_VERSION_WIN8 ((2 << 16) | (4))
78 #define HV_VMBUS_VERSION_WIN8_1 ((3 << 16) | (0))
80 #define HV_VMBUS_VERSION_INVALID -1
82 #define HV_VMBUS_VERSION_CURRENT HV_VMBUS_VERSION_WIN8_1
85 * Make maximum size of pipe payload of 16K
88 #define HV_MAX_PIPE_DATA_PAYLOAD (sizeof(BYTE) * 16384)
91 * Define pipe_mode values
94 #define HV_VMBUS_PIPE_TYPE_BYTE 0x00000000
95 #define HV_VMBUS_PIPE_TYPE_MESSAGE 0x00000004
98 * The size of the user defined data buffer for non-pipe offers
101 #define HV_MAX_USER_DEFINED_BYTES 120
104 * The size of the user defined data buffer for pipe offers
107 #define HV_MAX_PIPE_USER_DEFINED_BYTES 116
110 #define HV_MAX_PAGE_BUFFER_COUNT 32
111 #define HV_MAX_MULTIPAGE_BUFFER_COUNT 32
113 #define HV_ALIGN_UP(value, align) \
114 (((value) & (align-1)) ? \
115 (((value) + (align-1)) & ~(align-1) ) : (value))
117 #define HV_ALIGN_DOWN(value, align) ( (value) & ~(align-1) )
119 #define HV_NUM_PAGES_SPANNED(addr, len) \
120 ((HV_ALIGN_UP(addr+len, PAGE_SIZE) - \
121 HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT )
123 typedef struct hv_guid {
124 unsigned char data[16];
127 #define HV_NIC_GUID \
128 .data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, \
129 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}
131 #define HV_IDE_GUID \
132 .data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \
133 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5}
135 #define HV_SCSI_GUID \
136 .data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \
137 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f}
140 * At the center of the Channel Management library is
141 * the Channel Offer. This struct contains the
142 * fundamental information about an offer.
145 typedef struct hv_vmbus_channel_offer {
146 hv_guid interface_type;
147 hv_guid interface_instance;
148 uint64_t interrupt_latency_in_100ns_units;
149 uint32_t interface_revision;
150 uint32_t server_context_area_size; /* in bytes */
151 uint16_t channel_flags;
152 uint16_t mmio_megabytes; /* in bytes * 1024 * 1024 */
156 * Non-pipes: The user has HV_MAX_USER_DEFINED_BYTES bytes.
159 uint8_t user_defined[HV_MAX_USER_DEFINED_BYTES];
163 * Pipes: The following structure is an integrated pipe protocol, which
164 * is implemented on top of standard user-defined data. pipe
165 * clients have HV_MAX_PIPE_USER_DEFINED_BYTES left for their
170 uint8_t user_defined[HV_MAX_PIPE_USER_DEFINED_BYTES];
175 * Sub_channel_index, newly added in Win8.
177 uint16_t sub_channel_index;
180 } __packed hv_vmbus_channel_offer;
182 typedef uint32_t hv_gpadl_handle;
186 uint16_t data_offset8;
189 uint64_t transaction_id;
190 } __packed hv_vm_packet_descriptor;
192 typedef uint32_t hv_previous_packet_offset;
195 hv_previous_packet_offset previous_packet_start_offset;
196 hv_vm_packet_descriptor descriptor;
197 } __packed hv_vm_packet_header;
201 uint32_t byte_offset;
202 } __packed hv_vm_transfer_page;
205 hv_vm_packet_descriptor d;
206 uint16_t transfer_page_set_id;
207 hv_bool_uint8_t sender_owns_set;
209 uint32_t range_count;
210 hv_vm_transfer_page ranges[1];
211 } __packed hv_vm_transfer_page_packet_header;
214 hv_vm_packet_descriptor d;
217 } __packed hv_vm_gpadl_packet_header;
220 hv_vm_packet_descriptor d;
222 uint16_t transfer_page_set_id;
224 } __packed hv_vm_add_remove_transfer_page_set;
227 * This structure defines a range in guest
228 * physical space that can be made
229 * to look virtually contiguous.
234 uint32_t byte_offset;
235 uint64_t pfn_array[0];
236 } __packed hv_gpa_range;
239 * This is the format for an Establish Gpadl packet, which contains a handle
240 * by which this GPADL will be known and a set of GPA ranges associated with
241 * it. This can be converted to a MDL by the guest OS. If there are multiple
242 * GPA ranges, then the resulting MDL will be "chained," representing multiple
247 hv_vm_packet_descriptor d;
249 uint32_t range_count;
250 hv_gpa_range range[1];
251 } __packed hv_vm_establish_gpadl;
254 * This is the format for a Teardown Gpadl packet, which indicates that the
255 * GPADL handle in the Establish Gpadl packet will never be referenced again.
259 hv_vm_packet_descriptor d;
261 /* for alignment to a 8-byte boundary */
263 } __packed hv_vm_teardown_gpadl;
266 * This is the format for a GPA-Direct packet, which contains a set of GPA
267 * ranges, in addition to commands and/or data.
271 hv_vm_packet_descriptor d;
273 uint32_t range_count;
274 hv_gpa_range range[1];
275 } __packed hv_vm_data_gpa_direct;
278 * This is the format for a Additional data Packet.
281 hv_vm_packet_descriptor d;
282 uint64_t total_bytes;
283 uint32_t byte_offset;
286 } __packed hv_vm_additional_data;
289 hv_vm_packet_descriptor simple_header;
290 hv_vm_transfer_page_packet_header transfer_page_header;
291 hv_vm_gpadl_packet_header gpadl_header;
292 hv_vm_add_remove_transfer_page_set add_remove_transfer_page_header;
293 hv_vm_establish_gpadl establish_gpadl_header;
294 hv_vm_teardown_gpadl teardown_gpadl_header;
295 hv_vm_data_gpa_direct data_gpa_direct_header;
296 } __packed hv_vm_packet_largest_possible_header;
299 HV_VMBUS_PACKET_TYPE_INVALID = 0x0,
300 HV_VMBUS_PACKET_TYPES_SYNCH = 0x1,
301 HV_VMBUS_PACKET_TYPE_ADD_TRANSFER_PAGE_SET = 0x2,
302 HV_VMBUS_PACKET_TYPE_REMOVE_TRANSFER_PAGE_SET = 0x3,
303 HV_VMBUS_PACKET_TYPE_ESTABLISH_GPADL = 0x4,
304 HV_VMBUS_PACKET_TYPE_TEAR_DOWN_GPADL = 0x5,
305 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND = 0x6,
306 HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES = 0x7,
307 HV_VMBUS_PACKET_TYPE_DATA_USING_GPADL = 0x8,
308 HV_VMBUS_PACKET_TYPE_DATA_USING_GPA_DIRECT = 0x9,
309 HV_VMBUS_PACKET_TYPE_CANCEL_REQUEST = 0xa,
310 HV_VMBUS_PACKET_TYPE_COMPLETION = 0xb,
311 HV_VMBUS_PACKET_TYPE_DATA_USING_ADDITIONAL_PACKETS = 0xc,
312 HV_VMBUS_PACKET_TYPE_ADDITIONAL_DATA = 0xd
313 } hv_vmbus_packet_type;
315 #define HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1
321 HV_CHANNEL_MESSAGE_INVALID = 0,
322 HV_CHANNEL_MESSAGE_OFFER_CHANNEL = 1,
323 HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER = 2,
324 HV_CHANNEL_MESSAGE_REQUEST_OFFERS = 3,
325 HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED = 4,
326 HV_CHANNEL_MESSAGE_OPEN_CHANNEL = 5,
327 HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT = 6,
328 HV_CHANNEL_MESSAGE_CLOSE_CHANNEL = 7,
329 HV_CHANNEL_MESSAGEL_GPADL_HEADER = 8,
330 HV_CHANNEL_MESSAGE_GPADL_BODY = 9,
331 HV_CHANNEL_MESSAGE_GPADL_CREATED = 10,
332 HV_CHANNEL_MESSAGE_GPADL_TEARDOWN = 11,
333 HV_CHANNEL_MESSAGE_GPADL_TORNDOWN = 12,
334 HV_CHANNEL_MESSAGE_REL_ID_RELEASED = 13,
335 HV_CHANNEL_MESSAGE_INITIATED_CONTACT = 14,
336 HV_CHANNEL_MESSAGE_VERSION_RESPONSE = 15,
337 HV_CHANNEL_MESSAGE_UNLOAD = 16,
339 #ifdef HV_VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
340 HV_CHANNEL_MESSAGE_VIEW_RANGE_ADD = 17,
341 HV_CHANNEL_MESSAGE_VIEW_RANGE_REMOVE = 18,
343 HV_CHANNEL_MESSAGE_COUNT
344 } hv_vmbus_channel_msg_type;
347 hv_vmbus_channel_msg_type message_type;
349 } __packed hv_vmbus_channel_msg_header;
352 * Query VMBus Version parameters
355 hv_vmbus_channel_msg_header header;
357 } __packed hv_vmbus_channel_query_vmbus_version;
360 * VMBus Version Supported parameters
363 hv_vmbus_channel_msg_header header;
364 hv_bool_uint8_t version_supported;
365 } __packed hv_vmbus_channel_version_supported;
368 * Channel Offer parameters
371 hv_vmbus_channel_msg_header header;
372 hv_vmbus_channel_offer offer;
373 uint32_t child_rel_id;
376 * This field has been split into a bit field on Win7
379 uint8_t monitor_allocated:1;
382 * Following fields were added in win7 and higher.
383 * Make sure to check the version before accessing these fields.
385 * If "is_dedicated_interrupt" is set, we must not set the
386 * associated bit in the channel bitmap while sending the
387 * interrupt to the host.
389 * connection_id is used in signaling the host.
391 uint16_t is_dedicated_interrupt:1;
392 uint16_t reserved1:15;
393 uint32_t connection_id;
394 } __packed hv_vmbus_channel_offer_channel;
397 * Rescind Offer parameters
401 hv_vmbus_channel_msg_header header;
402 uint32_t child_rel_id;
403 } __packed hv_vmbus_channel_rescind_offer;
407 * Request Offer -- no parameters, SynIC message contains the partition ID
409 * Set Snoop -- no parameters, SynIC message contains the partition ID
411 * Clear Snoop -- no parameters, SynIC message contains the partition ID
413 * All Offers Delivered -- no parameters, SynIC message contains the
416 * Flush Client -- no parameters, SynIC message contains the partition ID
421 * Open Channel parameters
425 hv_vmbus_channel_msg_header header;
428 * Identifies the specific VMBus channel that is being opened.
430 uint32_t child_rel_id;
433 * ID making a particular open request at a channel offer unique.
438 * GPADL for the channel's ring buffer.
440 hv_gpadl_handle ring_buffer_gpadl_handle;
443 * Before win8, all incoming channel interrupts are only
444 * delivered on cpu 0. Setting this value to 0 would
445 * preserve the earlier behavior.
447 uint32_t target_vcpu;
450 * The upstream ring buffer begins at offset zero in the memory described
451 * by ring_buffer_gpadl_handle. The downstream ring buffer follows it at
452 * this offset (in pages).
454 uint32_t downstream_ring_buffer_page_offset;
457 * User-specific data to be passed along to the server endpoint.
459 uint8_t user_data[HV_MAX_USER_DEFINED_BYTES];
461 } __packed hv_vmbus_channel_open_channel;
463 typedef uint32_t hv_nt_status;
466 * Open Channel Result parameters
470 hv_vmbus_channel_msg_header header;
471 uint32_t child_rel_id;
474 } __packed hv_vmbus_channel_open_result;
477 * Close channel parameters
481 hv_vmbus_channel_msg_header header;
482 uint32_t child_rel_id;
483 } __packed hv_vmbus_channel_close_channel;
486 * Channel Message GPADL
488 #define HV_GPADL_TYPE_RING_BUFFER 1
489 #define HV_GPADL_TYPE_SERVER_SAVE_AREA 2
490 #define HV_GPADL_TYPE_TRANSACTION 8
493 * The number of PFNs in a GPADL message is defined by the number of pages
494 * that would be spanned by byte_count and byte_offset. If the implied number
495 * of PFNs won't fit in this packet, there will be a follow-up packet that
500 hv_vmbus_channel_msg_header header;
501 uint32_t child_rel_id;
503 uint16_t range_buf_len;
504 uint16_t range_count;
505 hv_gpa_range range[0];
506 } __packed hv_vmbus_channel_gpadl_header;
509 * This is the follow-up packet that contains more PFNs
512 hv_vmbus_channel_msg_header header;
513 uint32_t message_number;
516 } __packed hv_vmbus_channel_gpadl_body;
519 hv_vmbus_channel_msg_header header;
520 uint32_t child_rel_id;
522 uint32_t creation_status;
523 } __packed hv_vmbus_channel_gpadl_created;
526 hv_vmbus_channel_msg_header header;
527 uint32_t child_rel_id;
529 } __packed hv_vmbus_channel_gpadl_teardown;
532 hv_vmbus_channel_msg_header header;
534 } __packed hv_vmbus_channel_gpadl_torndown;
537 hv_vmbus_channel_msg_header header;
538 uint32_t child_rel_id;
539 } __packed hv_vmbus_channel_relid_released;
542 hv_vmbus_channel_msg_header header;
543 uint32_t vmbus_version_requested;
545 uint64_t interrupt_page;
546 uint64_t monitor_page_1;
547 uint64_t monitor_page_2;
548 } __packed hv_vmbus_channel_initiate_contact;
551 hv_vmbus_channel_msg_header header;
552 hv_bool_uint8_t version_supported;
553 } __packed hv_vmbus_channel_version_response;
555 typedef hv_vmbus_channel_msg_header hv_vmbus_channel_unload;
557 #define HW_MACADDR_LEN 6
560 * Fixme: Added to quiet "typeof" errors involving hv_vmbus.h when
561 * the including C file was compiled with "-std=c99".
564 #define typeof __typeof
568 #define NULL (void *)0
571 typedef void *hv_vmbus_handle;
573 #ifndef CONTAINING_RECORD
574 #define CONTAINING_RECORD(address, type, field) ((type *)( \
575 (uint8_t *)(address) - \
576 (uint8_t *)(&((type *)0)->field)))
577 #endif /* CONTAINING_RECORD */
580 #define container_of(ptr, type, member) ({ \
581 __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
582 (type *)( (char *)__mptr - offsetof(type,member) );})
586 HV_VMBUS_IVAR_INSTANCE,
591 #define HV_VMBUS_ACCESSOR(var, ivar, type) \
592 __BUS_ACCESSOR(vmbus, var, HV_VMBUS, ivar, type)
594 HV_VMBUS_ACCESSOR(type, TYPE, const char *)
595 HV_VMBUS_ACCESSOR(devctx, DEVCTX, struct hv_device *)
599 * Common defines for Hyper-V ICs
601 #define HV_ICMSGTYPE_NEGOTIATE 0
602 #define HV_ICMSGTYPE_HEARTBEAT 1
603 #define HV_ICMSGTYPE_KVPEXCHANGE 2
604 #define HV_ICMSGTYPE_SHUTDOWN 3
605 #define HV_ICMSGTYPE_TIMESYNC 4
606 #define HV_ICMSGTYPE_VSS 5
608 #define HV_ICMSGHDRFLAG_TRANSACTION 1
609 #define HV_ICMSGHDRFLAG_REQUEST 2
610 #define HV_ICMSGHDRFLAG_RESPONSE 4
612 typedef struct hv_vmbus_pipe_hdr {
615 } __packed hv_vmbus_pipe_hdr;
617 typedef struct hv_vmbus_ic_version {
620 } __packed hv_vmbus_ic_version;
622 typedef struct hv_vmbus_icmsg_hdr {
623 hv_vmbus_ic_version icverframe;
625 hv_vmbus_ic_version icvermsg;
628 uint8_t ictransaction_id;
631 } __packed hv_vmbus_icmsg_hdr;
633 typedef struct hv_vmbus_icmsg_negotiate {
634 uint16_t icframe_vercnt;
635 uint16_t icmsg_vercnt;
637 hv_vmbus_ic_version icversion_data[1]; /* any size array */
638 } __packed hv_vmbus_icmsg_negotiate;
640 typedef struct hv_vmbus_shutdown_msg_data {
641 uint32_t reason_code;
642 uint32_t timeout_seconds;
644 uint8_t display_message[2048];
645 } __packed hv_vmbus_shutdown_msg_data;
647 typedef struct hv_vmbus_heartbeat_msg_data {
649 uint32_t reserved[8];
650 } __packed hv_vmbus_heartbeat_msg_data;
654 * offset in bytes from the start of ring data below
656 volatile uint32_t write_index;
658 * offset in bytes from the start of ring data below
660 volatile uint32_t read_index;
662 * NOTE: The interrupt_mask field is used only for channels, but
663 * vmbus connection also uses this data structure
665 volatile uint32_t interrupt_mask;
666 /* pad it to PAGE_SIZE so that data starts on a page */
667 uint8_t reserved[4084];
670 * WARNING: Ring data starts here + ring_data_start_offset
671 * !!! DO NOT place any fields below this !!!
673 uint8_t buffer[0]; /* doubles as interrupt mask */
674 } __packed hv_vmbus_ring_buffer;
680 } __packed hv_vmbus_page_buffer;
685 uint64_t pfn_array[HV_MAX_MULTIPAGE_BUFFER_COUNT];
686 } __packed hv_vmbus_multipage_buffer;
689 hv_vmbus_ring_buffer* ring_buffer;
690 uint32_t ring_size; /* Include the shared header */
691 struct mtx ring_lock;
692 uint32_t ring_data_size; /* ring_size */
693 uint32_t ring_data_start_offset;
694 } hv_vmbus_ring_buffer_info;
696 typedef void (*hv_vmbus_pfn_channel_callback)(void *context);
697 typedef void (*hv_vmbus_sc_creation_callback)(void *context);
700 HV_CHANNEL_OFFER_STATE,
701 HV_CHANNEL_OPENING_STATE,
702 HV_CHANNEL_OPEN_STATE,
703 HV_CHANNEL_OPENED_STATE,
704 HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE,
705 } hv_vmbus_channel_state;
708 * Connection identifier type
711 uint32_t as_uint32_t;
717 } __packed hv_vmbus_connection_id;
720 * Definition of the hv_vmbus_signal_event hypercall input structure
723 hv_vmbus_connection_id connection_id;
724 uint16_t flag_number;
726 } __packed hv_vmbus_input_signal_event;
730 hv_vmbus_input_signal_event event;
731 } __packed hv_vmbus_input_signal_event_buffer;
733 typedef struct hv_vmbus_channel {
734 TAILQ_ENTRY(hv_vmbus_channel) list_entry;
735 struct hv_device* device;
736 hv_vmbus_channel_state state;
737 hv_vmbus_channel_offer_channel offer_msg;
739 * These are based on the offer_msg.monitor_id.
740 * Save it here for easy access.
742 uint8_t monitor_group;
745 uint32_t ring_buffer_gpadl_handle;
747 * Allocated memory for ring buffer
749 void* ring_buffer_pages;
750 unsigned long ring_buffer_size;
751 uint32_t ring_buffer_page_count;
755 hv_vmbus_ring_buffer_info outbound;
757 * receive from parent
759 hv_vmbus_ring_buffer_info inbound;
761 struct mtx inbound_lock;
762 hv_vmbus_handle control_work_queue;
764 hv_vmbus_pfn_channel_callback on_channel_callback;
765 void* channel_callback_context;
768 * If batched_reading is set to "true", mask the interrupt
769 * and read until the channel is empty.
770 * If batched_reading is set to "false", the channel is not
771 * going to perform batched reading.
773 * Batched reading is enabled by default; specific
774 * drivers that don't want this behavior can turn it off.
776 boolean_t batched_reading;
778 boolean_t is_dedicated_interrupt;
781 * Used as an input param for HV_CALL_SIGNAL_EVENT hypercall.
783 hv_vmbus_input_signal_event_buffer signal_event_buffer;
785 * 8-bytes aligned of the buffer above
787 hv_vmbus_input_signal_event *signal_event_param;
790 * From Win8, this field specifies the target virtual process
791 * on which to deliver the interupt from the host to guest.
792 * Before Win8, all channel interrupts would only be
793 * delivered on cpu 0. Setting this value to 0 would preserve
794 * the earlier behavior.
796 uint32_t target_vcpu;
797 /* The corresponding CPUID in the guest */
801 * Support for multi-channels.
802 * The initial offer is considered the primary channel and this
803 * offer message will indicate if the host supports multi-channels.
804 * The guest is free to ask for multi-channels to be offerred and can
805 * open these multi-channels as a normal "primary" channel. However,
806 * all multi-channels will have the same type and instance guids as the
807 * primary channel. Requests sent on a given channel will result in a
808 * response on the same channel.
812 * Multi-channel creation callback. This callback will be called in
813 * process context when a Multi-channel offer is received from the host.
814 * The guest can open the Multi-channel in the context of this callback.
816 hv_vmbus_sc_creation_callback sc_creation_callback;
821 * Link list of all the multi-channels if this is a primary channel
823 TAILQ_HEAD(, hv_vmbus_channel) sc_list_anchor;
824 TAILQ_ENTRY(hv_vmbus_channel) sc_list_entry;
827 * The primary channel this sub-channle belongs to.
828 * This will be NULL for the primary channel.
830 struct hv_vmbus_channel *primary_channel;
832 * Support per channel state for use by vmbus drivers.
834 void *per_channel_state;
838 hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t state)
840 channel->batched_reading = state;
843 typedef struct hv_device {
847 hv_vmbus_channel* channel;
852 int hv_vmbus_channel_recv_packet(
853 hv_vmbus_channel* channel,
856 uint32_t* buffer_actual_len,
857 uint64_t* request_id);
859 int hv_vmbus_channel_recv_packet_raw(
860 hv_vmbus_channel* channel,
863 uint32_t* buffer_actual_len,
864 uint64_t* request_id);
866 int hv_vmbus_channel_open(
867 hv_vmbus_channel* channel,
868 uint32_t send_ring_buffer_size,
869 uint32_t recv_ring_buffer_size,
871 uint32_t user_data_len,
872 hv_vmbus_pfn_channel_callback
873 pfn_on_channel_callback,
876 void hv_vmbus_channel_close(hv_vmbus_channel *channel);
878 int hv_vmbus_channel_send_packet(
879 hv_vmbus_channel* channel,
883 hv_vmbus_packet_type type,
886 int hv_vmbus_channel_send_packet_pagebuffer(
887 hv_vmbus_channel* channel,
888 hv_vmbus_page_buffer page_buffers[],
892 uint64_t request_id);
894 int hv_vmbus_channel_send_packet_multipagebuffer(
895 hv_vmbus_channel* channel,
896 hv_vmbus_multipage_buffer* multi_page_buffer,
899 uint64_t request_id);
901 int hv_vmbus_channel_establish_gpadl(
902 hv_vmbus_channel* channel,
903 /* must be phys and virt contiguous */
905 /* page-size multiple */
907 uint32_t* gpadl_handle);
909 int hv_vmbus_channel_teardown_gpdal(
910 hv_vmbus_channel* channel,
911 uint32_t gpadl_handle);
913 struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary);
916 * Work abstraction defines
918 typedef struct hv_work_queue {
919 struct taskqueue* queue;
921 struct sema* work_sema;
924 typedef struct hv_work_item {
926 void (*callback)(void *);
931 struct hv_work_queue* hv_work_queue_create(char* name);
933 void hv_work_queue_close(struct hv_work_queue* wq);
935 int hv_queue_work_item(
937 void (*callback)(void *),
940 * @brief Get physical address from virtual
942 static inline unsigned long
943 hv_get_phys_addr(void *virt)
946 ret = (vtophys(virt) | ((vm_offset_t) virt & PAGE_MASK));
952 * KVP related structures
955 typedef struct hv_vmbus_service {
956 hv_guid guid; /* Hyper-V GUID */
957 char *name; /* name of service */
958 boolean_t enabled; /* service enabled */
959 hv_work_queue *work_queue; /* background work queue */
962 * function to initialize service
964 int (*init)(struct hv_vmbus_service *);
967 * function to process Hyper-V messages
969 void (*callback)(void *);
972 extern uint8_t* receive_buffer[];
973 extern hv_vmbus_service service_table[];
974 extern uint32_t hv_vmbus_protocal_version;
976 void hv_kvp_callback(void *context);
977 int hv_kvp_init(hv_vmbus_service *serv);
978 void hv_kvp_deinit(void);
980 #endif /* __HYPERV_H__ */