aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-10-04 15:29:52 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-10-11 00:52:55 -0400
commit46a971913611a23478283931460a95be962ce329 (patch)
tree7452d0f07ee9f1f5270a8da6c1387f35c439843d /drivers
parent715a4801e734ea9c8e528265ce3ff6aead85bce1 (diff)
Staging: hv: move hyperv code out of staging directory
After many years wandering the desert, it is finally time for the Microsoft HyperV code to move out of the staging directory. Or at least the core hyperv bus code, and the utility driver, the rest still have some review to get through by the various subsystem maintainers. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/hv/Kconfig14
-rw-r--r--drivers/hv/Makefile7
-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/Kconfig28
-rw-r--r--drivers/staging/hv/Makefile7
-rw-r--r--drivers/staging/hv/hv_mouse.c3
-rw-r--r--drivers/staging/hv/hyperv.h969
-rw-r--r--drivers/staging/hv/hyperv_net.h2
-rw-r--r--drivers/staging/hv/storvsc_drv.c2
-rw-r--r--drivers/staging/hv/tools/hv_kvp_daemon.c500
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"
130 130
131source "drivers/virt/Kconfig" 131source "drivers/virt/Kconfig"
132 132
133source "drivers/hv/Kconfig"
134
133endmenu 135endmenu
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/
127 127
128# Virtualization drivers 128# Virtualization drivers
129obj-$(CONFIG_VIRT_DRIVERS) += virt/ 129obj-$(CONFIG_VIRT_DRIVERS) += virt/
130obj-$(CONFIG_HYPERV) += hv/
131
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 @@
1config HYPERV
2 tristate "Microsoft Hyper-V client drivers"
3 depends on X86 && ACPI && PCI
4 help
5 Select this option to run Linux as a Hyper-V client operating
6 system.
7
8config HYPERV_UTILS
9 tristate "Microsoft Hyper-V Utilities driver"
10 depends on HYPERV && CONNECTOR && NLS
11 help
12 Select this option to enable the Hyper-V Utilities.
13
14
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 @@
1obj-$(CONFIG_HYPERV) += hv_vmbus.o
2obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o
3
4hv_vmbus-y := vmbus_drv.o \
5 hv.o connection.o channel.o \
6 channel_mgmt.o ring_buffer.o
7hv_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 @@
26#include <linux/mm.h> 26#include <linux/mm.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/hyperv.h>
29 30
30#include "hyperv.h"
31#include "hyperv_vmbus.h" 31#include "hyperv_vmbus.h"
32 32
33#define NUM_PAGES_SPANNED(addr, len) \ 33#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 @@
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/completion.h> 30#include <linux/completion.h>
31#include <linux/hyperv.h>
31 32
32#include "hyperv.h"
33#include "hyperv_vmbus.h" 33#include "hyperv_vmbus.h"
34 34
35struct vmbus_channel_message_table_entry { 35struct 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 @@
29#include <linux/mm.h> 29#include <linux/mm.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/vmalloc.h> 31#include <linux/vmalloc.h>
32#include <linux/hyperv.h>
32 33
33#include "hyperv.h"
34#include "hyperv_vmbus.h" 34#include "hyperv_vmbus.h"
35 35
36 36
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 @@
25#include <linux/mm.h> 25#include <linux/mm.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
28#include <linux/hyperv.h>
28 29
29#include "hyperv.h"
30#include "hyperv_vmbus.h" 30#include "hyperv_vmbus.h"
31 31
32/* The one and only */ 32/* 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 @@
26#include <linux/nls.h> 26#include <linux/nls.h>
27#include <linux/connector.h> 27#include <linux/connector.h>
28#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include <linux/hyperv.h>
29 30
30#include "hyperv.h"
31#include "hv_kvp.h" 31#include "hv_kvp.h"
32 32
33 33
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 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/sysctl.h> 27#include <linux/sysctl.h>
28#include <linux/reboot.h> 28#include <linux/reboot.h>
29#include <linux/hyperv.h>
29 30
30#include "hyperv.h"
31#include "hv_kvp.h" 31#include "hv_kvp.h"
32 32
33 33
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 @@
28#include <linux/list.h> 28#include <linux/list.h>
29#include <asm/sync_bitops.h> 29#include <asm/sync_bitops.h>
30#include <linux/atomic.h> 30#include <linux/atomic.h>
31 31#include <linux/hyperv.h>
32#include "hyperv.h"
33 32
34/* 33/*
35 * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent 34 * 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 @@
25 25
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/hyperv.h>
28 29
29#include "hyperv.h"
30#include "hyperv_vmbus.h" 30#include "hyperv_vmbus.h"
31 31
32 32
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 @@
32#include <linux/acpi.h> 32#include <linux/acpi.h>
33#include <acpi/acpi_bus.h> 33#include <acpi/acpi_bus.h>
34#include <linux/completion.h> 34#include <linux/completion.h>
35#include <linux/hyperv.h>
35 36
36#include "hyperv.h"
37#include "hyperv_vmbus.h" 37#include "hyperv_vmbus.h"
38 38
39 39
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 @@
1config HYPERV
2 tristate "Microsoft Hyper-V client drivers"
3 depends on X86 && ACPI && PCI
4 default n
5 help
6 Select this option to run Linux as a Hyper-V client operating
7 system.
8
9if HYPERV
10
11config HYPERV_STORAGE 1config HYPERV_STORAGE
12 tristate "Microsoft Hyper-V virtual storage driver" 2 tristate "Microsoft Hyper-V virtual storage driver"
13 depends on SCSI 3 depends on HYPERV && SCSI
14 default HYPERV
15 help 4 help
16 Select this option to enable the Hyper-V virtual storage driver. 5 Select this option to enable the Hyper-V virtual storage driver.
17 6
18config HYPERV_NET 7config HYPERV_NET
19 tristate "Microsoft Hyper-V virtual network driver" 8 tristate "Microsoft Hyper-V virtual network driver"
20 depends on NET 9 depends on HYPERV && NET
21 default HYPERV
22 help 10 help
23 Select this option to enable the Hyper-V virtual network driver. 11 Select this option to enable the Hyper-V virtual network driver.
24 12
25config HYPERV_UTILS
26 tristate "Microsoft Hyper-V Utilities driver"
27 depends on CONNECTOR && NLS
28 default HYPERV
29 help
30 Select this option to enable the Hyper-V Utilities.
31
32config HYPERV_MOUSE 13config HYPERV_MOUSE
33 tristate "Microsoft Hyper-V mouse driver" 14 tristate "Microsoft Hyper-V mouse driver"
34 depends on HID 15 depends on HYPERV && HID
35 default HYPERV
36 help 16 help
37 Select this option to enable the Hyper-V mouse driver. 17 Select this option to enable the Hyper-V mouse driver.
38
39endif
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 @@
1obj-$(CONFIG_HYPERV) += hv_vmbus.o hv_timesource.o 1obj-$(CONFIG_HYPERV) += hv_timesource.o
2obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o 2obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o
3obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o 3obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o
4obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o
5obj-$(CONFIG_HYPERV_MOUSE) += hv_mouse.o 4obj-$(CONFIG_HYPERV_MOUSE) += hv_mouse.o
6 5
7hv_vmbus-y := vmbus_drv.o \
8 hv.o connection.o channel.o \
9 channel_mgmt.o ring_buffer.o
10hv_storvsc-y := storvsc_drv.o 6hv_storvsc-y := storvsc_drv.o
11hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o 7hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o
12hv_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 @@
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/hid.h> 23#include <linux/hid.h>
24#include <linux/hiddev.h> 24#include <linux/hiddev.h>
25 25#include <linux/hyperv.h>
26#include "hyperv.h"
27 26
28 27
29struct hv_input_dev_info { 28struct 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 @@
1/*
2 *
3 * Copyright (c) 2011, Microsoft Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 * Authors:
19 * Haiyang Zhang <haiyangz@microsoft.com>
20 * Hank Janssen <hjanssen@microsoft.com>
21 * K. Y. Srinivasan <kys@microsoft.com>
22 *
23 */
24
25#ifndef _HYPERV_H
26#define _HYPERV_H
27
28#include <linux/scatterlist.h>
29#include <linux/list.h>
30#include <linux/uuid.h>
31#include <linux/timer.h>
32#include <linux/workqueue.h>
33#include <linux/completion.h>
34#include <linux/device.h>
35#include <linux/mod_devicetable.h>
36
37
38#include <asm/hyperv.h>
39
40
41#define MAX_PAGE_BUFFER_COUNT 16
42#define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */
43
44#pragma pack(push, 1)
45
46/* Single-page buffer */
47struct hv_page_buffer {
48 u32 len;
49 u32 offset;
50 u64 pfn;
51};
52
53/* Multiple-page buffer */
54struct hv_multipage_buffer {
55 /* Length and Offset determines the # of pfns in the array */
56 u32 len;
57 u32 offset;
58 u64 pfn_array[MAX_MULTIPAGE_BUFFER_COUNT];
59};
60
61/* 0x18 includes the proprietary packet header */
62#define MAX_PAGE_BUFFER_PACKET (0x18 + \
63 (sizeof(struct hv_page_buffer) * \
64 MAX_PAGE_BUFFER_COUNT))
65#define MAX_MULTIPAGE_BUFFER_PACKET (0x18 + \
66 sizeof(struct hv_multipage_buffer))
67
68
69#pragma pack(pop)
70
71struct hv_ring_buffer {
72 /* Offset in bytes from the start of ring data below */
73 u32 write_index;
74
75 /* Offset in bytes from the start of ring data below */
76 u32 read_index;
77
78 u32 interrupt_mask;
79
80 /* Pad it to PAGE_SIZE so that data starts on page boundary */
81 u8 reserved[4084];
82
83 /* NOTE:
84 * The interrupt_mask field is used only for channels but since our
85 * vmbus connection also uses this data structure and its data starts
86 * here, we commented out this field.
87 */
88
89 /*
90 * Ring data starts here + RingDataStartOffset
91 * !!! DO NOT place any fields below this !!!
92 */
93 u8 buffer[0];
94} __packed;
95
96struct hv_ring_buffer_info {
97 struct hv_ring_buffer *ring_buffer;
98 u32 ring_size; /* Include the shared header */
99 spinlock_t ring_lock;
100
101 u32 ring_datasize; /* < ring_size */
102 u32 ring_data_startoffset;
103};
104
105struct hv_ring_buffer_debug_info {
106 u32 current_interrupt_mask;
107 u32 current_read_index;
108 u32 current_write_index;
109 u32 bytes_avail_toread;
110 u32 bytes_avail_towrite;
111};
112
113/*
114 * We use the same version numbering for all Hyper-V modules.
115 *
116 * Definition of versioning is as follows;
117 *
118 * Major Number Changes for these scenarios;
119 * 1. When a new version of Windows Hyper-V
120 * is released.
121 * 2. A Major change has occurred in the
122 * Linux IC's.
123 * (For example the merge for the first time
124 * into the kernel) Every time the Major Number
125 * changes, the Revision number is reset to 0.
126 * Minor Number Changes when new functionality is added
127 * to the Linux IC's that is not a bug fix.
128 *
129 * 3.1 - Added completed hv_utils driver. Shutdown/Heartbeat/Timesync
130 */
131#define HV_DRV_VERSION "3.1"
132
133
134/*
135 * A revision number of vmbus that is used for ensuring both ends on a
136 * partition are using compatible versions.
137 */
138#define VMBUS_REVISION_NUMBER 13
139
140/* Make maximum size of pipe payload of 16K */
141#define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384)
142
143/* Define PipeMode values. */
144#define VMBUS_PIPE_TYPE_BYTE 0x00000000
145#define VMBUS_PIPE_TYPE_MESSAGE 0x00000004
146
147/* The size of the user defined data buffer for non-pipe offers. */
148#define MAX_USER_DEFINED_BYTES 120
149
150/* The size of the user defined data buffer for pipe offers. */
151#define MAX_PIPE_USER_DEFINED_BYTES 116
152
153/*
154 * At the center of the Channel Management library is the Channel Offer. This
155 * struct contains the fundamental information about an offer.
156 */
157struct vmbus_channel_offer {
158 uuid_le if_type;
159 uuid_le if_instance;
160 u64 int_latency; /* in 100ns units */
161 u32 if_revision;
162 u32 server_ctx_size; /* in bytes */
163 u16 chn_flags;
164 u16 mmio_megabytes; /* in bytes * 1024 * 1024 */
165
166 union {
167 /* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */
168 struct {
169 unsigned char user_def[MAX_USER_DEFINED_BYTES];
170 } std;
171
172 /*
173 * Pipes:
174 * The following sructure is an integrated pipe protocol, which
175 * is implemented on top of standard user-defined data. Pipe
176 * clients have MAX_PIPE_USER_DEFINED_BYTES left for their own
177 * use.
178 */
179 struct {
180 u32 pipe_mode;
181 unsigned char user_def[MAX_PIPE_USER_DEFINED_BYTES];
182 } pipe;
183 } u;
184 u32 padding;
185} __packed;
186
187/* Server Flags */
188#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE 1
189#define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES 2
190#define VMBUS_CHANNEL_SERVER_SUPPORTS_GPADLS 4
191#define VMBUS_CHANNEL_NAMED_PIPE_MODE 0x10
192#define VMBUS_CHANNEL_LOOPBACK_OFFER 0x100
193#define VMBUS_CHANNEL_PARENT_OFFER 0x200
194#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION 0x400
195
196struct vmpacket_descriptor {
197 u16 type;
198 u16 offset8;
199 u16 len8;
200 u16 flags;
201 u64 trans_id;
202} __packed;
203
204struct vmpacket_header {
205 u32 prev_pkt_start_offset;
206 struct vmpacket_descriptor descriptor;
207} __packed;
208
209struct vmtransfer_page_range {
210 u32 byte_count;
211 u32 byte_offset;
212} __packed;
213
214struct vmtransfer_page_packet_header {
215 struct vmpacket_descriptor d;
216 u16 xfer_pageset_id;
217 bool sender_owns_set;
218 u8 reserved;
219 u32 range_cnt;
220 struct vmtransfer_page_range ranges[1];
221} __packed;
222
223struct vmgpadl_packet_header {
224 struct vmpacket_descriptor d;
225 u32 gpadl;
226 u32 reserved;
227} __packed;
228
229struct vmadd_remove_transfer_page_set {
230 struct vmpacket_descriptor d;
231 u32 gpadl;
232 u16 xfer_pageset_id;
233 u16 reserved;
234} __packed;
235
236/*
237 * This structure defines a range in guest physical space that can be made to
238 * look virtually contiguous.
239 */
240struct gpa_range {
241 u32 byte_count;
242 u32 byte_offset;
243 u64 pfn_array[0];
244};
245
246/*
247 * This is the format for an Establish Gpadl packet, which contains a handle by
248 * which this GPADL will be known and a set of GPA ranges associated with it.
249 * This can be converted to a MDL by the guest OS. If there are multiple GPA
250 * ranges, then the resulting MDL will be "chained," representing multiple VA
251 * ranges.
252 */
253struct vmestablish_gpadl {
254 struct vmpacket_descriptor d;
255 u32 gpadl;
256 u32 range_cnt;
257 struct gpa_range range[1];
258} __packed;
259
260/*
261 * This is the format for a Teardown Gpadl packet, which indicates that the
262 * GPADL handle in the Establish Gpadl packet will never be referenced again.
263 */
264struct vmteardown_gpadl {
265 struct vmpacket_descriptor d;
266 u32 gpadl;
267 u32 reserved; /* for alignment to a 8-byte boundary */
268} __packed;
269
270/*
271 * This is the format for a GPA-Direct packet, which contains a set of GPA
272 * ranges, in addition to commands and/or data.
273 */
274struct vmdata_gpa_direct {
275 struct vmpacket_descriptor d;
276 u32 reserved;
277 u32 range_cnt;
278 struct gpa_range range[1];
279} __packed;
280
281/* This is the format for a Additional Data Packet. */
282struct vmadditional_data {
283 struct vmpacket_descriptor d;
284 u64 total_bytes;
285 u32 offset;
286 u32 byte_cnt;
287 unsigned char data[1];
288} __packed;
289
290union vmpacket_largest_possible_header {
291 struct vmpacket_descriptor simple_hdr;
292 struct vmtransfer_page_packet_header xfer_page_hdr;
293 struct vmgpadl_packet_header gpadl_hdr;
294 struct vmadd_remove_transfer_page_set add_rm_xfer_page_hdr;
295 struct vmestablish_gpadl establish_gpadl_hdr;
296 struct vmteardown_gpadl teardown_gpadl_hdr;
297 struct vmdata_gpa_direct data_gpa_direct_hdr;
298};
299
300#define VMPACKET_DATA_START_ADDRESS(__packet) \
301 (void *)(((unsigned char *)__packet) + \
302 ((struct vmpacket_descriptor)__packet)->offset8 * 8)
303
304#define VMPACKET_DATA_LENGTH(__packet) \
305 ((((struct vmpacket_descriptor)__packet)->len8 - \
306 ((struct vmpacket_descriptor)__packet)->offset8) * 8)
307
308#define VMPACKET_TRANSFER_MODE(__packet) \
309 (((struct IMPACT)__packet)->type)
310
311enum vmbus_packet_type {
312 VM_PKT_INVALID = 0x0,
313 VM_PKT_SYNCH = 0x1,
314 VM_PKT_ADD_XFER_PAGESET = 0x2,
315 VM_PKT_RM_XFER_PAGESET = 0x3,
316 VM_PKT_ESTABLISH_GPADL = 0x4,
317 VM_PKT_TEARDOWN_GPADL = 0x5,
318 VM_PKT_DATA_INBAND = 0x6,
319 VM_PKT_DATA_USING_XFER_PAGES = 0x7,
320 VM_PKT_DATA_USING_GPADL = 0x8,
321 VM_PKT_DATA_USING_GPA_DIRECT = 0x9,
322 VM_PKT_CANCEL_REQUEST = 0xa,
323 VM_PKT_COMP = 0xb,
324 VM_PKT_DATA_USING_ADDITIONAL_PKT = 0xc,
325 VM_PKT_ADDITIONAL_DATA = 0xd
326};
327
328#define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1
329
330
331/* Version 1 messages */
332enum vmbus_channel_message_type {
333 CHANNELMSG_INVALID = 0,
334 CHANNELMSG_OFFERCHANNEL = 1,
335 CHANNELMSG_RESCIND_CHANNELOFFER = 2,
336 CHANNELMSG_REQUESTOFFERS = 3,
337 CHANNELMSG_ALLOFFERS_DELIVERED = 4,
338 CHANNELMSG_OPENCHANNEL = 5,
339 CHANNELMSG_OPENCHANNEL_RESULT = 6,
340 CHANNELMSG_CLOSECHANNEL = 7,
341 CHANNELMSG_GPADL_HEADER = 8,
342 CHANNELMSG_GPADL_BODY = 9,
343 CHANNELMSG_GPADL_CREATED = 10,
344 CHANNELMSG_GPADL_TEARDOWN = 11,
345 CHANNELMSG_GPADL_TORNDOWN = 12,
346 CHANNELMSG_RELID_RELEASED = 13,
347 CHANNELMSG_INITIATE_CONTACT = 14,
348 CHANNELMSG_VERSION_RESPONSE = 15,
349 CHANNELMSG_UNLOAD = 16,
350#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
351 CHANNELMSG_VIEWRANGE_ADD = 17,
352 CHANNELMSG_VIEWRANGE_REMOVE = 18,
353#endif
354 CHANNELMSG_COUNT
355};
356
357struct vmbus_channel_message_header {
358 enum vmbus_channel_message_type msgtype;
359 u32 padding;
360} __packed;
361
362/* Query VMBus Version parameters */
363struct vmbus_channel_query_vmbus_version {
364 struct vmbus_channel_message_header header;
365 u32 version;
366} __packed;
367
368/* VMBus Version Supported parameters */
369struct vmbus_channel_version_supported {
370 struct vmbus_channel_message_header header;
371 bool version_supported;
372} __packed;
373
374/* Offer Channel parameters */
375struct vmbus_channel_offer_channel {
376 struct vmbus_channel_message_header header;
377 struct vmbus_channel_offer offer;
378 u32 child_relid;
379 u8 monitorid;
380 bool monitor_allocated;
381} __packed;
382
383/* Rescind Offer parameters */
384struct vmbus_channel_rescind_offer {
385 struct vmbus_channel_message_header header;
386 u32 child_relid;
387} __packed;
388
389/*
390 * Request Offer -- no parameters, SynIC message contains the partition ID
391 * Set Snoop -- no parameters, SynIC message contains the partition ID
392 * Clear Snoop -- no parameters, SynIC message contains the partition ID
393 * All Offers Delivered -- no parameters, SynIC message contains the partition
394 * ID
395 * Flush Client -- no parameters, SynIC message contains the partition ID
396 */
397
398/* Open Channel parameters */
399struct vmbus_channel_open_channel {
400 struct vmbus_channel_message_header header;
401
402 /* Identifies the specific VMBus channel that is being opened. */
403 u32 child_relid;
404
405 /* ID making a particular open request at a channel offer unique. */
406 u32 openid;
407
408 /* GPADL for the channel's ring buffer. */
409 u32 ringbuffer_gpadlhandle;
410
411 /* GPADL for the channel's server context save area. */
412 u32 server_contextarea_gpadlhandle;
413
414 /*
415 * The upstream ring buffer begins at offset zero in the memory
416 * described by RingBufferGpadlHandle. The downstream ring buffer
417 * follows it at this offset (in pages).
418 */
419 u32 downstream_ringbuffer_pageoffset;
420
421 /* User-specific data to be passed along to the server endpoint. */
422 unsigned char userdata[MAX_USER_DEFINED_BYTES];
423} __packed;
424
425/* Open Channel Result parameters */
426struct vmbus_channel_open_result {
427 struct vmbus_channel_message_header header;
428 u32 child_relid;
429 u32 openid;
430 u32 status;
431} __packed;
432
433/* Close channel parameters; */
434struct vmbus_channel_close_channel {
435 struct vmbus_channel_message_header header;
436 u32 child_relid;
437} __packed;
438
439/* Channel Message GPADL */
440#define GPADL_TYPE_RING_BUFFER 1
441#define GPADL_TYPE_SERVER_SAVE_AREA 2
442#define GPADL_TYPE_TRANSACTION 8
443
444/*
445 * The number of PFNs in a GPADL message is defined by the number of
446 * pages that would be spanned by ByteCount and ByteOffset. If the
447 * implied number of PFNs won't fit in this packet, there will be a
448 * follow-up packet that contains more.
449 */
450struct vmbus_channel_gpadl_header {
451 struct vmbus_channel_message_header header;
452 u32 child_relid;
453 u32 gpadl;
454 u16 range_buflen;
455 u16 rangecount;
456 struct gpa_range range[0];
457} __packed;
458
459/* This is the followup packet that contains more PFNs. */
460struct vmbus_channel_gpadl_body {
461 struct vmbus_channel_message_header header;
462 u32 msgnumber;
463 u32 gpadl;
464 u64 pfn[0];
465} __packed;
466
467struct vmbus_channel_gpadl_created {
468 struct vmbus_channel_message_header header;
469 u32 child_relid;
470 u32 gpadl;
471 u32 creation_status;
472} __packed;
473
474struct vmbus_channel_gpadl_teardown {
475 struct vmbus_channel_message_header header;
476 u32 child_relid;
477 u32 gpadl;
478} __packed;
479
480struct vmbus_channel_gpadl_torndown {
481 struct vmbus_channel_message_header header;
482 u32 gpadl;
483} __packed;
484
485#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
486struct vmbus_channel_view_range_add {
487 struct vmbus_channel_message_header header;
488 PHYSICAL_ADDRESS viewrange_base;
489 u64 viewrange_length;
490 u32 child_relid;
491} __packed;
492
493struct vmbus_channel_view_range_remove {
494 struct vmbus_channel_message_header header;
495 PHYSICAL_ADDRESS viewrange_base;
496 u32 child_relid;
497} __packed;
498#endif
499
500struct vmbus_channel_relid_released {
501 struct vmbus_channel_message_header header;
502 u32 child_relid;
503} __packed;
504
505struct vmbus_channel_initiate_contact {
506 struct vmbus_channel_message_header header;
507 u32 vmbus_version_requested;
508 u32 padding2;
509 u64 interrupt_page;
510 u64 monitor_page1;
511 u64 monitor_page2;
512} __packed;
513
514struct vmbus_channel_version_response {
515 struct vmbus_channel_message_header header;
516 bool version_supported;
517} __packed;
518
519enum vmbus_channel_state {
520 CHANNEL_OFFER_STATE,
521 CHANNEL_OPENING_STATE,
522 CHANNEL_OPEN_STATE,
523};
524
525struct vmbus_channel_debug_info {
526 u32 relid;
527 enum vmbus_channel_state state;
528 uuid_le interfacetype;
529 uuid_le interface_instance;
530 u32 monitorid;
531 u32 servermonitor_pending;
532 u32 servermonitor_latency;
533 u32 servermonitor_connectionid;
534 u32 clientmonitor_pending;
535 u32 clientmonitor_latency;
536 u32 clientmonitor_connectionid;
537
538 struct hv_ring_buffer_debug_info inbound;
539 struct hv_ring_buffer_debug_info outbound;
540};
541
542/*
543 * Represents each channel msg on the vmbus connection This is a
544 * variable-size data structure depending on the msg type itself
545 */
546struct vmbus_channel_msginfo {
547 /* Bookkeeping stuff */
548 struct list_head msglistentry;
549
550 /* So far, this is only used to handle gpadl body message */
551 struct list_head submsglist;
552
553 /* Synchronize the request/response if needed */
554 struct completion waitevent;
555 union {
556 struct vmbus_channel_version_supported version_supported;
557 struct vmbus_channel_open_result open_result;
558 struct vmbus_channel_gpadl_torndown gpadl_torndown;
559 struct vmbus_channel_gpadl_created gpadl_created;
560 struct vmbus_channel_version_response version_response;
561 } response;
562
563 u32 msgsize;
564 /*
565 * The channel message that goes out on the "wire".
566 * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header
567 */
568 unsigned char msg[0];
569};
570
571struct vmbus_close_msg {
572 struct vmbus_channel_msginfo info;
573 struct vmbus_channel_close_channel msg;
574};
575
576struct vmbus_channel {
577 struct list_head listentry;
578
579 struct hv_device *device_obj;
580
581 struct work_struct work;
582
583 enum vmbus_channel_state state;
584
585 struct vmbus_channel_offer_channel offermsg;
586 /*
587 * These are based on the OfferMsg.MonitorId.
588 * Save it here for easy access.
589 */
590 u8 monitor_grp;
591 u8 monitor_bit;
592
593 u32 ringbuffer_gpadlhandle;
594
595 /* Allocated memory for ring buffer */
596 void *ringbuffer_pages;
597 u32 ringbuffer_pagecount;
598 struct hv_ring_buffer_info outbound; /* send to parent */
599 struct hv_ring_buffer_info inbound; /* receive from parent */
600 spinlock_t inbound_lock;
601 struct workqueue_struct *controlwq;
602
603 struct vmbus_close_msg close_msg;
604
605 /* Channel callback are invoked in this workqueue context */
606 /* HANDLE dataWorkQueue; */
607
608 void (*onchannel_callback)(void *context);
609 void *channel_callback_context;
610};
611
612void free_channel(struct vmbus_channel *channel);
613
614void vmbus_onmessage(void *context);
615
616int vmbus_request_offers(void);
617
618/* The format must be the same as struct vmdata_gpa_direct */
619struct vmbus_channel_packet_page_buffer {
620 u16 type;
621 u16 dataoffset8;
622 u16 length8;
623 u16 flags;
624 u64 transactionid;
625 u32 reserved;
626 u32 rangecount;
627 struct hv_page_buffer range[MAX_PAGE_BUFFER_COUNT];
628} __packed;
629
630/* The format must be the same as struct vmdata_gpa_direct */
631struct vmbus_channel_packet_multipage_buffer {
632 u16 type;
633 u16 dataoffset8;
634 u16 length8;
635 u16 flags;
636 u64 transactionid;
637 u32 reserved;
638 u32 rangecount; /* Always 1 in this case */
639 struct hv_multipage_buffer range;
640} __packed;
641
642
643extern int vmbus_open(struct vmbus_channel *channel,
644 u32 send_ringbuffersize,
645 u32 recv_ringbuffersize,
646 void *userdata,
647 u32 userdatalen,
648 void(*onchannel_callback)(void *context),
649 void *context);
650
651extern void vmbus_close(struct vmbus_channel *channel);
652
653extern int vmbus_sendpacket(struct vmbus_channel *channel,
654 const void *buffer,
655 u32 bufferLen,
656 u64 requestid,
657 enum vmbus_packet_type type,
658 u32 flags);
659
660extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
661 struct hv_page_buffer pagebuffers[],
662 u32 pagecount,
663 void *buffer,
664 u32 bufferlen,
665 u64 requestid);
666
667extern int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
668 struct hv_multipage_buffer *mpb,
669 void *buffer,
670 u32 bufferlen,
671 u64 requestid);
672
673extern int vmbus_establish_gpadl(struct vmbus_channel *channel,
674 void *kbuffer,
675 u32 size,
676 u32 *gpadl_handle);
677
678extern int vmbus_teardown_gpadl(struct vmbus_channel *channel,
679 u32 gpadl_handle);
680
681extern int vmbus_recvpacket(struct vmbus_channel *channel,
682 void *buffer,
683 u32 bufferlen,
684 u32 *buffer_actual_len,
685 u64 *requestid);
686
687extern int vmbus_recvpacket_raw(struct vmbus_channel *channel,
688 void *buffer,
689 u32 bufferlen,
690 u32 *buffer_actual_len,
691 u64 *requestid);
692
693
694extern void vmbus_get_debug_info(struct vmbus_channel *channel,
695 struct vmbus_channel_debug_info *debug);
696
697extern void vmbus_ontimer(unsigned long data);
698
699
700#define LOWORD(dw) ((unsigned short)(dw))
701#define HIWORD(dw) ((unsigned short)(((unsigned int) (dw) >> 16) & 0xFFFF))
702
703
704#define VMBUS 0x0001
705#define STORVSC 0x0002
706#define NETVSC 0x0004
707#define INPUTVSC 0x0008
708#define BLKVSC 0x0010
709#define VMBUS_DRV 0x0100
710#define STORVSC_DRV 0x0200
711#define NETVSC_DRV 0x0400
712#define INPUTVSC_DRV 0x0800
713#define BLKVSC_DRV 0x1000
714
715#define ALL_MODULES (VMBUS |\
716 STORVSC |\
717 NETVSC |\
718 INPUTVSC |\
719 BLKVSC |\
720 VMBUS_DRV |\
721 STORVSC_DRV |\
722 NETVSC_DRV |\
723 INPUTVSC_DRV|\
724 BLKVSC_DRV)
725
726/* Logging Level */
727#define ERROR_LVL 3
728#define WARNING_LVL 4
729#define INFO_LVL 6
730#define DEBUG_LVL 7
731#define DEBUG_LVL_ENTEREXIT 8
732#define DEBUG_RING_LVL 9
733
734extern unsigned int vmbus_loglevel;
735
736#define DPRINT(mod, lvl, fmt, args...) do {\
737 if ((mod & (HIWORD(vmbus_loglevel))) && \
738 (lvl <= LOWORD(vmbus_loglevel))) \
739 printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\
740 } while (0)
741
742#define DPRINT_DBG(mod, fmt, args...) do {\
743 if ((mod & (HIWORD(vmbus_loglevel))) && \
744 (DEBUG_LVL <= LOWORD(vmbus_loglevel))) \
745 printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\
746 } while (0)
747
748#define DPRINT_INFO(mod, fmt, args...) do {\
749 if ((mod & (HIWORD(vmbus_loglevel))) && \
750 (INFO_LVL <= LOWORD(vmbus_loglevel))) \
751 printk(KERN_INFO #mod": " fmt "\n", ## args);\
752 } while (0)
753
754#define DPRINT_WARN(mod, fmt, args...) do {\
755 if ((mod & (HIWORD(vmbus_loglevel))) && \
756 (WARNING_LVL <= LOWORD(vmbus_loglevel))) \
757 printk(KERN_WARNING #mod": WARNING! " fmt "\n", ## args);\
758 } while (0)
759
760#define DPRINT_ERR(mod, fmt, args...) do {\
761 if ((mod & (HIWORD(vmbus_loglevel))) && \
762 (ERROR_LVL <= LOWORD(vmbus_loglevel))) \
763 printk(KERN_ERR #mod": %s() ERROR!! " fmt "\n", \
764 __func__, ## args);\
765 } while (0)
766
767
768
769struct hv_driver;
770struct hv_device;
771
772struct hv_dev_port_info {
773 u32 int_mask;
774 u32 read_idx;
775 u32 write_idx;
776 u32 bytes_avail_toread;
777 u32 bytes_avail_towrite;
778};
779
780struct hv_device_info {
781 u32 chn_id;
782 u32 chn_state;
783 uuid_le chn_type;
784 uuid_le chn_instance;
785
786 u32 monitor_id;
787 u32 server_monitor_pending;
788 u32 server_monitor_latency;
789 u32 server_monitor_conn_id;
790 u32 client_monitor_pending;
791 u32 client_monitor_latency;
792 u32 client_monitor_conn_id;
793
794 struct hv_dev_port_info inbound;
795 struct hv_dev_port_info outbound;
796};
797
798/* Base driver object */
799struct hv_driver {
800 const char *name;
801
802 /* the device type supported by this driver */
803 uuid_le dev_type;
804 const struct hv_vmbus_device_id *id_table;
805
806 struct device_driver driver;
807
808 int (*probe)(struct hv_device *, const struct hv_vmbus_device_id *);
809 int (*remove)(struct hv_device *);
810 void (*shutdown)(struct hv_device *);
811
812};
813
814/* Base device object */
815struct hv_device {
816 /* the device type id of this device */
817 uuid_le dev_type;
818
819 /* the device instance id of this device */
820 uuid_le dev_instance;
821
822 struct device device;
823
824 struct vmbus_channel *channel;
825};
826
827
828static inline struct hv_device *device_to_hv_device(struct device *d)
829{
830 return container_of(d, struct hv_device, device);
831}
832
833static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d)
834{
835 return container_of(d, struct hv_driver, driver);
836}
837
838static inline void hv_set_drvdata(struct hv_device *dev, void *data)
839{
840 dev_set_drvdata(&dev->device, data);
841}
842
843static inline void *hv_get_drvdata(struct hv_device *dev)
844{
845 return dev_get_drvdata(&dev->device);
846}
847
848/* Vmbus interface */
849#define vmbus_driver_register(driver) \
850 __vmbus_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
851int __must_check __vmbus_driver_register(struct hv_driver *hv_driver,
852 struct module *owner,
853 const char *mod_name);
854void vmbus_driver_unregister(struct hv_driver *hv_driver);
855
856/**
857 * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
858 *
859 * This macro is used to create a struct hv_vmbus_device_id that matches a
860 * specific device.
861 */
862#define VMBUS_DEVICE(g0, g1, g2, g3, g4, g5, g6, g7, \
863 g8, g9, ga, gb, gc, gd, ge, gf) \
864 .guid = { g0, g1, g2, g3, g4, g5, g6, g7, \
865 g8, g9, ga, gb, gc, gd, ge, gf },
866
867/*
868 * Common header for Hyper-V ICs
869 */
870
871#define ICMSGTYPE_NEGOTIATE 0
872#define ICMSGTYPE_HEARTBEAT 1
873#define ICMSGTYPE_KVPEXCHANGE 2
874#define ICMSGTYPE_SHUTDOWN 3
875#define ICMSGTYPE_TIMESYNC 4
876#define ICMSGTYPE_VSS 5
877
878#define ICMSGHDRFLAG_TRANSACTION 1
879#define ICMSGHDRFLAG_REQUEST 2
880#define ICMSGHDRFLAG_RESPONSE 4
881
882#define HV_S_OK 0x00000000
883#define HV_E_FAIL 0x80004005
884#define HV_ERROR_NOT_SUPPORTED 0x80070032
885#define HV_ERROR_MACHINE_LOCKED 0x800704F7
886
887/*
888 * While we want to handle util services as regular devices,
889 * there is only one instance of each of these services; so
890 * we statically allocate the service specific state.
891 */
892
893struct hv_util_service {
894 u8 *recv_buffer;
895 void (*util_cb)(void *);
896 int (*util_init)(struct hv_util_service *);
897 void (*util_deinit)(void);
898};
899
900struct vmbuspipe_hdr {
901 u32 flags;
902 u32 msgsize;
903} __packed;
904
905struct ic_version {
906 u16 major;
907 u16 minor;
908} __packed;
909
910struct icmsg_hdr {
911 struct ic_version icverframe;
912 u16 icmsgtype;
913 struct ic_version icvermsg;
914 u16 icmsgsize;
915 u32 status;
916 u8 ictransaction_id;
917 u8 icflags;
918 u8 reserved[2];
919} __packed;
920
921struct icmsg_negotiate {
922 u16 icframe_vercnt;
923 u16 icmsg_vercnt;
924 u32 reserved;
925 struct ic_version icversion_data[1]; /* any size array */
926} __packed;
927
928struct shutdown_msg_data {
929 u32 reason_code;
930 u32 timeout_seconds;
931 u32 flags;
932 u8 display_message[2048];
933} __packed;
934
935struct heartbeat_msg_data {
936 u64 seq_num;
937 u32 reserved[8];
938} __packed;
939
940/* Time Sync IC defs */
941#define ICTIMESYNCFLAG_PROBE 0
942#define ICTIMESYNCFLAG_SYNC 1
943#define ICTIMESYNCFLAG_SAMPLE 2
944
945#ifdef __x86_64__
946#define WLTIMEDELTA 116444736000000000L /* in 100ns unit */
947#else
948#define WLTIMEDELTA 116444736000000000LL
949#endif
950
951struct ictimesync_data {
952 u64 parenttime;
953 u64 childtime;
954 u64 roundtriptime;
955 u8 flags;
956} __packed;
957
958struct hyperv_service_callback {
959 u8 msg_type;
960 char *log_msg;
961 uuid_le data;
962 struct vmbus_channel *channel;
963 void (*callback) (void *context);
964};
965
966extern void prep_negotiate_resp(struct icmsg_hdr *,
967 struct icmsg_negotiate *, u8 *);
968
969#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 @@
26#define _HYPERV_NET_H 26#define _HYPERV_NET_H
27 27
28#include <linux/list.h> 28#include <linux/list.h>
29#include "hyperv.h" 29#include <linux/hyperv.h>
30 30
31/* Fwd declaration */ 31/* Fwd declaration */
32struct hv_netvsc_packet; 32struct 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 @@
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/hyperv.h>
34#include <scsi/scsi.h> 35#include <scsi/scsi.h>
35#include <scsi/scsi_cmnd.h> 36#include <scsi/scsi_cmnd.h>
36#include <scsi/scsi_host.h> 37#include <scsi/scsi_host.h>
@@ -40,7 +41,6 @@
40#include <scsi/scsi_devinfo.h> 41#include <scsi/scsi_devinfo.h>
41#include <scsi/scsi_dbg.h> 42#include <scsi/scsi_dbg.h>
42 43
43#include "hyperv.h"
44 44
45#define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) 45#define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE)
46static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE; 46static 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 @@
1/*
2 * An implementation of key value pair (KVP) functionality for Linux.
3 *
4 *
5 * Copyright (C) 2010, Novell, Inc.
6 * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24
25#include <sys/types.h>
26#include <sys/socket.h>
27#include <sys/poll.h>
28#include <sys/utsname.h>
29#include <linux/types.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <unistd.h>
33#include <string.h>
34#include <errno.h>
35#include <arpa/inet.h>
36#include <linux/connector.h>
37#include <linux/netlink.h>
38#include <ifaddrs.h>
39#include <netdb.h>
40#include <syslog.h>
41
42/*
43 * KYS: TODO. Need to register these in the kernel.
44 *
45 * The following definitions are shared with the in-kernel component; do not
46 * change any of this without making the corresponding changes in
47 * the KVP kernel component.
48 */
49#define CN_KVP_IDX 0x9 /* MSFT KVP functionality */
50#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */
51#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */
52
53/*
54 * KVP protocol: The user mode component first registers with the
55 * the kernel component. Subsequently, the kernel component requests, data
56 * for the specified keys. In response to this message the user mode component
57 * fills in the value corresponding to the specified key. We overload the
58 * sequence field in the cn_msg header to define our KVP message types.
59 *
60 * We use this infrastructure for also supporting queries from user mode
61 * application for state that may be maintained in the KVP kernel component.
62 *
63 * XXXKYS: Have a shared header file between the user and kernel (TODO)
64 */
65
66enum kvp_op {
67 KVP_REGISTER = 0, /* Register the user mode component*/
68 KVP_KERNEL_GET, /*Kernel is requesting the value for the specified key*/
69 KVP_KERNEL_SET, /*Kernel is providing the value for the specified key*/
70 KVP_USER_GET, /*User is requesting the value for the specified key*/
71 KVP_USER_SET /*User is providing the value for the specified key*/
72};
73
74#define HV_KVP_EXCHANGE_MAX_KEY_SIZE 512
75#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE 2048
76
77struct hv_ku_msg {
78 __u32 kvp_index;
79 __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */
80 __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */
81};
82
83enum key_index {
84 FullyQualifiedDomainName = 0,
85 IntegrationServicesVersion, /*This key is serviced in the kernel*/
86 NetworkAddressIPv4,
87 NetworkAddressIPv6,
88 OSBuildNumber,
89 OSName,
90 OSMajorVersion,
91 OSMinorVersion,
92 OSVersion,
93 ProcessorArchitecture
94};
95
96/*
97 * End of shared definitions.
98 */
99
100static char kvp_send_buffer[4096];
101static char kvp_recv_buffer[4096];
102static struct sockaddr_nl addr;
103
104static char *os_name = "";
105static char *os_major = "";
106static char *os_minor = "";
107static char *processor_arch;
108static char *os_build;
109static char *lic_version;
110static struct utsname uts_buf;
111
112void kvp_get_os_info(void)
113{
114 FILE *file;
115 char *p, buf[512];
116
117 uname(&uts_buf);
118 os_build = uts_buf.release;
119 processor_arch = uts_buf.machine;
120
121 /*
122 * The current windows host (win7) expects the build
123 * string to be of the form: x.y.z
124 * Strip additional information we may have.
125 */
126 p = strchr(os_build, '-');
127 if (p)
128 *p = '\0';
129
130 file = fopen("/etc/SuSE-release", "r");
131 if (file != NULL)
132 goto kvp_osinfo_found;
133 file = fopen("/etc/redhat-release", "r");
134 if (file != NULL)
135 goto kvp_osinfo_found;
136 /*
137 * Add code for other supported platforms.
138 */
139
140 /*
141 * We don't have information about the os.
142 */
143 os_name = uts_buf.sysname;
144 return;
145
146kvp_osinfo_found:
147 /* up to three lines */
148 p = fgets(buf, sizeof(buf), file);
149 if (p) {
150 p = strchr(buf, '\n');
151 if (p)
152 *p = '\0';
153 p = strdup(buf);
154 if (!p)
155 goto done;
156 os_name = p;
157
158 /* second line */
159 p = fgets(buf, sizeof(buf), file);
160 if (p) {
161 p = strchr(buf, '\n');
162 if (p)
163 *p = '\0';
164 p = strdup(buf);
165 if (!p)
166 goto done;
167 os_major = p;
168
169 /* third line */
170 p = fgets(buf, sizeof(buf), file);
171 if (p) {
172 p = strchr(buf, '\n');
173 if (p)
174 *p = '\0';
175 p = strdup(buf);
176 if (p)
177 os_minor = p;
178 }
179 }
180 }
181
182done:
183 fclose(file);
184 return;
185}
186
187static int
188kvp_get_ip_address(int family, char *buffer, int length)
189{
190 struct ifaddrs *ifap;
191 struct ifaddrs *curp;
192 int ipv4_len = strlen("255.255.255.255") + 1;
193 int ipv6_len = strlen("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")+1;
194 int offset = 0;
195 const char *str;
196 char tmp[50];
197 int error = 0;
198
199 /*
200 * On entry into this function, the buffer is capable of holding the
201 * maximum key value (2048 bytes).
202 */
203
204 if (getifaddrs(&ifap)) {
205 strcpy(buffer, "getifaddrs failed\n");
206 return 1;
207 }
208
209 curp = ifap;
210 while (curp != NULL) {
211 if ((curp->ifa_addr != NULL) &&
212 (curp->ifa_addr->sa_family == family)) {
213 if (family == AF_INET) {
214 struct sockaddr_in *addr =
215 (struct sockaddr_in *) curp->ifa_addr;
216
217 str = inet_ntop(family, &addr->sin_addr,
218 tmp, 50);
219 if (str == NULL) {
220 strcpy(buffer, "inet_ntop failed\n");
221 error = 1;
222 goto getaddr_done;
223 }
224 if (offset == 0)
225 strcpy(buffer, tmp);
226 else
227 strcat(buffer, tmp);
228 strcat(buffer, ";");
229
230 offset += strlen(str) + 1;
231 if ((length - offset) < (ipv4_len + 1))
232 goto getaddr_done;
233
234 } else {
235
236 /*
237 * We only support AF_INET and AF_INET6
238 * and the list of addresses is separated by a ";".
239 */
240 struct sockaddr_in6 *addr =
241 (struct sockaddr_in6 *) curp->ifa_addr;
242
243 str = inet_ntop(family,
244 &addr->sin6_addr.s6_addr,
245 tmp, 50);
246 if (str == NULL) {
247 strcpy(buffer, "inet_ntop failed\n");
248 error = 1;
249 goto getaddr_done;
250 }
251 if (offset == 0)
252 strcpy(buffer, tmp);
253 else
254 strcat(buffer, tmp);
255 strcat(buffer, ";");
256 offset += strlen(str) + 1;
257 if ((length - offset) < (ipv6_len + 1))
258 goto getaddr_done;
259
260 }
261
262 }
263 curp = curp->ifa_next;
264 }
265
266getaddr_done:
267 freeifaddrs(ifap);
268 return error;
269}
270
271
272static int
273kvp_get_domain_name(char *buffer, int length)
274{
275 struct addrinfo hints, *info ;
276 int error = 0;
277
278 gethostname(buffer, length);
279 memset(&hints, 0, sizeof(hints));
280 hints.ai_family = AF_INET; /*Get only ipv4 addrinfo. */
281 hints.ai_socktype = SOCK_STREAM;
282 hints.ai_flags = AI_CANONNAME;
283
284 error = getaddrinfo(buffer, NULL, &hints, &info);
285 if (error != 0) {
286 strcpy(buffer, "getaddrinfo failed\n");
287 return error;
288 }
289 strcpy(buffer, info->ai_canonname);
290 freeaddrinfo(info);
291 return error;
292}
293
294static int
295netlink_send(int fd, struct cn_msg *msg)
296{
297 struct nlmsghdr *nlh;
298 unsigned int size;
299 struct msghdr message;
300 char buffer[64];
301 struct iovec iov[2];
302
303 size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
304
305 nlh = (struct nlmsghdr *)buffer;
306 nlh->nlmsg_seq = 0;
307 nlh->nlmsg_pid = getpid();
308 nlh->nlmsg_type = NLMSG_DONE;
309 nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
310 nlh->nlmsg_flags = 0;
311
312 iov[0].iov_base = nlh;
313 iov[0].iov_len = sizeof(*nlh);
314
315 iov[1].iov_base = msg;
316 iov[1].iov_len = size;
317
318 memset(&message, 0, sizeof(message));
319 message.msg_name = &addr;
320 message.msg_namelen = sizeof(addr);
321 message.msg_iov = iov;
322 message.msg_iovlen = 2;
323
324 return sendmsg(fd, &message, 0);
325}
326
327int main(void)
328{
329 int fd, len, sock_opt;
330 int error;
331 struct cn_msg *message;
332 struct pollfd pfd;
333 struct nlmsghdr *incoming_msg;
334 struct cn_msg *incoming_cn_msg;
335 struct hv_ku_msg *hv_msg;
336 char *p;
337 char *key_value;
338 char *key_name;
339
340 daemon(1, 0);
341 openlog("KVP", 0, LOG_USER);
342 syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
343 /*
344 * Retrieve OS release information.
345 */
346 kvp_get_os_info();
347
348 fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
349 if (fd < 0) {
350 syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd);
351 exit(-1);
352 }
353 addr.nl_family = AF_NETLINK;
354 addr.nl_pad = 0;
355 addr.nl_pid = 0;
356 addr.nl_groups = CN_KVP_IDX;
357
358
359 error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
360 if (error < 0) {
361 syslog(LOG_ERR, "bind failed; error:%d", error);
362 close(fd);
363 exit(-1);
364 }
365 sock_opt = addr.nl_groups;
366 setsockopt(fd, 270, 1, &sock_opt, sizeof(sock_opt));
367 /*
368 * Register ourselves with the kernel.
369 */
370 message = (struct cn_msg *)kvp_send_buffer;
371 message->id.idx = CN_KVP_IDX;
372 message->id.val = CN_KVP_VAL;
373 message->seq = KVP_REGISTER;
374 message->ack = 0;
375 message->len = 0;
376
377 len = netlink_send(fd, message);
378 if (len < 0) {
379 syslog(LOG_ERR, "netlink_send failed; error:%d", len);
380 close(fd);
381 exit(-1);
382 }
383
384 pfd.fd = fd;
385
386 while (1) {
387 pfd.events = POLLIN;
388 pfd.revents = 0;
389 poll(&pfd, 1, -1);
390
391 len = recv(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0);
392
393 if (len < 0) {
394 syslog(LOG_ERR, "recv failed; error:%d", len);
395 close(fd);
396 return -1;
397 }
398
399 incoming_msg = (struct nlmsghdr *)kvp_recv_buffer;
400 incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
401
402 switch (incoming_cn_msg->seq) {
403 case KVP_REGISTER:
404 /*
405 * Driver is registering with us; stash away the version
406 * information.
407 */
408 p = (char *)incoming_cn_msg->data;
409 lic_version = malloc(strlen(p) + 1);
410 if (lic_version) {
411 strcpy(lic_version, p);
412 syslog(LOG_INFO, "KVP LIC Version: %s",
413 lic_version);
414 } else {
415 syslog(LOG_ERR, "malloc failed");
416 }
417 continue;
418
419 case KVP_KERNEL_GET:
420 break;
421 default:
422 continue;
423 }
424
425 hv_msg = (struct hv_ku_msg *)incoming_cn_msg->data;
426 key_name = (char *)hv_msg->kvp_key;
427 key_value = (char *)hv_msg->kvp_value;
428
429 switch (hv_msg->kvp_index) {
430 case FullyQualifiedDomainName:
431 kvp_get_domain_name(key_value,
432 HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
433 strcpy(key_name, "FullyQualifiedDomainName");
434 break;
435 case IntegrationServicesVersion:
436 strcpy(key_name, "IntegrationServicesVersion");
437 strcpy(key_value, lic_version);
438 break;
439 case NetworkAddressIPv4:
440 kvp_get_ip_address(AF_INET, key_value,
441 HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
442 strcpy(key_name, "NetworkAddressIPv4");
443 break;
444 case NetworkAddressIPv6:
445 kvp_get_ip_address(AF_INET6, key_value,
446 HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
447 strcpy(key_name, "NetworkAddressIPv6");
448 break;
449 case OSBuildNumber:
450 strcpy(key_value, os_build);
451 strcpy(key_name, "OSBuildNumber");
452 break;
453 case OSName:
454 strcpy(key_value, os_name);
455 strcpy(key_name, "OSName");
456 break;
457 case OSMajorVersion:
458 strcpy(key_value, os_major);
459 strcpy(key_name, "OSMajorVersion");
460 break;
461 case OSMinorVersion:
462 strcpy(key_value, os_minor);
463 strcpy(key_name, "OSMinorVersion");
464 break;
465 case OSVersion:
466 strcpy(key_value, os_build);
467 strcpy(key_name, "OSVersion");
468 break;
469 case ProcessorArchitecture:
470 strcpy(key_value, processor_arch);
471 strcpy(key_name, "ProcessorArchitecture");
472 break;
473 default:
474 strcpy(key_value, "Unknown Key");
475 /*
476 * We use a null key name to terminate enumeration.
477 */
478 strcpy(key_name, "");
479 break;
480 }
481 /*
482 * Send the value back to the kernel. The response is
483 * already in the receive buffer. Update the cn_msg header to
484 * reflect the key value that has been added to the message
485 */
486
487 incoming_cn_msg->id.idx = CN_KVP_IDX;
488 incoming_cn_msg->id.val = CN_KVP_VAL;
489 incoming_cn_msg->seq = KVP_USER_SET;
490 incoming_cn_msg->ack = 0;
491 incoming_cn_msg->len = sizeof(struct hv_ku_msg);
492
493 len = netlink_send(fd, incoming_cn_msg);
494 if (len < 0) {
495 syslog(LOG_ERR, "net_link send failed; error:%d", len);
496 exit(-1);
497 }
498 }
499
500}