]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/hyperv/include/hyperv.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / hyperv / include / hyperv.h
1 /*-
2  * Copyright (c) 2009-2012 Microsoft Corp.
3  * Copyright (c) 2012 NetApp Inc.
4  * Copyright (c) 2012 Citrix Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
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.
16  *
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.
27  *
28  * $FreeBSD$
29  */
30
31 /**
32  * HyperV definitions for messages that are sent between instances of the
33  * Channel Management Library in separate partitions, or in some cases,
34  * back to itself.
35  */
36
37 #ifndef __HYPERV_H__
38 #define __HYPERV_H__
39
40 #include <sys/param.h>
41 #include <sys/mbuf.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>
47 #include <sys/lock.h>
48 #include <sys/sema.h>
49 #include <sys/mutex.h>
50 #include <sys/bus.h>
51 #include <vm/vm.h>
52 #include <vm/vm_param.h>
53 #include <vm/pmap.h>
54
55 #include <amd64/include/xen/synch_bitops.h>
56 #include <amd64/include/atomic.h>
57
58 typedef uint8_t hv_bool_uint8_t;
59
60 #define HV_S_OK                 0x00000000
61 #define HV_E_FAIL               0x80004005
62 #define HV_ERROR_NOT_SUPPORTED  0x80070032
63 #define HV_ERROR_MACHINE_LOCKED 0x800704F7
64
65 /*
66  * A revision number of vmbus that is used for ensuring both ends on a
67  * partition are using compatible versions.
68  */
69
70 #define HV_VMBUS_REVISION_NUMBER        13
71
72 /*
73  * Make maximum size of pipe payload of 16K
74  */
75
76 #define HV_MAX_PIPE_DATA_PAYLOAD        (sizeof(BYTE) * 16384)
77
78 /*
79  * Define pipe_mode values
80  */
81
82 #define HV_VMBUS_PIPE_TYPE_BYTE         0x00000000
83 #define HV_VMBUS_PIPE_TYPE_MESSAGE      0x00000004
84
85 /*
86  * The size of the user defined data buffer for non-pipe offers
87  */
88
89 #define HV_MAX_USER_DEFINED_BYTES       120
90
91 /*
92  *  The size of the user defined data buffer for pipe offers
93  */
94
95 #define HV_MAX_PIPE_USER_DEFINED_BYTES  116
96
97
98 #define HV_MAX_PAGE_BUFFER_COUNT        16
99 #define HV_MAX_MULTIPAGE_BUFFER_COUNT   32
100
101 #define HV_ALIGN_UP(value, align)                                       \
102                 (((value) & (align-1)) ?                                \
103                     (((value) + (align-1)) & ~(align-1) ) : (value))
104
105 #define HV_ALIGN_DOWN(value, align) ( (value) & ~(align-1) )
106
107 #define HV_NUM_PAGES_SPANNED(addr, len)                                 \
108                 ((HV_ALIGN_UP(addr+len, PAGE_SIZE) -                    \
109                     HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT )
110
111 typedef struct hv_guid {
112          unsigned char data[16];
113 } __packed hv_guid;
114
115 /*
116  * At the center of the Channel Management library is
117  * the Channel Offer. This struct contains the
118  * fundamental information about an offer.
119  */
120
121 typedef struct hv_vmbus_channel_offer {
122         hv_guid         interface_type;
123         hv_guid         interface_instance;
124         uint64_t        interrupt_latency_in_100ns_units;
125         uint32_t        interface_revision;
126         uint32_t        server_context_area_size; /* in bytes */
127         uint16_t        channel_flags;
128         uint16_t        mmio_megabytes;           /* in bytes * 1024 * 1024 */
129         union
130         {
131         /*
132          * Non-pipes: The user has HV_MAX_USER_DEFINED_BYTES bytes.
133          */
134                 struct {
135                         uint8_t user_defined[HV_MAX_USER_DEFINED_BYTES];
136                 } __packed standard;
137
138         /*
139          * Pipes: The following structure is an integrated pipe protocol, which
140          *        is implemented on top of standard user-defined data. pipe
141          *        clients  have HV_MAX_PIPE_USER_DEFINED_BYTES left for their
142          *        own use.
143          */
144                 struct {
145                         uint32_t        pipe_mode;
146                         uint8_t user_defined[HV_MAX_PIPE_USER_DEFINED_BYTES];
147                 } __packed pipe;
148         } u;
149
150         uint32_t        padding;
151
152 } __packed hv_vmbus_channel_offer;
153
154 typedef uint32_t hv_gpadl_handle;
155
156 typedef struct {
157         uint16_t type;
158         uint16_t data_offset8;
159         uint16_t length8;
160         uint16_t flags;
161         uint64_t transaction_id;
162 } __packed hv_vm_packet_descriptor;
163
164 typedef uint32_t hv_previous_packet_offset;
165
166 typedef struct {
167         hv_previous_packet_offset       previous_packet_start_offset;
168         hv_vm_packet_descriptor         descriptor;
169 } __packed hv_vm_packet_header;
170
171 typedef struct {
172         uint32_t byte_count;
173         uint32_t byte_offset;
174 } __packed hv_vm_transfer_page;
175
176 typedef struct {
177         hv_vm_packet_descriptor d;
178         uint16_t                transfer_page_set_id;
179         hv_bool_uint8_t         sender_owns_set;
180         uint8_t                 reserved;
181         uint32_t                range_count;
182         hv_vm_transfer_page     ranges[1];
183 } __packed hv_vm_transfer_page_packet_header;
184
185 typedef struct {
186         hv_vm_packet_descriptor d;
187         uint32_t                gpadl;
188         uint32_t                reserved;
189 } __packed hv_vm_gpadl_packet_header;
190
191 typedef struct {
192         hv_vm_packet_descriptor d;
193         uint32_t                gpadl;
194         uint16_t                transfer_page_set_id;
195         uint16_t                reserved;
196 } __packed hv_vm_add_remove_transfer_page_set;
197
198 /*
199  * This structure defines a range in guest
200  * physical space that can be made
201  * to look virtually contiguous.
202  */
203
204 typedef struct {
205         uint32_t byte_count;
206         uint32_t byte_offset;
207         uint64_t pfn_array[0];
208 } __packed hv_gpa_range;
209
210 /*
211  * This is the format for an Establish Gpadl packet, which contains a handle
212  * by which this GPADL will be known and a set of GPA ranges associated with
213  * it.  This can be converted to a MDL by the guest OS.  If there are multiple
214  * GPA ranges, then the resulting MDL will be "chained," representing multiple
215  * VA ranges.
216  */
217
218 typedef struct {
219         hv_vm_packet_descriptor d;
220         uint32_t                gpadl;
221         uint32_t                range_count;
222         hv_gpa_range            range[1];
223 } __packed hv_vm_establish_gpadl;
224
225 /*
226  * This is the format for a Teardown Gpadl packet, which indicates that the
227  * GPADL handle in the Establish Gpadl packet will never be referenced again.
228  */
229
230 typedef struct {
231         hv_vm_packet_descriptor d;
232         uint32_t                gpadl;
233                                 /* for alignment to a 8-byte boundary */
234         uint32_t                reserved;
235 } __packed hv_vm_teardown_gpadl;
236
237 /*
238  * This is the format for a GPA-Direct packet, which contains a set of GPA
239  * ranges, in addition to commands and/or data.
240  */
241
242 typedef struct {
243         hv_vm_packet_descriptor d;
244         uint32_t                reserved;
245         uint32_t                range_count;
246         hv_gpa_range            range[1];
247 } __packed hv_vm_data_gpa_direct;
248
249 /*
250  * This is the format for a Additional data Packet.
251  */
252 typedef struct {
253         hv_vm_packet_descriptor d;
254         uint64_t                total_bytes;
255         uint32_t                byte_offset;
256         uint32_t                byte_count;
257         uint8_t                 data[1];
258 } __packed hv_vm_additional_data;
259
260 typedef union {
261         hv_vm_packet_descriptor             simple_header;
262         hv_vm_transfer_page_packet_header   transfer_page_header;
263         hv_vm_gpadl_packet_header           gpadl_header;
264         hv_vm_add_remove_transfer_page_set  add_remove_transfer_page_header;
265         hv_vm_establish_gpadl               establish_gpadl_header;
266         hv_vm_teardown_gpadl                teardown_gpadl_header;
267         hv_vm_data_gpa_direct               data_gpa_direct_header;
268 } __packed hv_vm_packet_largest_possible_header;
269
270 typedef enum {
271         HV_VMBUS_PACKET_TYPE_INVALID                            = 0x0,
272         HV_VMBUS_PACKET_TYPES_SYNCH                             = 0x1,
273         HV_VMBUS_PACKET_TYPE_ADD_TRANSFER_PAGE_SET              = 0x2,
274         HV_VMBUS_PACKET_TYPE_REMOVE_TRANSFER_PAGE_SET           = 0x3,
275         HV_VMBUS_PACKET_TYPE_ESTABLISH_GPADL                    = 0x4,
276         HV_VMBUS_PACKET_TYPE_TEAR_DOWN_GPADL                    = 0x5,
277         HV_VMBUS_PACKET_TYPE_DATA_IN_BAND                       = 0x6,
278         HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES          = 0x7,
279         HV_VMBUS_PACKET_TYPE_DATA_USING_GPADL                   = 0x8,
280         HV_VMBUS_PACKET_TYPE_DATA_USING_GPA_DIRECT              = 0x9,
281         HV_VMBUS_PACKET_TYPE_CANCEL_REQUEST                     = 0xa,
282         HV_VMBUS_PACKET_TYPE_COMPLETION                         = 0xb,
283         HV_VMBUS_PACKET_TYPE_DATA_USING_ADDITIONAL_PACKETS      = 0xc,
284         HV_VMBUS_PACKET_TYPE_ADDITIONAL_DATA = 0xd
285 } hv_vmbus_packet_type;
286
287 #define HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED    1
288
289 /*
290  * Version 1 messages
291  */
292 typedef enum {
293         HV_CHANNEL_MESSAGE_INVALID                      = 0,
294         HV_CHANNEL_MESSAGE_OFFER_CHANNEL                = 1,
295         HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER        = 2,
296         HV_CHANNEL_MESSAGE_REQUEST_OFFERS               = 3,
297         HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED         = 4,
298         HV_CHANNEL_MESSAGE_OPEN_CHANNEL                 = 5,
299         HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT          = 6,
300         HV_CHANNEL_MESSAGE_CLOSE_CHANNEL                = 7,
301         HV_CHANNEL_MESSAGEL_GPADL_HEADER                = 8,
302         HV_CHANNEL_MESSAGE_GPADL_BODY                   = 9,
303         HV_CHANNEL_MESSAGE_GPADL_CREATED                = 10,
304         HV_CHANNEL_MESSAGE_GPADL_TEARDOWN               = 11,
305         HV_CHANNEL_MESSAGE_GPADL_TORNDOWN               = 12,
306         HV_CHANNEL_MESSAGE_REL_ID_RELEASED              = 13,
307         HV_CHANNEL_MESSAGE_INITIATED_CONTACT            = 14,
308         HV_CHANNEL_MESSAGE_VERSION_RESPONSE             = 15,
309         HV_CHANNEL_MESSAGE_UNLOAD                       = 16,
310
311 #ifdef  HV_VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
312         HV_CHANNEL_MESSAGE_VIEW_RANGE_ADD               = 17,
313         HV_CHANNEL_MESSAGE_VIEW_RANGE_REMOVE            = 18,
314 #endif
315         HV_CHANNEL_MESSAGE_COUNT
316 } hv_vmbus_channel_msg_type;
317
318 typedef struct {
319         hv_vmbus_channel_msg_type       message_type;
320         uint32_t                        padding;
321 } __packed hv_vmbus_channel_msg_header;
322
323 /*
324  * Query VMBus Version parameters
325  */
326 typedef struct {
327         hv_vmbus_channel_msg_header     header;
328         uint32_t                        version;
329 } __packed hv_vmbus_channel_query_vmbus_version;
330
331 /*
332  * VMBus Version Supported parameters
333  */
334 typedef struct {
335         hv_vmbus_channel_msg_header     header;
336         hv_bool_uint8_t                 version_supported;
337 } __packed hv_vmbus_channel_version_supported;
338
339 /*
340  * Channel Offer parameters
341  */
342 typedef struct {
343         hv_vmbus_channel_msg_header     header;
344         hv_vmbus_channel_offer          offer;
345         uint32_t                        child_rel_id;
346         uint8_t                         monitor_id;
347         hv_bool_uint8_t                 monitor_allocated;
348 } __packed hv_vmbus_channel_offer_channel;
349
350 /*
351  * Rescind Offer parameters
352  */
353 typedef struct
354 {
355     hv_vmbus_channel_msg_header header;
356     uint32_t                    child_rel_id;
357 } __packed hv_vmbus_channel_rescind_offer;
358
359
360 /*
361  * Request Offer -- no parameters, SynIC message contains the partition ID
362  *
363  * Set Snoop -- no parameters, SynIC message contains the partition ID
364  *
365  * Clear Snoop -- no parameters, SynIC message contains the partition ID
366  *
367  * All Offers Delivered -- no parameters, SynIC message contains the
368  * partition ID
369  *
370  * Flush Client -- no parameters, SynIC message contains the partition ID
371  */
372
373
374 /*
375  * Open Channel parameters
376  */
377 typedef struct
378 {
379     hv_vmbus_channel_msg_header header;
380
381     /*
382      * Identifies the specific VMBus channel that is being opened.
383      */
384     uint32_t            child_rel_id;
385
386     /*
387      * ID making a particular open request at a channel offer unique.
388      */
389     uint32_t            open_id;
390
391     /*
392      * GPADL for the channel's ring buffer.
393      */
394     hv_gpadl_handle     ring_buffer_gpadl_handle;
395
396     /*
397      * GPADL for the channel's server context save area.
398      */
399     hv_gpadl_handle     server_context_area_gpadl_handle;
400
401     /*
402      * The upstream ring buffer begins at offset zero in the memory described
403      * by ring_buffer_gpadl_handle. The downstream ring buffer follows it at
404      * this offset (in pages).
405      */
406     uint32_t            downstream_ring_buffer_page_offset;
407
408     /*
409      * User-specific data to be passed along to the server endpoint.
410      */
411     uint8_t             user_data[HV_MAX_USER_DEFINED_BYTES];
412
413 } __packed hv_vmbus_channel_open_channel;
414
415 typedef uint32_t hv_nt_status;
416
417 /*
418  * Open Channel Result parameters
419  */
420 typedef struct
421 {
422         hv_vmbus_channel_msg_header     header;
423         uint32_t                        child_rel_id;
424         uint32_t                        open_id;
425         hv_nt_status                    status;
426 } __packed hv_vmbus_channel_open_result;
427
428 /*
429  * Close channel parameters
430  */
431 typedef struct
432 {
433         hv_vmbus_channel_msg_header     header;
434         uint32_t                        child_rel_id;
435 } __packed hv_vmbus_channel_close_channel;
436
437 /*
438  * Channel Message GPADL
439  */
440 #define HV_GPADL_TYPE_RING_BUFFER       1
441 #define HV_GPADL_TYPE_SERVER_SAVE_AREA  2
442 #define HV_GPADL_TYPE_TRANSACTION       8
443
444 /*
445  * The number of PFNs in a GPADL message is defined by the number of pages
446  * that would be spanned by byte_count and byte_offset.  If the implied number
447  * of PFNs won't fit in this packet, there will be a follow-up packet that
448  * contains more
449  */
450
451 typedef struct {
452         hv_vmbus_channel_msg_header     header;
453         uint32_t                        child_rel_id;
454         uint32_t                        gpadl;
455         uint16_t                        range_buf_len;
456         uint16_t                        range_count;
457         hv_gpa_range                    range[0];
458 } __packed hv_vmbus_channel_gpadl_header;
459
460 /*
461  * This is the follow-up packet that contains more PFNs
462  */
463 typedef struct {
464         hv_vmbus_channel_msg_header     header;
465         uint32_t                        message_number;
466         uint32_t                        gpadl;
467         uint64_t                        pfn[0];
468 } __packed hv_vmbus_channel_gpadl_body;
469
470 typedef struct {
471         hv_vmbus_channel_msg_header     header;
472         uint32_t                        child_rel_id;
473         uint32_t                        gpadl;
474         uint32_t                        creation_status;
475 } __packed hv_vmbus_channel_gpadl_created;
476
477 typedef struct {
478         hv_vmbus_channel_msg_header     header;
479         uint32_t                        child_rel_id;
480         uint32_t                        gpadl;
481 } __packed hv_vmbus_channel_gpadl_teardown;
482
483 typedef struct {
484         hv_vmbus_channel_msg_header     header;
485         uint32_t                        gpadl;
486 } __packed hv_vmbus_channel_gpadl_torndown;
487
488 typedef struct {
489         hv_vmbus_channel_msg_header     header;
490         uint32_t                        child_rel_id;
491 } __packed hv_vmbus_channel_relid_released;
492
493 typedef struct {
494         hv_vmbus_channel_msg_header     header;
495         uint32_t                        vmbus_version_requested;
496         uint32_t                        padding2;
497         uint64_t                        interrupt_page;
498         uint64_t                        monitor_page_1;
499         uint64_t                        monitor_page_2;
500 } __packed hv_vmbus_channel_initiate_contact;
501
502 typedef struct {
503         hv_vmbus_channel_msg_header header;
504         hv_bool_uint8_t         version_supported;
505 } __packed hv_vmbus_channel_version_response;
506
507 typedef hv_vmbus_channel_msg_header hv_vmbus_channel_unload;
508
509 #define HW_MACADDR_LEN  6
510
511 /*
512  * Fixme:  Added to quiet "typeof" errors involving hv_vmbus.h when
513  * the including C file was compiled with "-std=c99".
514  */
515 #ifndef typeof
516 #define typeof __typeof
517 #endif
518
519 #ifndef NULL
520 #define NULL  (void *)0
521 #endif
522
523 typedef void *hv_vmbus_handle;
524
525 #ifndef CONTAINING_RECORD
526 #define CONTAINING_RECORD(address, type, field) ((type *)(      \
527                 (uint8_t *)(address) -                          \
528                 (uint8_t *)(&((type *)0)->field)))
529 #endif /* CONTAINING_RECORD */
530
531
532 #define container_of(ptr, type, member) ({                              \
533                 __typeof__( ((type *)0)->member ) *__mptr = (ptr);      \
534                 (type *)( (char *)__mptr - offsetof(type,member) );})
535
536 enum {
537         HV_VMBUS_IVAR_TYPE,
538         HV_VMBUS_IVAR_INSTANCE,
539         HV_VMBUS_IVAR_NODE,
540         HV_VMBUS_IVAR_DEVCTX
541 };
542
543 #define HV_VMBUS_ACCESSOR(var, ivar, type) \
544                 __BUS_ACCESSOR(vmbus, var, HV_VMBUS, ivar, type)
545
546 HV_VMBUS_ACCESSOR(type, TYPE,  const char *)
547 HV_VMBUS_ACCESSOR(devctx, DEVCTX,  struct hv_device *)
548
549
550 /*
551  * Common defines for Hyper-V ICs
552  */
553 #define HV_ICMSGTYPE_NEGOTIATE          0
554 #define HV_ICMSGTYPE_HEARTBEAT          1
555 #define HV_ICMSGTYPE_KVPEXCHANGE        2
556 #define HV_ICMSGTYPE_SHUTDOWN           3
557 #define HV_ICMSGTYPE_TIMESYNC           4
558 #define HV_ICMSGTYPE_VSS                5
559
560 #define HV_ICMSGHDRFLAG_TRANSACTION     1
561 #define HV_ICMSGHDRFLAG_REQUEST         2
562 #define HV_ICMSGHDRFLAG_RESPONSE        4
563
564 typedef struct hv_vmbus_pipe_hdr {
565         uint32_t flags;
566         uint32_t msgsize;
567 } __packed hv_vmbus_pipe_hdr;
568
569 typedef struct hv_vmbus_ic_version {
570         uint16_t major;
571         uint16_t minor;
572 } __packed hv_vmbus_ic_version;
573
574 typedef struct hv_vmbus_icmsg_hdr {
575         hv_vmbus_ic_version     icverframe;
576         uint16_t                icmsgtype;
577         hv_vmbus_ic_version     icvermsg;
578         uint16_t                icmsgsize;
579         uint32_t                status;
580         uint8_t                 ictransaction_id;
581         uint8_t                 icflags;
582         uint8_t                 reserved[2];
583 } __packed hv_vmbus_icmsg_hdr;
584
585 typedef struct hv_vmbus_icmsg_negotiate {
586         uint16_t                icframe_vercnt;
587         uint16_t                icmsg_vercnt;
588         uint32_t                reserved;
589         hv_vmbus_ic_version     icversion_data[1]; /* any size array */
590 } __packed hv_vmbus_icmsg_negotiate;
591
592 typedef struct hv_vmbus_shutdown_msg_data {
593         uint32_t                reason_code;
594         uint32_t                timeout_seconds;
595         uint32_t                flags;
596         uint8_t                 display_message[2048];
597 } __packed hv_vmbus_shutdown_msg_data;
598
599 typedef struct hv_vmbus_heartbeat_msg_data {
600         uint64_t                seq_num;
601         uint32_t                reserved[8];
602 } __packed hv_vmbus_heartbeat_msg_data;
603
604 typedef struct {
605         /*
606          * offset in bytes from the start of ring data below
607          */
608         volatile uint32_t       write_index;
609         /*
610          * offset in bytes from the start of ring data below
611          */
612         volatile uint32_t       read_index;
613         /*
614          * NOTE: The interrupt_mask field is used only for channels, but
615          * vmbus connection also uses this data structure
616          */
617         volatile uint32_t       interrupt_mask;
618         /* pad it to PAGE_SIZE so that data starts on a page */
619         uint8_t                 reserved[4084];
620
621         /*
622          * WARNING: Ring data starts here + ring_data_start_offset
623          *  !!! DO NOT place any fields below this !!!
624          */
625         uint8_t                 buffer[0];      /* doubles as interrupt mask */
626 } __packed hv_vmbus_ring_buffer;
627
628 typedef struct {
629         int             length;
630         int             offset;
631         uint64_t        pfn;
632 } __packed hv_vmbus_page_buffer;
633
634 typedef struct {
635         int             length;
636         int             offset;
637         uint64_t        pfn_array[HV_MAX_MULTIPAGE_BUFFER_COUNT];
638 } __packed hv_vmbus_multipage_buffer;
639
640 typedef struct {
641         hv_vmbus_ring_buffer*   ring_buffer;
642         uint32_t                ring_size;      /* Include the shared header */
643         struct mtx              ring_lock;
644         uint32_t                ring_data_size; /* ring_size */
645         uint32_t                ring_data_start_offset;
646 } hv_vmbus_ring_buffer_info;
647
648 typedef void (*hv_vmbus_pfn_channel_callback)(void *context);
649
650 typedef enum {
651         HV_CHANNEL_OFFER_STATE,
652         HV_CHANNEL_OPENING_STATE,
653         HV_CHANNEL_OPEN_STATE,
654         HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE,
655 } hv_vmbus_channel_state;
656
657 typedef struct hv_vmbus_channel {
658         TAILQ_ENTRY(hv_vmbus_channel)   list_entry;
659         struct hv_device*               device;
660         hv_vmbus_channel_state          state;
661         hv_vmbus_channel_offer_channel  offer_msg;
662         /*
663          * These are based on the offer_msg.monitor_id.
664          * Save it here for easy access.
665          */
666         uint8_t                         monitor_group;
667         uint8_t                         monitor_bit;
668
669         uint32_t                        ring_buffer_gpadl_handle;
670         /*
671          * Allocated memory for ring buffer
672          */
673         void*                           ring_buffer_pages;
674         unsigned long                   ring_buffer_size;
675         uint32_t                        ring_buffer_page_count;
676         /*
677          * send to parent
678          */
679         hv_vmbus_ring_buffer_info       outbound;
680         /*
681          * receive from parent
682          */
683         hv_vmbus_ring_buffer_info       inbound;
684
685         struct mtx                      inbound_lock;
686         hv_vmbus_handle                 control_work_queue;
687
688         hv_vmbus_pfn_channel_callback   on_channel_callback;
689         void*                           channel_callback_context;
690
691 } hv_vmbus_channel;
692
693 typedef struct hv_device {
694         hv_guid             class_id;
695         hv_guid             device_id;
696         device_t            device;
697         hv_vmbus_channel*   channel;
698 } hv_device;
699
700
701
702 int             hv_vmbus_channel_recv_packet(
703                                 hv_vmbus_channel*       channel,
704                                 void*                   buffer,
705                                 uint32_t                buffer_len,
706                                 uint32_t*               buffer_actual_len,
707                                 uint64_t*               request_id);
708
709 int             hv_vmbus_channel_recv_packet_raw(
710                                 hv_vmbus_channel*       channel,
711                                 void*                   buffer,
712                                 uint32_t                buffer_len,
713                                 uint32_t*               buffer_actual_len,
714                                 uint64_t*               request_id);
715
716 int             hv_vmbus_channel_open(
717                                 hv_vmbus_channel*       channel,
718                                 uint32_t                send_ring_buffer_size,
719                                 uint32_t                recv_ring_buffer_size,
720                                 void*                   user_data,
721                                 uint32_t                user_data_len,
722                                 hv_vmbus_pfn_channel_callback
723                                                         pfn_on_channel_callback,
724                                 void*                   context);
725
726 void            hv_vmbus_channel_close(hv_vmbus_channel *channel);
727
728 int             hv_vmbus_channel_send_packet(
729                                 hv_vmbus_channel*       channel,
730                                 void*                   buffer,
731                                 uint32_t                buffer_len,
732                                 uint64_t                request_id,
733                                 hv_vmbus_packet_type    type,
734                                 uint32_t                flags);
735
736 int             hv_vmbus_channel_send_packet_pagebuffer(
737                                 hv_vmbus_channel*       channel,
738                                 hv_vmbus_page_buffer    page_buffers[],
739                                 uint32_t                page_count,
740                                 void*                   buffer,
741                                 uint32_t                buffer_len,
742                                 uint64_t                request_id);
743
744 int             hv_vmbus_channel_send_packet_multipagebuffer(
745                                 hv_vmbus_channel*           channel,
746                                 hv_vmbus_multipage_buffer*  multi_page_buffer,
747                                 void*                       buffer,
748                                 uint32_t                    buffer_len,
749                                 uint64_t                    request_id);
750
751 int             hv_vmbus_channel_establish_gpadl(
752                                 hv_vmbus_channel*       channel,
753                                 /* must be phys and virt contiguous */
754                                 void*                   contig_buffer,
755                                 /*  page-size multiple  */
756                                 uint32_t                size,
757                                 uint32_t*               gpadl_handle);
758
759 int             hv_vmbus_channel_teardown_gpdal(
760                                 hv_vmbus_channel*       channel,
761                                 uint32_t                gpadl_handle);
762
763 /*
764  * Work abstraction defines
765  */
766 typedef struct hv_work_queue {
767         struct taskqueue*       queue;
768         struct proc*            proc;
769         struct sema*            work_sema;
770 } hv_work_queue;
771
772 typedef struct hv_work_item {
773         struct task     work;
774         void            (*callback)(void *);
775         void*           context;
776         hv_work_queue*  wq;
777 } hv_work_item;
778
779 struct hv_work_queue*   hv_work_queue_create(char* name);
780
781 void                    hv_work_queue_close(struct hv_work_queue* wq);
782
783 int                     hv_queue_work_item(
784                                 hv_work_queue*  wq,
785                                 void            (*callback)(void *),
786                                 void*           context);
787 /**
788  * @brief Get physical address from virtual
789  */
790 static inline unsigned long
791 hv_get_phys_addr(void *virt)
792 {
793         unsigned long ret;
794         ret = (vtophys(virt) | ((vm_offset_t) virt & PAGE_MASK));
795         return (ret);
796 }
797
798 #endif  /* __HYPERV_H__ */
799