hyperv.h revision 307022
1/*- 2 * Copyright (c) 2009-2012,2016 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: stable/10/sys/dev/hyperv/include/hyperv.h 307022 2016-10-11 07:30:59Z sephe $ 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/smp.h> 50#include <sys/mutex.h> 51#include <sys/bus.h> 52#include <sys/sysctl.h> 53#include <vm/vm.h> 54#include <vm/vm_param.h> 55#include <vm/pmap.h> 56 57#include <amd64/include/xen/synch_bitops.h> 58#include <amd64/include/atomic.h> 59#include <dev/hyperv/include/hyperv_busdma.h> 60 61typedef uint8_t hv_bool_uint8_t; 62 63#define HV_S_OK 0x00000000 64#define HV_E_FAIL 0x80004005 65#define HV_ERROR_NOT_SUPPORTED 0x80070032 66#define HV_ERROR_MACHINE_LOCKED 0x800704F7 67 68/* 69 * VMBUS version is 32 bit, upper 16 bit for major_number and lower 70 * 16 bit for minor_number. 71 * 72 * 0.13 -- Windows Server 2008 73 * 1.1 -- Windows 7 74 * 2.4 -- Windows 8 75 * 3.0 -- Windows 8.1 76 */ 77#define VMBUS_VERSION_WS2008 ((0 << 16) | (13)) 78#define VMBUS_VERSION_WIN7 ((1 << 16) | (1)) 79#define VMBUS_VERSION_WIN8 ((2 << 16) | (4)) 80#define VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) 81 82#define VMBUS_VERSION_MAJOR(ver) (((uint32_t)(ver)) >> 16) 83#define VMBUS_VERSION_MINOR(ver) (((uint32_t)(ver)) & 0xffff) 84 85/* 86 * Make maximum size of pipe payload of 16K 87 */ 88 89#define HV_MAX_PIPE_DATA_PAYLOAD (sizeof(BYTE) * 16384) 90 91/* 92 * Define pipe_mode values 93 */ 94 95#define HV_VMBUS_PIPE_TYPE_BYTE 0x00000000 96#define HV_VMBUS_PIPE_TYPE_MESSAGE 0x00000004 97 98/* 99 * The size of the user defined data buffer for non-pipe offers 100 */ 101 102#define HV_MAX_USER_DEFINED_BYTES 120 103 104/* 105 * The size of the user defined data buffer for pipe offers 106 */ 107 108#define HV_MAX_PIPE_USER_DEFINED_BYTES 116 109 110 111#define HV_MAX_PAGE_BUFFER_COUNT 32 112#define HV_MAX_MULTIPAGE_BUFFER_COUNT 32 113 114#define HV_ALIGN_UP(value, align) \ 115 (((value) & (align-1)) ? \ 116 (((value) + (align-1)) & ~(align-1) ) : (value)) 117 118#define HV_ALIGN_DOWN(value, align) ( (value) & ~(align-1) ) 119 120#define HV_NUM_PAGES_SPANNED(addr, len) \ 121 ((HV_ALIGN_UP(addr+len, PAGE_SIZE) - \ 122 HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT ) 123 124typedef struct hv_guid { 125 uint8_t data[16]; 126} __packed hv_guid; 127 128#define HYPERV_GUID_STRLEN 40 129 130int hyperv_guid2str(const struct hv_guid *, char *, size_t); 131 132#define HV_NIC_GUID \ 133 .data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, \ 134 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E} 135 136#define HV_IDE_GUID \ 137 .data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \ 138 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5} 139 140#define HV_SCSI_GUID \ 141 .data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \ 142 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f} 143 144/* 145 * At the center of the Channel Management library is 146 * the Channel Offer. This struct contains the 147 * fundamental information about an offer. 148 */ 149 150typedef struct hv_vmbus_channel_offer { 151 hv_guid interface_type; 152 hv_guid interface_instance; 153 uint64_t interrupt_latency_in_100ns_units; 154 uint32_t interface_revision; 155 uint32_t server_context_area_size; /* in bytes */ 156 uint16_t channel_flags; 157 uint16_t mmio_megabytes; /* in bytes * 1024 * 1024 */ 158 union 159 { 160 /* 161 * Non-pipes: The user has HV_MAX_USER_DEFINED_BYTES bytes. 162 */ 163 struct { 164 uint8_t user_defined[HV_MAX_USER_DEFINED_BYTES]; 165 } __packed standard; 166 167 /* 168 * Pipes: The following structure is an integrated pipe protocol, which 169 * is implemented on top of standard user-defined data. pipe 170 * clients have HV_MAX_PIPE_USER_DEFINED_BYTES left for their 171 * own use. 172 */ 173 struct { 174 uint32_t pipe_mode; 175 uint8_t user_defined[HV_MAX_PIPE_USER_DEFINED_BYTES]; 176 } __packed pipe; 177 } u; 178 179 /* 180 * Sub_channel_index, newly added in Win8. 181 */ 182 uint16_t sub_channel_index; 183 uint16_t padding; 184 185} __packed hv_vmbus_channel_offer; 186 187typedef struct { 188 uint16_t type; 189 uint16_t data_offset8; 190 uint16_t length8; 191 uint16_t flags; 192 uint64_t transaction_id; 193} __packed hv_vm_packet_descriptor; 194 195typedef uint32_t hv_previous_packet_offset; 196 197typedef struct { 198 hv_previous_packet_offset previous_packet_start_offset; 199 hv_vm_packet_descriptor descriptor; 200} __packed hv_vm_packet_header; 201 202typedef struct { 203 uint32_t byte_count; 204 uint32_t byte_offset; 205} __packed hv_vm_transfer_page; 206 207typedef struct { 208 hv_vm_packet_descriptor d; 209 uint16_t transfer_page_set_id; 210 hv_bool_uint8_t sender_owns_set; 211 uint8_t reserved; 212 uint32_t range_count; 213 hv_vm_transfer_page ranges[1]; 214} __packed hv_vm_transfer_page_packet_header; 215 216typedef struct { 217 hv_vm_packet_descriptor d; 218 uint32_t gpadl; 219 uint32_t reserved; 220} __packed hv_vm_gpadl_packet_header; 221 222typedef struct { 223 hv_vm_packet_descriptor d; 224 uint32_t gpadl; 225 uint16_t transfer_page_set_id; 226 uint16_t reserved; 227} __packed hv_vm_add_remove_transfer_page_set; 228 229/* 230 * This structure defines a range in guest 231 * physical space that can be made 232 * to look virtually contiguous. 233 */ 234 235typedef struct { 236 uint32_t byte_count; 237 uint32_t byte_offset; 238 uint64_t pfn_array[0]; 239} __packed hv_gpa_range; 240 241/* 242 * This is the format for an Establish Gpadl packet, which contains a handle 243 * by which this GPADL will be known and a set of GPA ranges associated with 244 * it. This can be converted to a MDL by the guest OS. If there are multiple 245 * GPA ranges, then the resulting MDL will be "chained," representing multiple 246 * VA ranges. 247 */ 248 249typedef struct { 250 hv_vm_packet_descriptor d; 251 uint32_t gpadl; 252 uint32_t range_count; 253 hv_gpa_range range[1]; 254} __packed hv_vm_establish_gpadl; 255 256/* 257 * This is the format for a Teardown Gpadl packet, which indicates that the 258 * GPADL handle in the Establish Gpadl packet will never be referenced again. 259 */ 260 261typedef struct { 262 hv_vm_packet_descriptor d; 263 uint32_t gpadl; 264 /* for alignment to a 8-byte boundary */ 265 uint32_t reserved; 266} __packed hv_vm_teardown_gpadl; 267 268/* 269 * This is the format for a GPA-Direct packet, which contains a set of GPA 270 * ranges, in addition to commands and/or data. 271 */ 272 273typedef struct { 274 hv_vm_packet_descriptor d; 275 uint32_t reserved; 276 uint32_t range_count; 277 hv_gpa_range range[1]; 278} __packed hv_vm_data_gpa_direct; 279 280/* 281 * This is the format for a Additional data Packet. 282 */ 283typedef struct { 284 hv_vm_packet_descriptor d; 285 uint64_t total_bytes; 286 uint32_t byte_offset; 287 uint32_t byte_count; 288 uint8_t data[1]; 289} __packed hv_vm_additional_data; 290 291typedef union { 292 hv_vm_packet_descriptor simple_header; 293 hv_vm_transfer_page_packet_header transfer_page_header; 294 hv_vm_gpadl_packet_header gpadl_header; 295 hv_vm_add_remove_transfer_page_set add_remove_transfer_page_header; 296 hv_vm_establish_gpadl establish_gpadl_header; 297 hv_vm_teardown_gpadl teardown_gpadl_header; 298 hv_vm_data_gpa_direct data_gpa_direct_header; 299} __packed hv_vm_packet_largest_possible_header; 300 301typedef enum { 302 HV_VMBUS_PACKET_TYPE_INVALID = 0x0, 303 HV_VMBUS_PACKET_TYPES_SYNCH = 0x1, 304 HV_VMBUS_PACKET_TYPE_ADD_TRANSFER_PAGE_SET = 0x2, 305 HV_VMBUS_PACKET_TYPE_REMOVE_TRANSFER_PAGE_SET = 0x3, 306 HV_VMBUS_PACKET_TYPE_ESTABLISH_GPADL = 0x4, 307 HV_VMBUS_PACKET_TYPE_TEAR_DOWN_GPADL = 0x5, 308 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND = 0x6, 309 HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES = 0x7, 310 HV_VMBUS_PACKET_TYPE_DATA_USING_GPADL = 0x8, 311 HV_VMBUS_PACKET_TYPE_DATA_USING_GPA_DIRECT = 0x9, 312 HV_VMBUS_PACKET_TYPE_CANCEL_REQUEST = 0xa, 313 HV_VMBUS_PACKET_TYPE_COMPLETION = 0xb, 314 HV_VMBUS_PACKET_TYPE_DATA_USING_ADDITIONAL_PACKETS = 0xc, 315 HV_VMBUS_PACKET_TYPE_ADDITIONAL_DATA = 0xd 316} hv_vmbus_packet_type; 317 318#define HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1 319 320/* 321 * Version 1 messages 322 */ 323typedef enum { 324 HV_CHANNEL_MESSAGE_INVALID = 0, 325 HV_CHANNEL_MESSAGE_OFFER_CHANNEL = 1, 326 HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER = 2, 327 HV_CHANNEL_MESSAGE_REQUEST_OFFERS = 3, 328 HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED = 4, 329 HV_CHANNEL_MESSAGE_OPEN_CHANNEL = 5, 330 HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT = 6, 331 HV_CHANNEL_MESSAGE_CLOSE_CHANNEL = 7, 332 HV_CHANNEL_MESSAGEL_GPADL_HEADER = 8, 333 HV_CHANNEL_MESSAGE_GPADL_BODY = 9, 334 HV_CHANNEL_MESSAGE_GPADL_CREATED = 10, 335 HV_CHANNEL_MESSAGE_GPADL_TEARDOWN = 11, 336 HV_CHANNEL_MESSAGE_GPADL_TORNDOWN = 12, 337 HV_CHANNEL_MESSAGE_REL_ID_RELEASED = 13, 338 HV_CHANNEL_MESSAGE_INITIATED_CONTACT = 14, 339 HV_CHANNEL_MESSAGE_VERSION_RESPONSE = 15, 340 HV_CHANNEL_MESSAGE_UNLOAD = 16, 341 HV_CHANNEL_MESSAGE_COUNT 342} hv_vmbus_channel_msg_type; 343 344typedef struct { 345 hv_vmbus_channel_msg_type message_type; 346 uint32_t padding; 347} __packed hv_vmbus_channel_msg_header; 348 349/* 350 * Query VMBus Version parameters 351 */ 352typedef struct { 353 hv_vmbus_channel_msg_header header; 354 uint32_t version; 355} __packed hv_vmbus_channel_query_vmbus_version; 356 357/* 358 * Channel Offer parameters 359 */ 360typedef struct { 361 hv_vmbus_channel_msg_header header; 362 hv_vmbus_channel_offer offer; 363 uint32_t child_rel_id; 364 uint8_t monitor_id; 365 /* 366 * This field has been split into a bit field on Win7 367 * and higher. 368 */ 369 uint8_t monitor_allocated:1; 370 uint8_t reserved:7; 371 /* 372 * Following fields were added in win7 and higher. 373 * Make sure to check the version before accessing these fields. 374 * 375 * If "is_dedicated_interrupt" is set, we must not set the 376 * associated bit in the channel bitmap while sending the 377 * interrupt to the host. 378 * 379 * connection_id is used in signaling the host. 380 */ 381 uint16_t is_dedicated_interrupt:1; 382 uint16_t reserved1:15; 383 uint32_t connection_id; 384} __packed hv_vmbus_channel_offer_channel; 385 386/* 387 * Rescind Offer parameters 388 */ 389typedef struct 390{ 391 hv_vmbus_channel_msg_header header; 392 uint32_t child_rel_id; 393} __packed hv_vmbus_channel_rescind_offer; 394 395typedef struct { 396 hv_vmbus_channel_msg_header header; 397 uint32_t child_rel_id; 398} __packed hv_vmbus_channel_relid_released; 399 400#define HW_MACADDR_LEN 6 401 402/* 403 * Common defines for Hyper-V ICs 404 */ 405#define HV_ICMSGTYPE_NEGOTIATE 0 406#define HV_ICMSGTYPE_HEARTBEAT 1 407#define HV_ICMSGTYPE_KVPEXCHANGE 2 408#define HV_ICMSGTYPE_SHUTDOWN 3 409#define HV_ICMSGTYPE_TIMESYNC 4 410#define HV_ICMSGTYPE_VSS 5 411 412#define HV_ICMSGHDRFLAG_TRANSACTION 1 413#define HV_ICMSGHDRFLAG_REQUEST 2 414#define HV_ICMSGHDRFLAG_RESPONSE 4 415 416typedef struct hv_vmbus_pipe_hdr { 417 uint32_t flags; 418 uint32_t msgsize; 419} __packed hv_vmbus_pipe_hdr; 420 421typedef struct hv_vmbus_ic_version { 422 uint16_t major; 423 uint16_t minor; 424} __packed hv_vmbus_ic_version; 425 426typedef struct hv_vmbus_icmsg_hdr { 427 hv_vmbus_ic_version icverframe; 428 uint16_t icmsgtype; 429 hv_vmbus_ic_version icvermsg; 430 uint16_t icmsgsize; 431 uint32_t status; 432 uint8_t ictransaction_id; 433 uint8_t icflags; 434 uint8_t reserved[2]; 435} __packed hv_vmbus_icmsg_hdr; 436 437typedef struct hv_vmbus_icmsg_negotiate { 438 uint16_t icframe_vercnt; 439 uint16_t icmsg_vercnt; 440 uint32_t reserved; 441 hv_vmbus_ic_version icversion_data[1]; /* any size array */ 442} __packed hv_vmbus_icmsg_negotiate; 443 444typedef struct hv_vmbus_shutdown_msg_data { 445 uint32_t reason_code; 446 uint32_t timeout_seconds; 447 uint32_t flags; 448 uint8_t display_message[2048]; 449} __packed hv_vmbus_shutdown_msg_data; 450 451typedef struct hv_vmbus_heartbeat_msg_data { 452 uint64_t seq_num; 453 uint32_t reserved[8]; 454} __packed hv_vmbus_heartbeat_msg_data; 455 456typedef struct { 457 /* 458 * offset in bytes from the start of ring data below 459 */ 460 volatile uint32_t write_index; 461 /* 462 * offset in bytes from the start of ring data below 463 */ 464 volatile uint32_t read_index; 465 /* 466 * NOTE: The interrupt_mask field is used only for channels, but 467 * vmbus connection also uses this data structure 468 */ 469 volatile uint32_t interrupt_mask; 470 /* pad it to PAGE_SIZE so that data starts on a page */ 471 uint8_t reserved[4084]; 472 473 /* 474 * WARNING: Ring data starts here + ring_data_start_offset 475 * !!! DO NOT place any fields below this !!! 476 */ 477 uint8_t buffer[0]; /* doubles as interrupt mask */ 478} __packed hv_vmbus_ring_buffer; 479 480typedef struct { 481 int length; 482 int offset; 483 uint64_t pfn; 484} __packed hv_vmbus_page_buffer; 485 486typedef struct { 487 int length; 488 int offset; 489 uint64_t pfn_array[HV_MAX_MULTIPAGE_BUFFER_COUNT]; 490} __packed hv_vmbus_multipage_buffer; 491 492typedef struct { 493 hv_vmbus_ring_buffer* ring_buffer; 494 uint32_t ring_size; /* Include the shared header */ 495 struct mtx ring_lock; 496 uint32_t ring_data_size; /* ring_size */ 497 uint32_t ring_data_start_offset; 498} hv_vmbus_ring_buffer_info; 499 500typedef void (*hv_vmbus_pfn_channel_callback)(void *context); 501 502typedef enum { 503 HV_CHANNEL_OFFER_STATE, 504 HV_CHANNEL_OPENING_STATE, 505 HV_CHANNEL_OPEN_STATE, 506 HV_CHANNEL_OPENED_STATE, 507 HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE, 508} hv_vmbus_channel_state; 509 510/* 511 * Connection identifier type 512 */ 513typedef union { 514 uint32_t as_uint32_t; 515 struct { 516 uint32_t id:24; 517 uint32_t reserved:8; 518 } u; 519 520} __packed hv_vmbus_connection_id; 521 522typedef struct hv_vmbus_channel { 523 device_t ch_dev; 524 struct vmbus_softc *vmbus_sc; 525 hv_vmbus_channel_state state; 526 uint32_t ch_flags; /* VMBUS_CHAN_FLAG_ */ 527 uint32_t ch_id; /* channel id */ 528 /* 529 * These are based on the offer_msg.monitor_id. 530 * Save it here for easy access. 531 */ 532 uint8_t monitor_group; 533 uint8_t monitor_bit; 534 535 uint32_t ring_buffer_gpadl_handle; 536 /* 537 * Allocated memory for ring buffer 538 */ 539 void* ring_buffer_pages; 540 unsigned long ring_buffer_size; 541 uint32_t ring_buffer_page_count; 542 /* 543 * send to parent 544 */ 545 hv_vmbus_ring_buffer_info outbound; 546 /* 547 * receive from parent 548 */ 549 hv_vmbus_ring_buffer_info inbound; 550 551 struct taskqueue * rxq; 552 struct task channel_task; 553 hv_vmbus_pfn_channel_callback on_channel_callback; 554 void* channel_callback_context; 555 556 /* 557 * If batched_reading is set to "true", mask the interrupt 558 * and read until the channel is empty. 559 * If batched_reading is set to "false", the channel is not 560 * going to perform batched reading. 561 * 562 * Batched reading is enabled by default; specific 563 * drivers that don't want this behavior can turn it off. 564 */ 565 boolean_t batched_reading; 566 567 boolean_t is_dedicated_interrupt; 568 569 struct hypercall_sigevt_in *ch_sigevt; 570 struct hyperv_dma ch_sigevt_dma; 571 572 /* 573 * From Win8, this field specifies the target virtual process 574 * on which to deliver the interupt from the host to guest. 575 * Before Win8, all channel interrupts would only be 576 * delivered on cpu 0. Setting this value to 0 would preserve 577 * the earlier behavior. 578 */ 579 uint32_t target_vcpu; 580 /* The corresponding CPUID in the guest */ 581 uint32_t target_cpu; 582 583 /* 584 * Support for multi-channels. 585 * The initial offer is considered the primary channel and this 586 * offer message will indicate if the host supports multi-channels. 587 * The guest is free to ask for multi-channels to be offerred and can 588 * open these multi-channels as a normal "primary" channel. However, 589 * all multi-channels will have the same type and instance guids as the 590 * primary channel. Requests sent on a given channel will result in a 591 * response on the same channel. 592 */ 593 594 struct mtx sc_lock; 595 596 /* 597 * Link list of all the multi-channels if this is a primary channel 598 */ 599 TAILQ_HEAD(, hv_vmbus_channel) sc_list_anchor; 600 TAILQ_ENTRY(hv_vmbus_channel) sc_list_entry; 601 int subchan_cnt; 602 603 /* 604 * The primary channel this sub-channle belongs to. 605 * This will be NULL for the primary channel. 606 */ 607 struct hv_vmbus_channel *primary_channel; 608 609 /* 610 * Driver private data 611 */ 612 void *hv_chan_priv1; 613 void *hv_chan_priv2; 614 void *hv_chan_priv3; 615 616 struct task ch_detach_task; 617 TAILQ_ENTRY(hv_vmbus_channel) ch_link; 618 uint32_t ch_subidx; /* subchan index */ 619 620 struct hv_guid ch_guid_type; 621 struct hv_guid ch_guid_inst; 622 623 struct sysctl_ctx_list ch_sysctl_ctx; 624} hv_vmbus_channel; 625 626#define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL) 627 628#define VMBUS_CHAN_FLAG_HASMNF 0x0001 629 630static inline void 631hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t state) 632{ 633 channel->batched_reading = state; 634} 635 636int hv_vmbus_channel_recv_packet( 637 hv_vmbus_channel* channel, 638 void* buffer, 639 uint32_t buffer_len, 640 uint32_t* buffer_actual_len, 641 uint64_t* request_id); 642 643int hv_vmbus_channel_recv_packet_raw( 644 hv_vmbus_channel* channel, 645 void* buffer, 646 uint32_t buffer_len, 647 uint32_t* buffer_actual_len, 648 uint64_t* request_id); 649 650int hv_vmbus_channel_open( 651 hv_vmbus_channel* channel, 652 uint32_t send_ring_buffer_size, 653 uint32_t recv_ring_buffer_size, 654 void* user_data, 655 uint32_t user_data_len, 656 hv_vmbus_pfn_channel_callback 657 pfn_on_channel_callback, 658 void* context); 659 660void hv_vmbus_channel_close(hv_vmbus_channel *channel); 661 662int hv_vmbus_channel_send_packet( 663 hv_vmbus_channel* channel, 664 void* buffer, 665 uint32_t buffer_len, 666 uint64_t request_id, 667 hv_vmbus_packet_type type, 668 uint32_t flags); 669 670int hv_vmbus_channel_send_packet_pagebuffer( 671 hv_vmbus_channel* channel, 672 hv_vmbus_page_buffer page_buffers[], 673 uint32_t page_count, 674 void* buffer, 675 uint32_t buffer_len, 676 uint64_t request_id); 677 678int hv_vmbus_channel_send_packet_multipagebuffer( 679 hv_vmbus_channel* channel, 680 hv_vmbus_multipage_buffer* multi_page_buffer, 681 void* buffer, 682 uint32_t buffer_len, 683 uint64_t request_id); 684 685int hv_vmbus_channel_establish_gpadl( 686 hv_vmbus_channel* channel, 687 /* must be phys and virt contiguous */ 688 void* contig_buffer, 689 /* page-size multiple */ 690 uint32_t size, 691 uint32_t* gpadl_handle); 692 693int hv_vmbus_channel_teardown_gpdal( 694 hv_vmbus_channel* channel, 695 uint32_t gpadl_handle); 696 697struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary); 698 699void vmbus_channel_cpu_set(struct hv_vmbus_channel *chan, int cpu); 700void vmbus_channel_cpu_rr(struct hv_vmbus_channel *chan); 701struct hv_vmbus_channel ** 702 vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt); 703void vmbus_rel_subchan(struct hv_vmbus_channel **subchan, int subchan_cnt); 704void vmbus_drain_subchan(struct hv_vmbus_channel *pri_chan); 705 706/** 707 * @brief Get physical address from virtual 708 */ 709static inline unsigned long 710hv_get_phys_addr(void *virt) 711{ 712 unsigned long ret; 713 ret = (vtophys(virt) | ((vm_offset_t) virt & PAGE_MASK)); 714 return (ret); 715} 716 717static __inline struct hv_vmbus_channel * 718vmbus_get_channel(device_t dev) 719{ 720 return device_get_ivars(dev); 721} 722 723#endif /* __HYPERV_H__ */ 724