diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/Kconfig | 2 | ||||
-rw-r--r-- | drivers/Makefile | 2 | ||||
-rw-r--r-- | drivers/hv/Kconfig | 14 | ||||
-rw-r--r-- | drivers/hv/Makefile | 7 | ||||
-rw-r--r-- | drivers/hv/channel.c (renamed from drivers/staging/hv/channel.c) | 2 | ||||
-rw-r--r-- | drivers/hv/channel_mgmt.c (renamed from drivers/staging/hv/channel_mgmt.c) | 2 | ||||
-rw-r--r-- | drivers/hv/connection.c (renamed from drivers/staging/hv/connection.c) | 2 | ||||
-rw-r--r-- | drivers/hv/hv.c (renamed from drivers/staging/hv/hv.c) | 2 | ||||
-rw-r--r-- | drivers/hv/hv_kvp.c (renamed from drivers/staging/hv/hv_kvp.c) | 2 | ||||
-rw-r--r-- | drivers/hv/hv_kvp.h (renamed from drivers/staging/hv/hv_kvp.h) | 0 | ||||
-rw-r--r-- | drivers/hv/hv_util.c (renamed from drivers/staging/hv/hv_util.c) | 2 | ||||
-rw-r--r-- | drivers/hv/hyperv_vmbus.h (renamed from drivers/staging/hv/hyperv_vmbus.h) | 3 | ||||
-rw-r--r-- | drivers/hv/ring_buffer.c (renamed from drivers/staging/hv/ring_buffer.c) | 2 | ||||
-rw-r--r-- | drivers/hv/vmbus_drv.c (renamed from drivers/staging/hv/vmbus_drv.c) | 2 | ||||
-rw-r--r-- | drivers/staging/hv/Kconfig | 28 | ||||
-rw-r--r-- | drivers/staging/hv/Makefile | 7 | ||||
-rw-r--r-- | drivers/staging/hv/hv_mouse.c | 3 | ||||
-rw-r--r-- | drivers/staging/hv/hyperv.h | 969 | ||||
-rw-r--r-- | drivers/staging/hv/hyperv_net.h | 2 | ||||
-rw-r--r-- | drivers/staging/hv/storvsc_drv.c | 2 | ||||
-rw-r--r-- | drivers/staging/hv/tools/hv_kvp_daemon.c | 500 |
21 files changed, 41 insertions, 1514 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index 95b9e7eefadc..ce3c35f4041c 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -130,4 +130,6 @@ source "drivers/iommu/Kconfig" source "drivers/virt/Kconfig" +source "drivers/hv/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 7fa433a7030c..ef693cfb4813 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -127,3 +127,5 @@ obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ # Virtualization drivers obj-$(CONFIG_VIRT_DRIVERS) += virt/ +obj-$(CONFIG_HYPERV) += hv/ + diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig new file mode 100644 index 000000000000..9fa09ac000ad --- /dev/null +++ b/drivers/hv/Kconfig @@ -0,0 +1,14 @@ +config HYPERV + tristate "Microsoft Hyper-V client drivers" + depends on X86 && ACPI && PCI + help + Select this option to run Linux as a Hyper-V client operating + system. + +config HYPERV_UTILS + tristate "Microsoft Hyper-V Utilities driver" + depends on HYPERV && CONNECTOR && NLS + help + Select this option to enable the Hyper-V Utilities. + + diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile new file mode 100644 index 000000000000..a23938b991c9 --- /dev/null +++ b/drivers/hv/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_HYPERV) += hv_vmbus.o +obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o + +hv_vmbus-y := vmbus_drv.o \ + hv.o connection.o channel.o \ + channel_mgmt.o ring_buffer.o +hv_utils-y := hv_util.o hv_kvp.o diff --git a/drivers/staging/hv/channel.c b/drivers/hv/channel.c index b6f3d38a6dbb..406537420fff 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/hv/channel.c @@ -26,8 +26,8 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/module.h> +#include <linux/hyperv.h> -#include "hyperv.h" #include "hyperv_vmbus.h" #define NUM_PAGES_SPANNED(addr, len) \ diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 9f007522a9d5..41bf287baa1c 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -28,8 +28,8 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/completion.h> +#include <linux/hyperv.h> -#include "hyperv.h" #include "hyperv_vmbus.h" struct vmbus_channel_message_table_entry { diff --git a/drivers/staging/hv/connection.c b/drivers/hv/connection.c index 649b91bcd8c1..5f438b650068 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/hv/connection.c @@ -29,8 +29,8 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/vmalloc.h> +#include <linux/hyperv.h> -#include "hyperv.h" #include "hyperv_vmbus.h" diff --git a/drivers/staging/hv/hv.c b/drivers/hv/hv.c index 06f1e158c27c..931b7b030784 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/hv/hv.c @@ -25,8 +25,8 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/vmalloc.h> +#include <linux/hyperv.h> -#include "hyperv.h" #include "hyperv_vmbus.h" /* The one and only */ diff --git a/drivers/staging/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 1e9515cc6094..69c4c985daeb 100644 --- a/drivers/staging/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -26,8 +26,8 @@ #include <linux/nls.h> #include <linux/connector.h> #include <linux/workqueue.h> +#include <linux/hyperv.h> -#include "hyperv.h" #include "hv_kvp.h" diff --git a/drivers/staging/hv/hv_kvp.h b/drivers/hv/hv_kvp.h index 9b765d7df838..9b765d7df838 100644 --- a/drivers/staging/hv/hv_kvp.h +++ b/drivers/hv/hv_kvp.h diff --git a/drivers/staging/hv/hv_util.c b/drivers/hv/hv_util.c index faa66074cc21..e0e3a6d0244d 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/hv/hv_util.c @@ -26,8 +26,8 @@ #include <linux/slab.h> #include <linux/sysctl.h> #include <linux/reboot.h> +#include <linux/hyperv.h> -#include "hyperv.h" #include "hv_kvp.h" diff --git a/drivers/staging/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 3d2d836c3cc8..8261cb64931b 100644 --- a/drivers/staging/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -28,8 +28,7 @@ #include <linux/list.h> #include <asm/sync_bitops.h> #include <linux/atomic.h> - -#include "hyperv.h" +#include <linux/hyperv.h> /* * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 70e2e66fec71..f594ed09d7e0 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -25,8 +25,8 @@ #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/hyperv.h> -#include "hyperv.h" #include "hyperv_vmbus.h" diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index d2562afcce4c..b0d08f980de1 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -32,8 +32,8 @@ #include <linux/acpi.h> #include <acpi/acpi_bus.h> #include <linux/completion.h> +#include <linux/hyperv.h> -#include "hyperv.h" #include "hyperv_vmbus.h" diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig index 815f8c2f7cdc..072185ebe95b 100644 --- a/drivers/staging/hv/Kconfig +++ b/drivers/staging/hv/Kconfig @@ -1,39 +1,17 @@ -config HYPERV - tristate "Microsoft Hyper-V client drivers" - depends on X86 && ACPI && PCI - default n - help - Select this option to run Linux as a Hyper-V client operating - system. - -if HYPERV - config HYPERV_STORAGE tristate "Microsoft Hyper-V virtual storage driver" - depends on SCSI - default HYPERV + depends on HYPERV && SCSI help Select this option to enable the Hyper-V virtual storage driver. config HYPERV_NET tristate "Microsoft Hyper-V virtual network driver" - depends on NET - default HYPERV + depends on HYPERV && NET help Select this option to enable the Hyper-V virtual network driver. -config HYPERV_UTILS - tristate "Microsoft Hyper-V Utilities driver" - depends on CONNECTOR && NLS - default HYPERV - help - Select this option to enable the Hyper-V Utilities. - config HYPERV_MOUSE tristate "Microsoft Hyper-V mouse driver" - depends on HID - default HYPERV + depends on HYPERV && HID help Select this option to enable the Hyper-V mouse driver. - -endif diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index bd176b1f231e..e071c12c8f69 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -1,12 +1,7 @@ -obj-$(CONFIG_HYPERV) += hv_vmbus.o hv_timesource.o +obj-$(CONFIG_HYPERV) += hv_timesource.o obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o -obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o obj-$(CONFIG_HYPERV_MOUSE) += hv_mouse.o -hv_vmbus-y := vmbus_drv.o \ - hv.o connection.o channel.o \ - channel_mgmt.o ring_buffer.o hv_storvsc-y := storvsc_drv.o hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o -hv_utils-y := hv_util.o hv_kvp.o diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index edbb4797db75..c354ade76ef5 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -22,8 +22,7 @@ #include <linux/input.h> #include <linux/hid.h> #include <linux/hiddev.h> - -#include "hyperv.h" +#include <linux/hyperv.h> struct hv_input_dev_info { diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h deleted file mode 100644 index edaa9e2f58ec..000000000000 --- a/drivers/staging/hv/hyperv.h +++ /dev/null @@ -1,969 +0,0 @@ -/* - * - * Copyright (c) 2011, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang <haiyangz@microsoft.com> - * Hank Janssen <hjanssen@microsoft.com> - * K. Y. Srinivasan <kys@microsoft.com> - * - */ - -#ifndef _HYPERV_H -#define _HYPERV_H - -#include <linux/scatterlist.h> -#include <linux/list.h> -#include <linux/uuid.h> -#include <linux/timer.h> -#include <linux/workqueue.h> -#include <linux/completion.h> -#include <linux/device.h> -#include <linux/mod_devicetable.h> - - -#include <asm/hyperv.h> - - -#define MAX_PAGE_BUFFER_COUNT 16 -#define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */ - -#pragma pack(push, 1) - -/* Single-page buffer */ -struct hv_page_buffer { - u32 len; - u32 offset; - u64 pfn; -}; - -/* Multiple-page buffer */ -struct hv_multipage_buffer { - /* Length and Offset determines the # of pfns in the array */ - u32 len; - u32 offset; - u64 pfn_array[MAX_MULTIPAGE_BUFFER_COUNT]; -}; - -/* 0x18 includes the proprietary packet header */ -#define MAX_PAGE_BUFFER_PACKET (0x18 + \ - (sizeof(struct hv_page_buffer) * \ - MAX_PAGE_BUFFER_COUNT)) -#define MAX_MULTIPAGE_BUFFER_PACKET (0x18 + \ - sizeof(struct hv_multipage_buffer)) - - -#pragma pack(pop) - -struct hv_ring_buffer { - /* Offset in bytes from the start of ring data below */ - u32 write_index; - - /* Offset in bytes from the start of ring data below */ - u32 read_index; - - u32 interrupt_mask; - - /* Pad it to PAGE_SIZE so that data starts on page boundary */ - u8 reserved[4084]; - - /* NOTE: - * The interrupt_mask field is used only for channels but since our - * vmbus connection also uses this data structure and its data starts - * here, we commented out this field. - */ - - /* - * Ring data starts here + RingDataStartOffset - * !!! DO NOT place any fields below this !!! - */ - u8 buffer[0]; -} __packed; - -struct hv_ring_buffer_info { - struct hv_ring_buffer *ring_buffer; - u32 ring_size; /* Include the shared header */ - spinlock_t ring_lock; - - u32 ring_datasize; /* < ring_size */ - u32 ring_data_startoffset; -}; - -struct hv_ring_buffer_debug_info { - u32 current_interrupt_mask; - u32 current_read_index; - u32 current_write_index; - u32 bytes_avail_toread; - u32 bytes_avail_towrite; -}; - -/* - * We use the same version numbering for all Hyper-V modules. - * - * Definition of versioning is as follows; - * - * Major Number Changes for these scenarios; - * 1. When a new version of Windows Hyper-V - * is released. - * 2. A Major change has occurred in the - * Linux IC's. - * (For example the merge for the first time - * into the kernel) Every time the Major Number - * changes, the Revision number is reset to 0. - * Minor Number Changes when new functionality is added - * to the Linux IC's that is not a bug fix. - * - * 3.1 - Added completed hv_utils driver. Shutdown/Heartbeat/Timesync - */ -#define HV_DRV_VERSION "3.1" - - -/* - * A revision number of vmbus that is used for ensuring both ends on a - * partition are using compatible versions. - */ -#define VMBUS_REVISION_NUMBER 13 - -/* Make maximum size of pipe payload of 16K */ -#define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384) - -/* Define PipeMode values. */ -#define VMBUS_PIPE_TYPE_BYTE 0x00000000 -#define VMBUS_PIPE_TYPE_MESSAGE 0x00000004 - -/* The size of the user defined data buffer for non-pipe offers. */ -#define MAX_USER_DEFINED_BYTES 120 - -/* The size of the user defined data buffer for pipe offers. */ -#define MAX_PIPE_USER_DEFINED_BYTES 116 - -/* - * At the center of the Channel Management library is the Channel Offer. This - * struct contains the fundamental information about an offer. - */ -struct vmbus_channel_offer { - uuid_le if_type; - uuid_le if_instance; - u64 int_latency; /* in 100ns units */ - u32 if_revision; - u32 server_ctx_size; /* in bytes */ - u16 chn_flags; - u16 mmio_megabytes; /* in bytes * 1024 * 1024 */ - - union { - /* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */ - struct { - unsigned char user_def[MAX_USER_DEFINED_BYTES]; - } std; - - /* - * Pipes: - * The following sructure is an integrated pipe protocol, which - * is implemented on top of standard user-defined data. Pipe - * clients have MAX_PIPE_USER_DEFINED_BYTES left for their own - * use. - */ - struct { - u32 pipe_mode; - unsigned char user_def[MAX_PIPE_USER_DEFINED_BYTES]; - } pipe; - } u; - u32 padding; -} __packed; - -/* Server Flags */ -#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE 1 -#define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES 2 -#define VMBUS_CHANNEL_SERVER_SUPPORTS_GPADLS 4 -#define VMBUS_CHANNEL_NAMED_PIPE_MODE 0x10 -#define VMBUS_CHANNEL_LOOPBACK_OFFER 0x100 -#define VMBUS_CHANNEL_PARENT_OFFER 0x200 -#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION 0x400 - -struct vmpacket_descriptor { - u16 type; - u16 offset8; - u16 len8; - u16 flags; - u64 trans_id; -} __packed; - -struct vmpacket_header { - u32 prev_pkt_start_offset; - struct vmpacket_descriptor descriptor; -} __packed; - -struct vmtransfer_page_range { - u32 byte_count; - u32 byte_offset; -} __packed; - -struct vmtransfer_page_packet_header { - struct vmpacket_descriptor d; - u16 xfer_pageset_id; - bool sender_owns_set; - u8 reserved; - u32 range_cnt; - struct vmtransfer_page_range ranges[1]; -} __packed; - -struct vmgpadl_packet_header { - struct vmpacket_descriptor d; - u32 gpadl; - u32 reserved; -} __packed; - -struct vmadd_remove_transfer_page_set { - struct vmpacket_descriptor d; - u32 gpadl; - u16 xfer_pageset_id; - u16 reserved; -} __packed; - -/* - * This structure defines a range in guest physical space that can be made to - * look virtually contiguous. - */ -struct gpa_range { - u32 byte_count; - u32 byte_offset; - u64 pfn_array[0]; -}; - -/* - * This is the format for an Establish Gpadl packet, which contains a handle by - * which this GPADL will be known and a set of GPA ranges associated with it. - * This can be converted to a MDL by the guest OS. If there are multiple GPA - * ranges, then the resulting MDL will be "chained," representing multiple VA - * ranges. - */ -struct vmestablish_gpadl { - struct vmpacket_descriptor d; - u32 gpadl; - u32 range_cnt; - struct gpa_range range[1]; -} __packed; - -/* - * This is the format for a Teardown Gpadl packet, which indicates that the - * GPADL handle in the Establish Gpadl packet will never be referenced again. - */ -struct vmteardown_gpadl { - struct vmpacket_descriptor d; - u32 gpadl; - u32 reserved; /* for alignment to a 8-byte boundary */ -} __packed; - -/* - * This is the format for a GPA-Direct packet, which contains a set of GPA - * ranges, in addition to commands and/or data. - */ -struct vmdata_gpa_direct { - struct vmpacket_descriptor d; - u32 reserved; - u32 range_cnt; - struct gpa_range range[1]; -} __packed; - -/* This is the format for a Additional Data Packet. */ -struct vmadditional_data { - struct vmpacket_descriptor d; - u64 total_bytes; - u32 offset; - u32 byte_cnt; - unsigned char data[1]; -} __packed; - -union vmpacket_largest_possible_header { - struct vmpacket_descriptor simple_hdr; - struct vmtransfer_page_packet_header xfer_page_hdr; - struct vmgpadl_packet_header gpadl_hdr; - struct vmadd_remove_transfer_page_set add_rm_xfer_page_hdr; - struct vmestablish_gpadl establish_gpadl_hdr; - struct vmteardown_gpadl teardown_gpadl_hdr; - struct vmdata_gpa_direct data_gpa_direct_hdr; -}; - -#define VMPACKET_DATA_START_ADDRESS(__packet) \ - (void *)(((unsigned char *)__packet) + \ - ((struct vmpacket_descriptor)__packet)->offset8 * 8) - -#define VMPACKET_DATA_LENGTH(__packet) \ - ((((struct vmpacket_descriptor)__packet)->len8 - \ - ((struct vmpacket_descriptor)__packet)->offset8) * 8) - -#define VMPACKET_TRANSFER_MODE(__packet) \ - (((struct IMPACT)__packet)->type) - -enum vmbus_packet_type { - VM_PKT_INVALID = 0x0, - VM_PKT_SYNCH = 0x1, - VM_PKT_ADD_XFER_PAGESET = 0x2, - VM_PKT_RM_XFER_PAGESET = 0x3, - VM_PKT_ESTABLISH_GPADL = 0x4, - VM_PKT_TEARDOWN_GPADL = 0x5, - VM_PKT_DATA_INBAND = 0x6, - VM_PKT_DATA_USING_XFER_PAGES = 0x7, - VM_PKT_DATA_USING_GPADL = 0x8, - VM_PKT_DATA_USING_GPA_DIRECT = 0x9, - VM_PKT_CANCEL_REQUEST = 0xa, - VM_PKT_COMP = 0xb, - VM_PKT_DATA_USING_ADDITIONAL_PKT = 0xc, - VM_PKT_ADDITIONAL_DATA = 0xd -}; - -#define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1 - - -/* Version 1 messages */ -enum vmbus_channel_message_type { - CHANNELMSG_INVALID = 0, - CHANNELMSG_OFFERCHANNEL = 1, - CHANNELMSG_RESCIND_CHANNELOFFER = 2, - CHANNELMSG_REQUESTOFFERS = 3, - CHANNELMSG_ALLOFFERS_DELIVERED = 4, - CHANNELMSG_OPENCHANNEL = 5, - CHANNELMSG_OPENCHANNEL_RESULT = 6, - CHANNELMSG_CLOSECHANNEL = 7, - CHANNELMSG_GPADL_HEADER = 8, - CHANNELMSG_GPADL_BODY = 9, - CHANNELMSG_GPADL_CREATED = 10, - CHANNELMSG_GPADL_TEARDOWN = 11, - CHANNELMSG_GPADL_TORNDOWN = 12, - CHANNELMSG_RELID_RELEASED = 13, - CHANNELMSG_INITIATE_CONTACT = 14, - CHANNELMSG_VERSION_RESPONSE = 15, - CHANNELMSG_UNLOAD = 16, -#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD - CHANNELMSG_VIEWRANGE_ADD = 17, - CHANNELMSG_VIEWRANGE_REMOVE = 18, -#endif - CHANNELMSG_COUNT -}; - -struct vmbus_channel_message_header { - enum vmbus_channel_message_type msgtype; - u32 padding; -} __packed; - -/* Query VMBus Version parameters */ -struct vmbus_channel_query_vmbus_version { - struct vmbus_channel_message_header header; - u32 version; -} __packed; - -/* VMBus Version Supported parameters */ -struct vmbus_channel_version_supported { - struct vmbus_channel_message_header header; - bool version_supported; -} __packed; - -/* Offer Channel parameters */ -struct vmbus_channel_offer_channel { - struct vmbus_channel_message_header header; - struct vmbus_channel_offer offer; - u32 child_relid; - u8 monitorid; - bool monitor_allocated; -} __packed; - -/* Rescind Offer parameters */ -struct vmbus_channel_rescind_offer { - struct vmbus_channel_message_header header; - u32 child_relid; -} __packed; - -/* - * Request Offer -- no parameters, SynIC message contains the partition ID - * Set Snoop -- no parameters, SynIC message contains the partition ID - * Clear Snoop -- no parameters, SynIC message contains the partition ID - * All Offers Delivered -- no parameters, SynIC message contains the partition - * ID - * Flush Client -- no parameters, SynIC message contains the partition ID - */ - -/* Open Channel parameters */ -struct vmbus_channel_open_channel { - struct vmbus_channel_message_header header; - - /* Identifies the specific VMBus channel that is being opened. */ - u32 child_relid; - - /* ID making a particular open request at a channel offer unique. */ - u32 openid; - - /* GPADL for the channel's ring buffer. */ - u32 ringbuffer_gpadlhandle; - - /* GPADL for the channel's server context save area. */ - u32 server_contextarea_gpadlhandle; - - /* - * The upstream ring buffer begins at offset zero in the memory - * described by RingBufferGpadlHandle. The downstream ring buffer - * follows it at this offset (in pages). - */ - u32 downstream_ringbuffer_pageoffset; - - /* User-specific data to be passed along to the server endpoint. */ - unsigned char userdata[MAX_USER_DEFINED_BYTES]; -} __packed; - -/* Open Channel Result parameters */ -struct vmbus_channel_open_result { - struct vmbus_channel_message_header header; - u32 child_relid; - u32 openid; - u32 status; -} __packed; - -/* Close channel parameters; */ -struct vmbus_channel_close_channel { - struct vmbus_channel_message_header header; - u32 child_relid; -} __packed; - -/* Channel Message GPADL */ -#define GPADL_TYPE_RING_BUFFER 1 -#define GPADL_TYPE_SERVER_SAVE_AREA 2 -#define GPADL_TYPE_TRANSACTION 8 - -/* - * The number of PFNs in a GPADL message is defined by the number of - * pages that would be spanned by ByteCount and ByteOffset. If the - * implied number of PFNs won't fit in this packet, there will be a - * follow-up packet that contains more. - */ -struct vmbus_channel_gpadl_header { - struct vmbus_channel_message_header header; - u32 child_relid; - u32 gpadl; - u16 range_buflen; - u16 rangecount; - struct gpa_range range[0]; -} __packed; - -/* This is the followup packet that contains more PFNs. */ -struct vmbus_channel_gpadl_body { - struct vmbus_channel_message_header header; - u32 msgnumber; - u32 gpadl; - u64 pfn[0]; -} __packed; - -struct vmbus_channel_gpadl_created { - struct vmbus_channel_message_header header; - u32 child_relid; - u32 gpadl; - u32 creation_status; -} __packed; - -struct vmbus_channel_gpadl_teardown { - struct vmbus_channel_message_header header; - u32 child_relid; - u32 gpadl; -} __packed; - -struct vmbus_channel_gpadl_torndown { - struct vmbus_channel_message_header header; - u32 gpadl; -} __packed; - -#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD -struct vmbus_channel_view_range_add { - struct vmbus_channel_message_header header; - PHYSICAL_ADDRESS viewrange_base; - u64 viewrange_length; - u32 child_relid; -} __packed; - -struct vmbus_channel_view_range_remove { - struct vmbus_channel_message_header header; - PHYSICAL_ADDRESS viewrange_base; - u32 child_relid; -} __packed; -#endif - -struct vmbus_channel_relid_released { - struct vmbus_channel_message_header header; - u32 child_relid; -} __packed; - -struct vmbus_channel_initiate_contact { - struct vmbus_channel_message_header header; - u32 vmbus_version_requested; - u32 padding2; - u64 interrupt_page; - u64 monitor_page1; - u64 monitor_page2; -} __packed; - -struct vmbus_channel_version_response { - struct vmbus_channel_message_header header; - bool version_supported; -} __packed; - -enum vmbus_channel_state { - CHANNEL_OFFER_STATE, - CHANNEL_OPENING_STATE, - CHANNEL_OPEN_STATE, -}; - -struct vmbus_channel_debug_info { - u32 relid; - enum vmbus_channel_state state; - uuid_le interfacetype; - uuid_le interface_instance; - u32 monitorid; - u32 servermonitor_pending; - u32 servermonitor_latency; - u32 servermonitor_connectionid; - u32 clientmonitor_pending; - u32 clientmonitor_latency; - u32 clientmonitor_connectionid; - - struct hv_ring_buffer_debug_info inbound; - struct hv_ring_buffer_debug_info outbound; -}; - -/* - * Represents each channel msg on the vmbus connection This is a - * variable-size data structure depending on the msg type itself - */ -struct vmbus_channel_msginfo { - /* Bookkeeping stuff */ - struct list_head msglistentry; - - /* So far, this is only used to handle gpadl body message */ - struct list_head submsglist; - - /* Synchronize the request/response if needed */ - struct completion waitevent; - union { - struct vmbus_channel_version_supported version_supported; - struct vmbus_channel_open_result open_result; - struct vmbus_channel_gpadl_torndown gpadl_torndown; - struct vmbus_channel_gpadl_created gpadl_created; - struct vmbus_channel_version_response version_response; - } response; - - u32 msgsize; - /* - * The channel message that goes out on the "wire". - * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header - */ - unsigned char msg[0]; -}; - -struct vmbus_close_msg { - struct vmbus_channel_msginfo info; - struct vmbus_channel_close_channel msg; -}; - -struct vmbus_channel { - struct list_head listentry; - - struct hv_device *device_obj; - - struct work_struct work; - - enum vmbus_channel_state state; - - struct vmbus_channel_offer_channel offermsg; - /* - * These are based on the OfferMsg.MonitorId. - * Save it here for easy access. - */ - u8 monitor_grp; - u8 monitor_bit; - - u32 ringbuffer_gpadlhandle; - - /* Allocated memory for ring buffer */ - void *ringbuffer_pages; - u32 ringbuffer_pagecount; - struct hv_ring_buffer_info outbound; /* send to parent */ - struct hv_ring_buffer_info inbound; /* receive from parent */ - spinlock_t inbound_lock; - struct workqueue_struct *controlwq; - - struct vmbus_close_msg close_msg; - - /* Channel callback are invoked in this workqueue context */ - /* HANDLE dataWorkQueue; */ - - void (*onchannel_callback)(void *context); - void *channel_callback_context; -}; - -void free_channel(struct vmbus_channel *channel); - -void vmbus_onmessage(void *context); - -int vmbus_request_offers(void); - -/* The format must be the same as struct vmdata_gpa_direct */ -struct vmbus_channel_packet_page_buffer { - u16 type; - u16 dataoffset8; - u16 length8; - u16 flags; - u64 transactionid; - u32 reserved; - u32 rangecount; - struct hv_page_buffer range[MAX_PAGE_BUFFER_COUNT]; -} __packed; - -/* The format must be the same as struct vmdata_gpa_direct */ -struct vmbus_channel_packet_multipage_buffer { - u16 type; - u16 dataoffset8; - u16 length8; - u16 flags; - u64 transactionid; - u32 reserved; - u32 rangecount; /* Always 1 in this case */ - struct hv_multipage_buffer range; -} __packed; - - -extern int vmbus_open(struct vmbus_channel *channel, - u32 send_ringbuffersize, - u32 recv_ringbuffersize, - void *userdata, - u32 userdatalen, - void(*onchannel_callback)(void *context), - void *context); - -extern void vmbus_close(struct vmbus_channel *channel); - -extern int vmbus_sendpacket(struct vmbus_channel *channel, - const void *buffer, - u32 bufferLen, - u64 requestid, - enum vmbus_packet_type type, - u32 flags); - -extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, - struct hv_page_buffer pagebuffers[], - u32 pagecount, - void *buffer, - u32 bufferlen, - u64 requestid); - -extern int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, - struct hv_multipage_buffer *mpb, - void *buffer, - u32 bufferlen, - u64 requestid); - -extern int vmbus_establish_gpadl(struct vmbus_channel *channel, - void *kbuffer, - u32 size, - u32 *gpadl_handle); - -extern int vmbus_teardown_gpadl(struct vmbus_channel *channel, - u32 gpadl_handle); - -extern int vmbus_recvpacket(struct vmbus_channel *channel, - void *buffer, - u32 bufferlen, - u32 *buffer_actual_len, - u64 *requestid); - -extern int vmbus_recvpacket_raw(struct vmbus_channel *channel, - void *buffer, - u32 bufferlen, - u32 *buffer_actual_len, - u64 *requestid); - - -extern void vmbus_get_debug_info(struct vmbus_channel *channel, - struct vmbus_channel_debug_info *debug); - -extern void vmbus_ontimer(unsigned long data); - - -#define LOWORD(dw) ((unsigned short)(dw)) -#define HIWORD(dw) ((unsigned short)(((unsigned int) (dw) >> 16) & 0xFFFF)) - - -#define VMBUS 0x0001 -#define STORVSC 0x0002 -#define NETVSC 0x0004 -#define INPUTVSC 0x0008 -#define BLKVSC 0x0010 -#define VMBUS_DRV 0x0100 -#define STORVSC_DRV 0x0200 -#define NETVSC_DRV 0x0400 -#define INPUTVSC_DRV 0x0800 -#define BLKVSC_DRV 0x1000 - -#define ALL_MODULES (VMBUS |\ - STORVSC |\ - NETVSC |\ - INPUTVSC |\ - BLKVSC |\ - VMBUS_DRV |\ - STORVSC_DRV |\ - NETVSC_DRV |\ - INPUTVSC_DRV|\ - BLKVSC_DRV) - -/* Logging Level */ -#define ERROR_LVL 3 -#define WARNING_LVL 4 -#define INFO_LVL 6 -#define DEBUG_LVL 7 -#define DEBUG_LVL_ENTEREXIT 8 -#define DEBUG_RING_LVL 9 - -extern unsigned int vmbus_loglevel; - -#define DPRINT(mod, lvl, fmt, args...) do {\ - if ((mod & (HIWORD(vmbus_loglevel))) && \ - (lvl <= LOWORD(vmbus_loglevel))) \ - printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\ - } while (0) - -#define DPRINT_DBG(mod, fmt, args...) do {\ - if ((mod & (HIWORD(vmbus_loglevel))) && \ - (DEBUG_LVL <= LOWORD(vmbus_loglevel))) \ - printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\ - } while (0) - -#define DPRINT_INFO(mod, fmt, args...) do {\ - if ((mod & (HIWORD(vmbus_loglevel))) && \ - (INFO_LVL <= LOWORD(vmbus_loglevel))) \ - printk(KERN_INFO #mod": " fmt "\n", ## args);\ - } while (0) - -#define DPRINT_WARN(mod, fmt, args...) do {\ - if ((mod & (HIWORD(vmbus_loglevel))) && \ - (WARNING_LVL <= LOWORD(vmbus_loglevel))) \ - printk(KERN_WARNING #mod": WARNING! " fmt "\n", ## args);\ - } while (0) - -#define DPRINT_ERR(mod, fmt, args...) do {\ - if ((mod & (HIWORD(vmbus_loglevel))) && \ - (ERROR_LVL <= LOWORD(vmbus_loglevel))) \ - printk(KERN_ERR #mod": %s() ERROR!! " fmt "\n", \ - __func__, ## args);\ - } while (0) - - - -struct hv_driver; -struct hv_device; - -struct hv_dev_port_info { - u32 int_mask; - u32 read_idx; - u32 write_idx; - u32 bytes_avail_toread; - u32 bytes_avail_towrite; -}; - -struct hv_device_info { - u32 chn_id; - u32 chn_state; - uuid_le chn_type; - uuid_le chn_instance; - - u32 monitor_id; - u32 server_monitor_pending; - u32 server_monitor_latency; - u32 server_monitor_conn_id; - u32 client_monitor_pending; - u32 client_monitor_latency; - u32 client_monitor_conn_id; - - struct hv_dev_port_info inbound; - struct hv_dev_port_info outbound; -}; - -/* Base driver object */ -struct hv_driver { - const char *name; - - /* the device type supported by this driver */ - uuid_le dev_type; - const struct hv_vmbus_device_id *id_table; - - struct device_driver driver; - - int (*probe)(struct hv_device *, const struct hv_vmbus_device_id *); - int (*remove)(struct hv_device *); - void (*shutdown)(struct hv_device *); - -}; - -/* Base device object */ -struct hv_device { - /* the device type id of this device */ - uuid_le dev_type; - - /* the device instance id of this device */ - uuid_le dev_instance; - - struct device device; - - struct vmbus_channel *channel; -}; - - -static inline struct hv_device *device_to_hv_device(struct device *d) -{ - return container_of(d, struct hv_device, device); -} - -static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d) -{ - return container_of(d, struct hv_driver, driver); -} - -static inline void hv_set_drvdata(struct hv_device *dev, void *data) -{ - dev_set_drvdata(&dev->device, data); -} - -static inline void *hv_get_drvdata(struct hv_device *dev) -{ - return dev_get_drvdata(&dev->device); -} - -/* Vmbus interface */ -#define vmbus_driver_register(driver) \ - __vmbus_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) -int __must_check __vmbus_driver_register(struct hv_driver *hv_driver, - struct module *owner, - const char *mod_name); -void vmbus_driver_unregister(struct hv_driver *hv_driver); - -/** - * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device - * - * This macro is used to create a struct hv_vmbus_device_id that matches a - * specific device. - */ -#define VMBUS_DEVICE(g0, g1, g2, g3, g4, g5, g6, g7, \ - g8, g9, ga, gb, gc, gd, ge, gf) \ - .guid = { g0, g1, g2, g3, g4, g5, g6, g7, \ - g8, g9, ga, gb, gc, gd, ge, gf }, - -/* - * Common header for Hyper-V ICs - */ - -#define ICMSGTYPE_NEGOTIATE 0 -#define ICMSGTYPE_HEARTBEAT 1 -#define ICMSGTYPE_KVPEXCHANGE 2 -#define ICMSGTYPE_SHUTDOWN 3 -#define ICMSGTYPE_TIMESYNC 4 -#define ICMSGTYPE_VSS 5 - -#define ICMSGHDRFLAG_TRANSACTION 1 -#define ICMSGHDRFLAG_REQUEST 2 -#define ICMSGHDRFLAG_RESPONSE 4 - -#define HV_S_OK 0x00000000 -#define HV_E_FAIL 0x80004005 -#define HV_ERROR_NOT_SUPPORTED 0x80070032 -#define HV_ERROR_MACHINE_LOCKED 0x800704F7 - -/* - * While we want to handle util services as regular devices, - * there is only one instance of each of these services; so - * we statically allocate the service specific state. - */ - -struct hv_util_service { - u8 *recv_buffer; - void (*util_cb)(void *); - int (*util_init)(struct hv_util_service *); - void (*util_deinit)(void); -}; - -struct vmbuspipe_hdr { - u32 flags; - u32 msgsize; -} __packed; - -struct ic_version { - u16 major; - u16 minor; -} __packed; - -struct icmsg_hdr { - struct ic_version icverframe; - u16 icmsgtype; - struct ic_version icvermsg; - u16 icmsgsize; - u32 status; - u8 ictransaction_id; - u8 icflags; - u8 reserved[2]; -} __packed; - -struct icmsg_negotiate { - u16 icframe_vercnt; - u16 icmsg_vercnt; - u32 reserved; - struct ic_version icversion_data[1]; /* any size array */ -} __packed; - -struct shutdown_msg_data { - u32 reason_code; - u32 timeout_seconds; - u32 flags; - u8 display_message[2048]; -} __packed; - -struct heartbeat_msg_data { - u64 seq_num; - u32 reserved[8]; -} __packed; - -/* Time Sync IC defs */ -#define ICTIMESYNCFLAG_PROBE 0 -#define ICTIMESYNCFLAG_SYNC 1 -#define ICTIMESYNCFLAG_SAMPLE 2 - -#ifdef __x86_64__ -#define WLTIMEDELTA 116444736000000000L /* in 100ns unit */ -#else -#define WLTIMEDELTA 116444736000000000LL -#endif - -struct ictimesync_data { - u64 parenttime; - u64 childtime; - u64 roundtriptime; - u8 flags; -} __packed; - -struct hyperv_service_callback { - u8 msg_type; - char *log_msg; - uuid_le data; - struct vmbus_channel *channel; - void (*callback) (void *context); -}; - -extern void prep_negotiate_resp(struct icmsg_hdr *, - struct icmsg_negotiate *, u8 *); - -#endif /* _HYPERV_H */ diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/staging/hv/hyperv_net.h index 366dd2b32b13..ac1ec8405124 100644 --- a/drivers/staging/hv/hyperv_net.h +++ b/drivers/staging/hv/hyperv_net.h @@ -26,7 +26,7 @@ #define _HYPERV_NET_H #include <linux/list.h> -#include "hyperv.h" +#include <linux/hyperv.h> /* Fwd declaration */ struct hv_netvsc_packet; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index e41271632609..af185abbaa73 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -31,6 +31,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/device.h> +#include <linux/hyperv.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_host.h> @@ -40,7 +41,6 @@ #include <scsi/scsi_devinfo.h> #include <scsi/scsi_dbg.h> -#include "hyperv.h" #define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE; diff --git a/drivers/staging/hv/tools/hv_kvp_daemon.c b/drivers/staging/hv/tools/hv_kvp_daemon.c deleted file mode 100644 index 11224eddcdc2..000000000000 --- a/drivers/staging/hv/tools/hv_kvp_daemon.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * An implementation of key value pair (KVP) functionality for Linux. - * - * - * Copyright (C) 2010, Novell, Inc. - * Author : K. Y. Srinivasan <ksrinivasan@novell.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/poll.h> -#include <sys/utsname.h> -#include <linux/types.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <arpa/inet.h> -#include <linux/connector.h> -#include <linux/netlink.h> -#include <ifaddrs.h> -#include <netdb.h> -#include <syslog.h> - -/* - * KYS: TODO. Need to register these in the kernel. - * - * The following definitions are shared with the in-kernel component; do not - * change any of this without making the corresponding changes in - * the KVP kernel component. - */ -#define CN_KVP_IDX 0x9 /* MSFT KVP functionality */ -#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */ -#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */ - -/* - * KVP protocol: The user mode component first registers with the - * the kernel component. Subsequently, the kernel component requests, data - * for the specified keys. In response to this message the user mode component - * fills in the value corresponding to the specified key. We overload the - * sequence field in the cn_msg header to define our KVP message types. - * - * We use this infrastructure for also supporting queries from user mode - * application for state that may be maintained in the KVP kernel component. - * - * XXXKYS: Have a shared header file between the user and kernel (TODO) - */ - -enum kvp_op { - KVP_REGISTER = 0, /* Register the user mode component*/ - KVP_KERNEL_GET, /*Kernel is requesting the value for the specified key*/ - KVP_KERNEL_SET, /*Kernel is providing the value for the specified key*/ - KVP_USER_GET, /*User is requesting the value for the specified key*/ - KVP_USER_SET /*User is providing the value for the specified key*/ -}; - -#define HV_KVP_EXCHANGE_MAX_KEY_SIZE 512 -#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE 2048 - -struct hv_ku_msg { - __u32 kvp_index; - __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ - __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ -}; - -enum key_index { - FullyQualifiedDomainName = 0, - IntegrationServicesVersion, /*This key is serviced in the kernel*/ - NetworkAddressIPv4, - NetworkAddressIPv6, - OSBuildNumber, - OSName, - OSMajorVersion, - OSMinorVersion, - OSVersion, - ProcessorArchitecture -}; - -/* - * End of shared definitions. - */ - -static char kvp_send_buffer[4096]; -static char kvp_recv_buffer[4096]; -static struct sockaddr_nl addr; - -static char *os_name = ""; -static char *os_major = ""; -static char *os_minor = ""; -static char *processor_arch; -static char *os_build; -static char *lic_version; -static struct utsname uts_buf; - -void kvp_get_os_info(void) -{ - FILE *file; - char *p, buf[512]; - - uname(&uts_buf); - os_build = uts_buf.release; - processor_arch = uts_buf.machine; - - /* - * The current windows host (win7) expects the build - * string to be of the form: x.y.z - * Strip additional information we may have. - */ - p = strchr(os_build, '-'); - if (p) - *p = '\0'; - - file = fopen("/etc/SuSE-release", "r"); - if (file != NULL) - goto kvp_osinfo_found; - file = fopen("/etc/redhat-release", "r"); - if (file != NULL) - goto kvp_osinfo_found; - /* - * Add code for other supported platforms. - */ - - /* - * We don't have information about the os. - */ - os_name = uts_buf.sysname; - return; - -kvp_osinfo_found: - /* up to three lines */ - p = fgets(buf, sizeof(buf), file); - if (p) { - p = strchr(buf, '\n'); - if (p) - *p = '\0'; - p = strdup(buf); - if (!p) - goto done; - os_name = p; - - /* second line */ - p = fgets(buf, sizeof(buf), file); - if (p) { - p = strchr(buf, '\n'); - if (p) - *p = '\0'; - p = strdup(buf); - if (!p) - goto done; - os_major = p; - - /* third line */ - p = fgets(buf, sizeof(buf), file); - if (p) { - p = strchr(buf, '\n'); - if (p) - *p = '\0'; - p = strdup(buf); - if (p) - os_minor = p; - } - } - } - -done: - fclose(file); - return; -} - -static int -kvp_get_ip_address(int family, char *buffer, int length) -{ - struct ifaddrs *ifap; - struct ifaddrs *curp; - int ipv4_len = strlen("255.255.255.255") + 1; - int ipv6_len = strlen("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")+1; - int offset = 0; - const char *str; - char tmp[50]; - int error = 0; - - /* - * On entry into this function, the buffer is capable of holding the - * maximum key value (2048 bytes). - */ - - if (getifaddrs(&ifap)) { - strcpy(buffer, "getifaddrs failed\n"); - return 1; - } - - curp = ifap; - while (curp != NULL) { - if ((curp->ifa_addr != NULL) && - (curp->ifa_addr->sa_family == family)) { - if (family == AF_INET) { - struct sockaddr_in *addr = - (struct sockaddr_in *) curp->ifa_addr; - - str = inet_ntop(family, &addr->sin_addr, - tmp, 50); - if (str == NULL) { - strcpy(buffer, "inet_ntop failed\n"); - error = 1; - goto getaddr_done; - } - if (offset == 0) - strcpy(buffer, tmp); - else - strcat(buffer, tmp); - strcat(buffer, ";"); - - offset += strlen(str) + 1; - if ((length - offset) < (ipv4_len + 1)) - goto getaddr_done; - - } else { - - /* - * We only support AF_INET and AF_INET6 - * and the list of addresses is separated by a ";". - */ - struct sockaddr_in6 *addr = - (struct sockaddr_in6 *) curp->ifa_addr; - - str = inet_ntop(family, - &addr->sin6_addr.s6_addr, - tmp, 50); - if (str == NULL) { - strcpy(buffer, "inet_ntop failed\n"); - error = 1; - goto getaddr_done; - } - if (offset == 0) - strcpy(buffer, tmp); - else - strcat(buffer, tmp); - strcat(buffer, ";"); - offset += strlen(str) + 1; - if ((length - offset) < (ipv6_len + 1)) - goto getaddr_done; - - } - - } - curp = curp->ifa_next; - } - -getaddr_done: - freeifaddrs(ifap); - return error; -} - - -static int -kvp_get_domain_name(char *buffer, int length) -{ - struct addrinfo hints, *info ; - int error = 0; - - gethostname(buffer, length); - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; /*Get only ipv4 addrinfo. */ - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_CANONNAME; - - error = getaddrinfo(buffer, NULL, &hints, &info); - if (error != 0) { - strcpy(buffer, "getaddrinfo failed\n"); - return error; - } - strcpy(buffer, info->ai_canonname); - freeaddrinfo(info); - return error; -} - -static int -netlink_send(int fd, struct cn_msg *msg) -{ - struct nlmsghdr *nlh; - unsigned int size; - struct msghdr message; - char buffer[64]; - struct iovec iov[2]; - - size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len); - - nlh = (struct nlmsghdr *)buffer; - nlh->nlmsg_seq = 0; - nlh->nlmsg_pid = getpid(); - nlh->nlmsg_type = NLMSG_DONE; - nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh)); - nlh->nlmsg_flags = 0; - - iov[0].iov_base = nlh; - iov[0].iov_len = sizeof(*nlh); - - iov[1].iov_base = msg; - iov[1].iov_len = size; - - memset(&message, 0, sizeof(message)); - message.msg_name = &addr; - message.msg_namelen = sizeof(addr); - message.msg_iov = iov; - message.msg_iovlen = 2; - - return sendmsg(fd, &message, 0); -} - -int main(void) -{ - int fd, len, sock_opt; - int error; - struct cn_msg *message; - struct pollfd pfd; - struct nlmsghdr *incoming_msg; - struct cn_msg *incoming_cn_msg; - struct hv_ku_msg *hv_msg; - char *p; - char *key_value; - char *key_name; - - daemon(1, 0); - openlog("KVP", 0, LOG_USER); - syslog(LOG_INFO, "KVP starting; pid is:%d", getpid()); - /* - * Retrieve OS release information. - */ - kvp_get_os_info(); - - fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); - if (fd < 0) { - syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd); - exit(-1); - } - addr.nl_family = AF_NETLINK; - addr.nl_pad = 0; - addr.nl_pid = 0; - addr.nl_groups = CN_KVP_IDX; - - - error = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); - if (error < 0) { - syslog(LOG_ERR, "bind failed; error:%d", error); - close(fd); - exit(-1); - } - sock_opt = addr.nl_groups; - setsockopt(fd, 270, 1, &sock_opt, sizeof(sock_opt)); - /* - * Register ourselves with the kernel. - */ - message = (struct cn_msg *)kvp_send_buffer; - message->id.idx = CN_KVP_IDX; - message->id.val = CN_KVP_VAL; - message->seq = KVP_REGISTER; - message->ack = 0; - message->len = 0; - - len = netlink_send(fd, message); - if (len < 0) { - syslog(LOG_ERR, "netlink_send failed; error:%d", len); - close(fd); - exit(-1); - } - - pfd.fd = fd; - - while (1) { - pfd.events = POLLIN; - pfd.revents = 0; - poll(&pfd, 1, -1); - - len = recv(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0); - - if (len < 0) { - syslog(LOG_ERR, "recv failed; error:%d", len); - close(fd); - return -1; - } - - incoming_msg = (struct nlmsghdr *)kvp_recv_buffer; - incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg); - - switch (incoming_cn_msg->seq) { - case KVP_REGISTER: - /* - * Driver is registering with us; stash away the version - * information. - */ - p = (char *)incoming_cn_msg->data; - lic_version = malloc(strlen(p) + 1); - if (lic_version) { - strcpy(lic_version, p); - syslog(LOG_INFO, "KVP LIC Version: %s", - lic_version); - } else { - syslog(LOG_ERR, "malloc failed"); - } - continue; - - case KVP_KERNEL_GET: - break; - default: - continue; - } - - hv_msg = (struct hv_ku_msg *)incoming_cn_msg->data; - key_name = (char *)hv_msg->kvp_key; - key_value = (char *)hv_msg->kvp_value; - - switch (hv_msg->kvp_index) { - case FullyQualifiedDomainName: - kvp_get_domain_name(key_value, - HV_KVP_EXCHANGE_MAX_VALUE_SIZE); - strcpy(key_name, "FullyQualifiedDomainName"); - break; - case IntegrationServicesVersion: - strcpy(key_name, "IntegrationServicesVersion"); - strcpy(key_value, lic_version); - break; - case NetworkAddressIPv4: - kvp_get_ip_address(AF_INET, key_value, - HV_KVP_EXCHANGE_MAX_VALUE_SIZE); - strcpy(key_name, "NetworkAddressIPv4"); - break; - case NetworkAddressIPv6: - kvp_get_ip_address(AF_INET6, key_value, - HV_KVP_EXCHANGE_MAX_VALUE_SIZE); - strcpy(key_name, "NetworkAddressIPv6"); - break; - case OSBuildNumber: - strcpy(key_value, os_build); - strcpy(key_name, "OSBuildNumber"); - break; - case OSName: - strcpy(key_value, os_name); - strcpy(key_name, "OSName"); - break; - case OSMajorVersion: - strcpy(key_value, os_major); - strcpy(key_name, "OSMajorVersion"); - break; - case OSMinorVersion: - strcpy(key_value, os_minor); - strcpy(key_name, "OSMinorVersion"); - break; - case OSVersion: - strcpy(key_value, os_build); - strcpy(key_name, "OSVersion"); - break; - case ProcessorArchitecture: - strcpy(key_value, processor_arch); - strcpy(key_name, "ProcessorArchitecture"); - break; - default: - strcpy(key_value, "Unknown Key"); - /* - * We use a null key name to terminate enumeration. - */ - strcpy(key_name, ""); - break; - } - /* - * Send the value back to the kernel. The response is - * already in the receive buffer. Update the cn_msg header to - * reflect the key value that has been added to the message - */ - - incoming_cn_msg->id.idx = CN_KVP_IDX; - incoming_cn_msg->id.val = CN_KVP_VAL; - incoming_cn_msg->seq = KVP_USER_SET; - incoming_cn_msg->ack = 0; - incoming_cn_msg->len = sizeof(struct hv_ku_msg); - - len = netlink_send(fd, incoming_cn_msg); - if (len < 0) { - syslog(LOG_ERR, "net_link send failed; error:%d", len); - exit(-1); - } - } - -} |