Blame view

drivers/hv/channel.c 25.7 KB
3e7ee4902   Hank Janssen   Staging: hv: add ...
1
  /*
3e7ee4902   Hank Janssen   Staging: hv: add ...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
   * Copyright (c) 2009, 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>
3e7ee4902   Hank Janssen   Staging: hv: add ...
20
   */
0a46618d5   Hank Janssen   staging: hv: Repl...
21
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5654e9322   Greg Kroah-Hartman   Staging: hv: remo...
22
  #include <linux/kernel.h>
0c3b7b2f7   K. Y. Srinivasan   Staging: hv: Use ...
23
24
  #include <linux/sched.h>
  #include <linux/wait.h>
a0086dc51   Greg Kroah-Hartman   Staging: hv: remo...
25
  #include <linux/mm.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
26
  #include <linux/slab.h>
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
27
  #include <linux/module.h>
46a971913   Greg Kroah-Hartman   Staging: hv: move...
28
  #include <linux/hyperv.h>
011a7c3cc   K. Y. Srinivasan   Drivers: hv: vmbu...
29
  #include <linux/uio.h>
63d55b2ae   Dexuan Cui   Drivers: hv: vmbu...
30
  #include <linux/interrupt.h>
3f335ea21   K. Y. Srinivasan   Staging: hv: Incl...
31

0f2a6619e   K. Y. Srinivasan   Staging: hv: vmbu...
32
  #include "hyperv_vmbus.h"
3e7ee4902   Hank Janssen   Staging: hv: add ...
33

e3fe0bb65   K. Y. Srinivasan   Staging: hv: Remo...
34
35
  #define NUM_PAGES_SPANNED(addr, len) \
  ((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - (addr >> PAGE_SHIFT))
3e1895195   Hank Janssen   staging: hv: Corr...
36
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
37
   * vmbus_setevent- Trigger an event notification on the specified
3e1895195   Hank Janssen   staging: hv: Corr...
38
   * channel.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
39
   */
e2fdf7841   K. Y. Srinivasan   Drivers: hv: vmbu...
40
  void vmbus_setevent(struct vmbus_channel *channel)
3e7ee4902   Hank Janssen   Staging: hv: add ...
41
  {
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
42
  	struct hv_monitor_page *monitorpage;
3e7ee4902   Hank Janssen   Staging: hv: add ...
43

3724287c0   K. Y. Srinivasan   Drivers: hv: vmbu...
44
45
46
47
48
49
  	/*
  	 * For channels marked as in "low latency" mode
  	 * bypass the monitor page mechanism.
  	 */
  	if ((channel->offermsg.monitor_allocated) &&
  	    (!channel->low_latency)) {
454f18a96   Bill Pemberton   Staging: hv: Remo...
50
  		/* Each u32 represents 32 channels */
223565857   Olaf Hering   staging: hv: use ...
51
  		sync_set_bit(channel->offermsg.child_relid & 31,
da9fcb726   Haiyang Zhang   staging: hv: Conv...
52
  			(unsigned long *) vmbus_connection.send_int_page +
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
53
  			(channel->offermsg.child_relid >> 5));
3e7ee4902   Hank Janssen   Staging: hv: add ...
54

8681db445   Greg Kroah-Hartman   hv: make "monitor...
55
56
  		/* Get the child to parent monitor page */
  		monitorpage = vmbus_connection.monitor_pages[1];
3e7ee4902   Hank Janssen   Staging: hv: add ...
57

223565857   Olaf Hering   staging: hv: use ...
58
  		sync_set_bit(channel->monitor_bit,
f6feebe07   Haiyang Zhang   staging: hv: Conv...
59
60
  			(unsigned long *)&monitorpage->trigger_group
  					[channel->monitor_grp].pending);
7c369f405   Bill Pemberton   Staging: hv: remo...
61

f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
62
  	} else {
21c3bef5d   K. Y. Srinivasan   Drivers: hv: Chan...
63
  		vmbus_set_event(channel);
3e7ee4902   Hank Janssen   Staging: hv: add ...
64
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
65
  }
e2fdf7841   K. Y. Srinivasan   Drivers: hv: vmbu...
66
  EXPORT_SYMBOL_GPL(vmbus_setevent);
3e7ee4902   Hank Janssen   Staging: hv: add ...
67

3e1895195   Hank Janssen   staging: hv: Corr...
68
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
69
   * vmbus_open - Open the specified channel.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
70
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
71
  int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
72
73
  		     u32 recv_ringbuffer_size, void *userdata, u32 userdatalen,
  		     void (*onchannelcallback)(void *context), void *context)
3e7ee4902   Hank Janssen   Staging: hv: add ...
74
  {
0987ff696   K. Y. Srinivasan   Staging: hv: vmbu...
75
  	struct vmbus_channel_open_channel *open_msg;
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
76
  	struct vmbus_channel_msginfo *open_info = NULL;
dd0813b6f   Greg Kroah-Hartman   Staging: hv: make...
77
  	unsigned long flags;
08a9513f7   Nicholas Mc Guire   hv: channel: matc...
78
  	int ret, err = 0;
294409d20   K. Y. Srinivasan   Drivers: hv: vmbu...
79
  	struct page *page;
3e7ee4902   Hank Janssen   Staging: hv: add ...
80

98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
81
82
83
  	if (send_ringbuffer_size % PAGE_SIZE ||
  	    recv_ringbuffer_size % PAGE_SIZE)
  		return -EINVAL;
67fae053b   Vitaly Kuznetsov   Drivers: hv: rena...
84
  	spin_lock_irqsave(&newchannel->lock, flags);
e68d2971d   K. Y. Srinivasan   Drivers: hv: vmbu...
85
86
87
  	if (newchannel->state == CHANNEL_OPEN_STATE) {
  		newchannel->state = CHANNEL_OPENING_STATE;
  	} else {
67fae053b   Vitaly Kuznetsov   Drivers: hv: rena...
88
  		spin_unlock_irqrestore(&newchannel->lock, flags);
e68d2971d   K. Y. Srinivasan   Drivers: hv: vmbu...
89
90
  		return -EINVAL;
  	}
67fae053b   Vitaly Kuznetsov   Drivers: hv: rena...
91
  	spin_unlock_irqrestore(&newchannel->lock, flags);
e68d2971d   K. Y. Srinivasan   Drivers: hv: vmbu...
92

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
93
94
  	newchannel->onchannel_callback = onchannelcallback;
  	newchannel->channel_callback_context = context;
3e7ee4902   Hank Janssen   Staging: hv: add ...
95

454f18a96   Bill Pemberton   Staging: hv: Remo...
96
  	/* Allocate the ring buffer */
294409d20   K. Y. Srinivasan   Drivers: hv: vmbu...
97
98
99
100
101
102
  	page = alloc_pages_node(cpu_to_node(newchannel->target_cpu),
  				GFP_KERNEL|__GFP_ZERO,
  				get_order(send_ringbuffer_size +
  				recv_ringbuffer_size));
  
  	if (!page)
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
103
104
105
  		page = alloc_pages(GFP_KERNEL|__GFP_ZERO,
  				   get_order(send_ringbuffer_size +
  					     recv_ringbuffer_size));
df3493e0b   K. Y. Srinivasan   Staging: hv: Use ...
106

98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
107
  	if (!page) {
ac0d12b7c   Dexuan Cui   hv: vmbus_open():...
108
  		err = -ENOMEM;
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
109
  		goto error_set_chnstate;
ac0d12b7c   Dexuan Cui   hv: vmbus_open():...
110
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
111

9988ce685   Vitaly Kuznetsov   Drivers: hv: ring...
112
  	newchannel->ringbuffer_pages = page_address(page);
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
113
  	newchannel->ringbuffer_pagecount = (send_ringbuffer_size +
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
114
  					   recv_ringbuffer_size) >> PAGE_SHIFT;
3e7ee4902   Hank Janssen   Staging: hv: add ...
115

9988ce685   Vitaly Kuznetsov   Drivers: hv: ring...
116
117
  	ret = hv_ringbuffer_init(&newchannel->outbound, page,
  				 send_ringbuffer_size >> PAGE_SHIFT);
72a95cbcb   K. Y. Srinivasan   Staging: hv: Rena...
118

fd4dc88e4   Haiyang Zhang   staging: hv: Fix ...
119
  	if (ret != 0) {
3324fb405   Bill Pemberton   staging: hv: chec...
120
  		err = ret;
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
121
  		goto error_free_pages;
3324fb405   Bill Pemberton   staging: hv: chec...
122
  	}
9988ce685   Vitaly Kuznetsov   Drivers: hv: ring...
123
124
125
  	ret = hv_ringbuffer_init(&newchannel->inbound,
  				 &page[send_ringbuffer_size >> PAGE_SHIFT],
  				 recv_ringbuffer_size >> PAGE_SHIFT);
fd4dc88e4   Haiyang Zhang   staging: hv: Fix ...
126
  	if (ret != 0) {
3324fb405   Bill Pemberton   staging: hv: chec...
127
  		err = ret;
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
128
  		goto error_free_pages;
3324fb405   Bill Pemberton   staging: hv: chec...
129
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
130

3e7ee4902   Hank Janssen   Staging: hv: add ...
131

454f18a96   Bill Pemberton   Staging: hv: Remo...
132
  	/* Establish the gpadl for the ring buffer */
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
133
  	newchannel->ringbuffer_gpadlhandle = 0;
3e7ee4902   Hank Janssen   Staging: hv: add ...
134

fff41b2e3   Haiyang Zhang   staging: hv: Rena...
135
  	ret = vmbus_establish_gpadl(newchannel,
9988ce685   Vitaly Kuznetsov   Drivers: hv: ring...
136
137
138
139
  				    page_address(page),
  				    send_ringbuffer_size +
  				    recv_ringbuffer_size,
  				    &newchannel->ringbuffer_gpadlhandle);
b94ef345b   Bill Pemberton   Staging: hv: test...
140

fd4dc88e4   Haiyang Zhang   staging: hv: Fix ...
141
  	if (ret != 0) {
b94ef345b   Bill Pemberton   Staging: hv: test...
142
  		err = ret;
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
143
  		goto error_free_pages;
b94ef345b   Bill Pemberton   Staging: hv: test...
144
  	}
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
145

454f18a96   Bill Pemberton   Staging: hv: Remo...
146
  	/* Create and init the channel open message */
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
147
  	open_info = kmalloc(sizeof(*open_info) +
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
148
149
  			   sizeof(struct vmbus_channel_open_channel),
  			   GFP_KERNEL);
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
150
  	if (!open_info) {
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
151
  		err = -ENOMEM;
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
152
  		goto error_free_gpadl;
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
153
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
154

176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
155
  	init_completion(&open_info->waitevent);
3e7ee4902   Hank Janssen   Staging: hv: add ...
156

176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
157
  	open_msg = (struct vmbus_channel_open_channel *)open_info->msg;
0987ff696   K. Y. Srinivasan   Staging: hv: vmbu...
158
159
160
161
162
  	open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL;
  	open_msg->openid = newchannel->offermsg.child_relid;
  	open_msg->child_relid = newchannel->offermsg.child_relid;
  	open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
  	open_msg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
163
  						  PAGE_SHIFT;
abbf3b2aa   K. Y. Srinivasan   Drivers: hv: Add ...
164
  	open_msg->target_vp = newchannel->target_vp;
3e7ee4902   Hank Janssen   Staging: hv: add ...
165

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
166
  	if (userdatalen > MAX_USER_DEFINED_BYTES) {
c827f944f   Bill Pemberton   Staging: hv: remo...
167
  		err = -EINVAL;
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
168
  		goto error_free_gpadl;
c827f944f   Bill Pemberton   Staging: hv: remo...
169
  	}
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
170
  	if (userdatalen)
0987ff696   K. Y. Srinivasan   Staging: hv: vmbu...
171
  		memcpy(open_msg->userdata, userdata, userdatalen);
3e7ee4902   Hank Janssen   Staging: hv: add ...
172

15b2f6479   Haiyang Zhang   staging: hv: Conv...
173
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
174
  	list_add_tail(&open_info->msglistentry,
da9fcb726   Haiyang Zhang   staging: hv: Conv...
175
  		      &vmbus_connection.chn_msg_list);
15b2f6479   Haiyang Zhang   staging: hv: Conv...
176
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
177

0987ff696   K. Y. Srinivasan   Staging: hv: vmbu...
178
  	ret = vmbus_post_msg(open_msg,
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
179
  			       sizeof(struct vmbus_channel_open_channel));
98e087022   Hank Janssen   staging: hv: Remo...
180

45d727cee   K. Y. Srinivasan   Drivers: hv: vmbu...
181
182
  	if (ret != 0) {
  		err = ret;
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
183
  		goto error_clean_msglist;
45d727cee   K. Y. Srinivasan   Drivers: hv: vmbu...
184
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
185

396e287fa   Vitaly Kuznetsov   Drivers: hv: get ...
186
  	wait_for_completion(&open_info->waitevent);
0c3b7b2f7   K. Y. Srinivasan   Staging: hv: Use ...
187

15b2f6479   Haiyang Zhang   staging: hv: Conv...
188
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
189
  	list_del(&open_info->msglistentry);
15b2f6479   Haiyang Zhang   staging: hv: Conv...
190
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
191

ffc151f3c   Vitaly Kuznetsov   Drivers: hv: vmbu...
192
193
  	if (open_info->response.open_result.status) {
  		err = -EAGAIN;
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
194
  		goto error_free_gpadl;
ffc151f3c   Vitaly Kuznetsov   Drivers: hv: vmbu...
195
  	}
e68d2971d   K. Y. Srinivasan   Drivers: hv: vmbu...
196

ffc151f3c   Vitaly Kuznetsov   Drivers: hv: vmbu...
197
  	newchannel->state = CHANNEL_OPENED_STATE;
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
198
  	kfree(open_info);
ffc151f3c   Vitaly Kuznetsov   Drivers: hv: vmbu...
199
  	return 0;
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
200

98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
201
  error_clean_msglist:
139255024   K. Y. Srinivasan   Drivers: hv: Clea...
202
203
204
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
  	list_del(&open_info->msglistentry);
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
205
  error_free_gpadl:
40384e4bb   K. Y. Srinivasan   Drivers: hv: vmbu...
206
  	vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
207
208
  	kfree(open_info);
  error_free_pages:
9988ce685   Vitaly Kuznetsov   Drivers: hv: ring...
209
210
211
212
  	hv_ringbuffer_cleanup(&newchannel->outbound);
  	hv_ringbuffer_cleanup(&newchannel->inbound);
  	__free_pages(page,
  		     get_order(send_ringbuffer_size + recv_ringbuffer_size));
98f531b10   Vitaly Kuznetsov   Drivers: hv: clea...
213
  error_set_chnstate:
ac0d12b7c   Dexuan Cui   hv: vmbus_open():...
214
  	newchannel->state = CHANNEL_OPEN_STATE;
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
215
  	return err;
3e7ee4902   Hank Janssen   Staging: hv: add ...
216
  }
36ceadfc6   Greg Kroah-Hartman   Staging: hv: chan...
217
  EXPORT_SYMBOL_GPL(vmbus_open);
3e7ee4902   Hank Janssen   Staging: hv: add ...
218

5c23a1a5c   Dexuan Cui   Drivers: hv: vmbu...
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  /* Used for Hyper-V Socket: a guest client's connect() to the host */
  int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
  				  const uuid_le *shv_host_servie_id)
  {
  	struct vmbus_channel_tl_connect_request conn_msg;
  
  	memset(&conn_msg, 0, sizeof(conn_msg));
  	conn_msg.header.msgtype = CHANNELMSG_TL_CONNECT_REQUEST;
  	conn_msg.guest_endpoint_id = *shv_guest_servie_id;
  	conn_msg.host_service_id = *shv_host_servie_id;
  
  	return vmbus_post_msg(&conn_msg, sizeof(conn_msg));
  }
  EXPORT_SYMBOL_GPL(vmbus_send_tl_connect_request);
3e1895195   Hank Janssen   staging: hv: Corr...
233
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
234
   * create_gpadl_header - Creates a gpadl for the specified buffer
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
235
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
236
  static int create_gpadl_header(void *kbuffer, u32 size,
4d6376329   Vitaly Kuznetsov   Drivers: hv: get ...
237
  			       struct vmbus_channel_msginfo **msginfo)
3e7ee4902   Hank Janssen   Staging: hv: add ...
238
239
  {
  	int i;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
240
  	int pagecount;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
241
242
243
244
245
  	struct vmbus_channel_gpadl_header *gpadl_header;
  	struct vmbus_channel_gpadl_body *gpadl_body;
  	struct vmbus_channel_msginfo *msgheader;
  	struct vmbus_channel_msginfo *msgbody = NULL;
  	u32 msgsize;
3e7ee4902   Hank Janssen   Staging: hv: add ...
246

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
247
  	int pfnsum, pfncount, pfnleft, pfncurr, pfnsize;
3e7ee4902   Hank Janssen   Staging: hv: add ...
248

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
249
  	pagecount = size >> PAGE_SHIFT;
3e7ee4902   Hank Janssen   Staging: hv: add ...
250

454f18a96   Bill Pemberton   Staging: hv: Remo...
251
  	/* do we need a gpadl body msg */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
252
  	pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
253
254
  		  sizeof(struct vmbus_channel_gpadl_header) -
  		  sizeof(struct gpa_range);
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
255
  	pfncount = pfnsize / sizeof(u64);
3e7ee4902   Hank Janssen   Staging: hv: add ...
256

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
257
  	if (pagecount > pfncount) {
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
258
  		/* we need a gpadl body */
454f18a96   Bill Pemberton   Staging: hv: Remo...
259
  		/* fill in the header */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
260
  		msgsize = sizeof(struct vmbus_channel_msginfo) +
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
261
  			  sizeof(struct vmbus_channel_gpadl_header) +
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
262
263
264
  			  sizeof(struct gpa_range) + pfncount * sizeof(u64);
  		msgheader =  kzalloc(msgsize, GFP_KERNEL);
  		if (!msgheader)
d1c250bb5   Bill Pemberton   Staging: hv: remo...
265
  			goto nomem;
3e7ee4902   Hank Janssen   Staging: hv: add ...
266

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
267
268
  		INIT_LIST_HEAD(&msgheader->submsglist);
  		msgheader->msgsize = msgsize;
3e7ee4902   Hank Janssen   Staging: hv: add ...
269

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
270
  		gpadl_header = (struct vmbus_channel_gpadl_header *)
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
271
272
273
  			msgheader->msg;
  		gpadl_header->rangecount = 1;
  		gpadl_header->range_buflen = sizeof(struct gpa_range) +
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
274
  					 pagecount * sizeof(u64);
415f22871   Haiyang Zhang   staging: hv: Conv...
275
276
  		gpadl_header->range[0].byte_offset = 0;
  		gpadl_header->range[0].byte_count = size;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
277
  		for (i = 0; i < pfncount; i++)
b679ef73e   Haiyang Zhang   hyperv: Add suppo...
278
279
  			gpadl_header->range[0].pfn_array[i] = slow_virt_to_phys(
  				kbuffer + PAGE_SIZE * i) >> PAGE_SHIFT;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
280
  		*msginfo = msgheader;
3e7ee4902   Hank Janssen   Staging: hv: add ...
281

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
282
283
  		pfnsum = pfncount;
  		pfnleft = pagecount - pfncount;
3e7ee4902   Hank Janssen   Staging: hv: add ...
284

454f18a96   Bill Pemberton   Staging: hv: Remo...
285
  		/* how many pfns can we fit */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
286
  		pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
287
  			  sizeof(struct vmbus_channel_gpadl_body);
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
288
  		pfncount = pfnsize / sizeof(u64);
3e7ee4902   Hank Janssen   Staging: hv: add ...
289

454f18a96   Bill Pemberton   Staging: hv: Remo...
290
  		/* fill in the body */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
291
292
293
  		while (pfnleft) {
  			if (pfnleft > pfncount)
  				pfncurr = pfncount;
3e7ee4902   Hank Janssen   Staging: hv: add ...
294
  			else
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
295
  				pfncurr = pfnleft;
3e7ee4902   Hank Janssen   Staging: hv: add ...
296

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
297
  			msgsize = sizeof(struct vmbus_channel_msginfo) +
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
298
  				  sizeof(struct vmbus_channel_gpadl_body) +
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
299
300
  				  pfncurr * sizeof(u64);
  			msgbody = kzalloc(msgsize, GFP_KERNEL);
f38cf9ccd   K. Y. Srinivasan   Staging: hv: vmbu...
301
302
303
304
305
306
307
308
309
310
311
312
313
314
  
  			if (!msgbody) {
  				struct vmbus_channel_msginfo *pos = NULL;
  				struct vmbus_channel_msginfo *tmp = NULL;
  				/*
  				 * Free up all the allocated messages.
  				 */
  				list_for_each_entry_safe(pos, tmp,
  					&msgheader->submsglist,
  					msglistentry) {
  
  					list_del(&pos->msglistentry);
  					kfree(pos);
  				}
d1c250bb5   Bill Pemberton   Staging: hv: remo...
315
  				goto nomem;
f38cf9ccd   K. Y. Srinivasan   Staging: hv: vmbu...
316
  			}
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
317
  			msgbody->msgsize = msgsize;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
318
  			gpadl_body =
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
319
  				(struct vmbus_channel_gpadl_body *)msgbody->msg;
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
320
321
  
  			/*
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
322
323
  			 * Gpadl is u32 and we are using a pointer which could
  			 * be 64-bit
f27df643d   K. Y. Srinivasan   Staging: hv: vmbu...
324
325
  			 * This is governed by the guest/host protocol and
  			 * so the hypervisor gurantees that this is ok.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
326
  			 */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
327
  			for (i = 0; i < pfncurr; i++)
b679ef73e   Haiyang Zhang   hyperv: Add suppo...
328
329
330
  				gpadl_body->pfn[i] = slow_virt_to_phys(
  					kbuffer + PAGE_SIZE * (pfnsum + i)) >>
  					PAGE_SHIFT;
3e7ee4902   Hank Janssen   Staging: hv: add ...
331

454f18a96   Bill Pemberton   Staging: hv: Remo...
332
  			/* add to msg header */
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
333
334
  			list_add_tail(&msgbody->msglistentry,
  				      &msgheader->submsglist);
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
335
336
  			pfnsum += pfncurr;
  			pfnleft -= pfncurr;
3e7ee4902   Hank Janssen   Staging: hv: add ...
337
  		}
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
338
  	} else {
454f18a96   Bill Pemberton   Staging: hv: Remo...
339
  		/* everything fits in a header */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
340
  		msgsize = sizeof(struct vmbus_channel_msginfo) +
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
341
  			  sizeof(struct vmbus_channel_gpadl_header) +
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
342
343
344
  			  sizeof(struct gpa_range) + pagecount * sizeof(u64);
  		msgheader = kzalloc(msgsize, GFP_KERNEL);
  		if (msgheader == NULL)
e3eb7cdd1   Kulikov Vasiliy   staging: hv: chec...
345
  			goto nomem;
4d6376329   Vitaly Kuznetsov   Drivers: hv: get ...
346
347
  
  		INIT_LIST_HEAD(&msgheader->submsglist);
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
348
  		msgheader->msgsize = msgsize;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
349
350
  
  		gpadl_header = (struct vmbus_channel_gpadl_header *)
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
351
352
353
  			msgheader->msg;
  		gpadl_header->rangecount = 1;
  		gpadl_header->range_buflen = sizeof(struct gpa_range) +
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
354
  					 pagecount * sizeof(u64);
415f22871   Haiyang Zhang   staging: hv: Conv...
355
356
  		gpadl_header->range[0].byte_offset = 0;
  		gpadl_header->range[0].byte_count = size;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
357
  		for (i = 0; i < pagecount; i++)
b679ef73e   Haiyang Zhang   hyperv: Add suppo...
358
359
  			gpadl_header->range[0].pfn_array[i] = slow_virt_to_phys(
  				kbuffer + PAGE_SIZE * i) >> PAGE_SHIFT;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
360
361
  
  		*msginfo = msgheader;
3e7ee4902   Hank Janssen   Staging: hv: add ...
362
363
364
  	}
  
  	return 0;
d1c250bb5   Bill Pemberton   Staging: hv: remo...
365
  nomem:
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
366
367
  	kfree(msgheader);
  	kfree(msgbody);
d1c250bb5   Bill Pemberton   Staging: hv: remo...
368
  	return -ENOMEM;
3e7ee4902   Hank Janssen   Staging: hv: add ...
369
  }
3e1895195   Hank Janssen   staging: hv: Corr...
370
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
371
   * vmbus_establish_gpadl - Estabish a GPADL for the specified buffer
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
372
   *
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
373
   * @channel: a channel
b679ef73e   Haiyang Zhang   hyperv: Add suppo...
374
   * @kbuffer: from kmalloc or vmalloc
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
375
376
   * @size: page-size multiple
   * @gpadl_handle: some funky thing
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
377
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
378
  int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
379
  			       u32 size, u32 *gpadl_handle)
3e7ee4902   Hank Janssen   Staging: hv: add ...
380
  {
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
381
382
  	struct vmbus_channel_gpadl_header *gpadlmsg;
  	struct vmbus_channel_gpadl_body *gpadl_body;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
383
  	struct vmbus_channel_msginfo *msginfo = NULL;
7cc80c980   Vitaly Kuznetsov   Drivers: hv: don'...
384
  	struct vmbus_channel_msginfo *submsginfo, *tmp;
53af545b2   Bill Pemberton   Staging: hv: remo...
385
  	struct list_head *curr;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
386
  	u32 next_gpadl_handle;
dd0813b6f   Greg Kroah-Hartman   Staging: hv: make...
387
  	unsigned long flags;
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
388
  	int ret = 0;
3e7ee4902   Hank Janssen   Staging: hv: add ...
389

9f52a1630   K. Y. Srinivasan   Drivers: hv: vmbu...
390
391
  	next_gpadl_handle =
  		(atomic_inc_return(&vmbus_connection.next_gpadl_handle) - 1);
3e7ee4902   Hank Janssen   Staging: hv: add ...
392

4d6376329   Vitaly Kuznetsov   Drivers: hv: get ...
393
  	ret = create_gpadl_header(kbuffer, size, &msginfo);
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
394
395
  	if (ret)
  		return ret;
3e7ee4902   Hank Janssen   Staging: hv: add ...
396

9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
397
  	init_completion(&msginfo->waitevent);
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
398

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
399
400
401
402
  	gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg;
  	gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER;
  	gpadlmsg->child_relid = channel->offermsg.child_relid;
  	gpadlmsg->gpadl = next_gpadl_handle;
3e7ee4902   Hank Janssen   Staging: hv: add ...
403

3e7ee4902   Hank Janssen   Staging: hv: add ...
404

15b2f6479   Haiyang Zhang   staging: hv: Conv...
405
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
406
  	list_add_tail(&msginfo->msglistentry,
da9fcb726   Haiyang Zhang   staging: hv: Conv...
407
  		      &vmbus_connection.chn_msg_list);
3e7ee4902   Hank Janssen   Staging: hv: add ...
408

15b2f6479   Haiyang Zhang   staging: hv: Conv...
409
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
410

c69776771   Haiyang Zhang   staging: hv: Conv...
411
  	ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize -
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
412
  			       sizeof(*msginfo));
98e087022   Hank Janssen   staging: hv: Remo...
413
  	if (ret != 0)
00d760b05   K. Y. Srinivasan   Staging: hv: vmbu...
414
  		goto cleanup;
3e7ee4902   Hank Janssen   Staging: hv: add ...
415

4d6376329   Vitaly Kuznetsov   Drivers: hv: get ...
416
417
418
419
  	list_for_each(curr, &msginfo->submsglist) {
  		submsginfo = (struct vmbus_channel_msginfo *)curr;
  		gpadl_body =
  			(struct vmbus_channel_gpadl_body *)submsginfo->msg;
53af545b2   Bill Pemberton   Staging: hv: remo...
420

4d6376329   Vitaly Kuznetsov   Drivers: hv: get ...
421
422
423
  		gpadl_body->header.msgtype =
  			CHANNELMSG_GPADL_BODY;
  		gpadl_body->gpadl = next_gpadl_handle;
3e7ee4902   Hank Janssen   Staging: hv: add ...
424

4d6376329   Vitaly Kuznetsov   Drivers: hv: get ...
425
426
427
428
429
  		ret = vmbus_post_msg(gpadl_body,
  				     submsginfo->msgsize -
  				     sizeof(*submsginfo));
  		if (ret != 0)
  			goto cleanup;
3e7ee4902   Hank Janssen   Staging: hv: add ...
430

3e7ee4902   Hank Janssen   Staging: hv: add ...
431
  	}
72c6b71c2   K. Y. Srinivasan   Drivers: hv: vmbu...
432
  	wait_for_completion(&msginfo->waitevent);
3e7ee4902   Hank Janssen   Staging: hv: add ...
433

454f18a96   Bill Pemberton   Staging: hv: Remo...
434
  	/* At this point, we received the gpadl created msg */
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
435
  	*gpadl_handle = gpadlmsg->gpadl;
3e7ee4902   Hank Janssen   Staging: hv: add ...
436

00d760b05   K. Y. Srinivasan   Staging: hv: vmbu...
437
  cleanup:
15b2f6479   Haiyang Zhang   staging: hv: Conv...
438
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
439
  	list_del(&msginfo->msglistentry);
15b2f6479   Haiyang Zhang   staging: hv: Conv...
440
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
7cc80c980   Vitaly Kuznetsov   Drivers: hv: don'...
441
442
443
444
  	list_for_each_entry_safe(submsginfo, tmp, &msginfo->submsglist,
  				 msglistentry) {
  		kfree(submsginfo);
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
445

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
446
  	kfree(msginfo);
3e7ee4902   Hank Janssen   Staging: hv: add ...
447
448
  	return ret;
  }
98873724a   Greg Kroah-Hartman   Staging: hv: chan...
449
  EXPORT_SYMBOL_GPL(vmbus_establish_gpadl);
3e7ee4902   Hank Janssen   Staging: hv: add ...
450

3e1895195   Hank Janssen   staging: hv: Corr...
451
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
452
   * vmbus_teardown_gpadl -Teardown the specified GPADL handle
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
453
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
454
  int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
3e7ee4902   Hank Janssen   Staging: hv: add ...
455
  {
82250213d   Greg Kroah-Hartman   Staging: hv: type...
456
  	struct vmbus_channel_gpadl_teardown *msg;
aded7165f   Greg Kroah-Hartman   Staging: hv: clea...
457
  	struct vmbus_channel_msginfo *info;
dd0813b6f   Greg Kroah-Hartman   Staging: hv: make...
458
  	unsigned long flags;
66be65308   K. Y. Srinivasan   Drivers: hv: vmbu...
459
  	int ret;
3e7ee4902   Hank Janssen   Staging: hv: add ...
460

f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
461
462
  	info = kmalloc(sizeof(*info) +
  		       sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
463
464
  	if (!info)
  		return -ENOMEM;
3e7ee4902   Hank Janssen   Staging: hv: add ...
465

9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
466
  	init_completion(&info->waitevent);
3e7ee4902   Hank Janssen   Staging: hv: add ...
467

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
468
  	msg = (struct vmbus_channel_gpadl_teardown *)info->msg;
3e7ee4902   Hank Janssen   Staging: hv: add ...
469

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
470
471
472
  	msg->header.msgtype = CHANNELMSG_GPADL_TEARDOWN;
  	msg->child_relid = channel->offermsg.child_relid;
  	msg->gpadl = gpadl_handle;
3e7ee4902   Hank Janssen   Staging: hv: add ...
473

15b2f6479   Haiyang Zhang   staging: hv: Conv...
474
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
475
  	list_add_tail(&info->msglistentry,
da9fcb726   Haiyang Zhang   staging: hv: Conv...
476
  		      &vmbus_connection.chn_msg_list);
15b2f6479   Haiyang Zhang   staging: hv: Conv...
477
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
c69776771   Haiyang Zhang   staging: hv: Conv...
478
  	ret = vmbus_post_msg(msg,
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
479
  			       sizeof(struct vmbus_channel_gpadl_teardown));
3e7ee4902   Hank Janssen   Staging: hv: add ...
480

66be65308   K. Y. Srinivasan   Drivers: hv: vmbu...
481
482
483
484
  	if (ret)
  		goto post_msg_err;
  
  	wait_for_completion(&info->waitevent);
3e7ee4902   Hank Janssen   Staging: hv: add ...
485

66be65308   K. Y. Srinivasan   Drivers: hv: vmbu...
486
  post_msg_err:
15b2f6479   Haiyang Zhang   staging: hv: Conv...
487
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
488
  	list_del(&info->msglistentry);
15b2f6479   Haiyang Zhang   staging: hv: Conv...
489
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
490

8c69f52ab   Greg Kroah-Hartman   Staging: hv: osd:...
491
  	kfree(info);
3e7ee4902   Hank Janssen   Staging: hv: add ...
492
493
  	return ret;
  }
18726d7a6   Greg Kroah-Hartman   Staging: hv: chan...
494
  EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
3e7ee4902   Hank Janssen   Staging: hv: add ...
495

d3ba720dd   K. Y. Srinivasan   Drivers: hv: Elim...
496
497
498
499
500
501
  static void reset_channel_cb(void *arg)
  {
  	struct vmbus_channel *channel = arg;
  
  	channel->onchannel_callback = NULL;
  }
98d731bb0   K. Y. Srinivasan   Drivers: hv: vmbu...
502
  static int vmbus_close_internal(struct vmbus_channel *channel)
3e7ee4902   Hank Janssen   Staging: hv: add ...
503
  {
82250213d   Greg Kroah-Hartman   Staging: hv: type...
504
  	struct vmbus_channel_close_channel *msg;
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
505
  	int ret;
3e7ee4902   Hank Janssen   Staging: hv: add ...
506

63d55b2ae   Dexuan Cui   Drivers: hv: vmbu...
507
508
509
510
511
512
513
514
515
  	/*
  	 * process_chn_event(), running in the tasklet, can race
  	 * with vmbus_close_internal() in the case of SMP guest, e.g., when
  	 * the former is accessing channel->inbound.ring_buffer, the latter
  	 * could be freeing the ring_buffer pages.
  	 *
  	 * To resolve the race, we can serialize them by disabling the
  	 * tasklet when the latter is running here.
  	 */
638fea33a   Dexuan Cui   Drivers: hv: vmbu...
516
  	hv_event_tasklet_disable(channel);
63d55b2ae   Dexuan Cui   Drivers: hv: vmbu...
517

64b7faf90   Dexuan Cui   Drivers: hv: vmbu...
518
519
520
521
522
523
524
525
526
527
528
  	/*
  	 * In case a device driver's probe() fails (e.g.,
  	 * util_probe() -> vmbus_open() returns -ENOMEM) and the device is
  	 * rescinded later (e.g., we dynamically disble an Integrated Service
  	 * in Hyper-V Manager), the driver's remove() invokes vmbus_close():
  	 * here we should skip most of the below cleanup work.
  	 */
  	if (channel->state != CHANNEL_OPENED_STATE) {
  		ret = -EINVAL;
  		goto out;
  	}
e68d2971d   K. Y. Srinivasan   Drivers: hv: vmbu...
529
530
  	channel->state = CHANNEL_OPEN_STATE;
  	channel->sc_creation_callback = NULL;
454f18a96   Bill Pemberton   Staging: hv: Remo...
531
  	/* Stop callback and cancel the timer asap */
2115b5617   K. Y. Srinivasan   Drivers: hv: vmbu...
532
533
  	if (channel->target_cpu != get_cpu()) {
  		put_cpu();
d3ba720dd   K. Y. Srinivasan   Drivers: hv: Elim...
534
535
  		smp_call_function_single(channel->target_cpu, reset_channel_cb,
  					 channel, true);
2115b5617   K. Y. Srinivasan   Drivers: hv: vmbu...
536
  	} else {
d3ba720dd   K. Y. Srinivasan   Drivers: hv: Elim...
537
  		reset_channel_cb(channel);
2115b5617   K. Y. Srinivasan   Drivers: hv: vmbu...
538
539
  		put_cpu();
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
540

454f18a96   Bill Pemberton   Staging: hv: Remo...
541
  	/* Send a closing message */
3e7ee4902   Hank Janssen   Staging: hv: add ...
542

e9a27a9f9   K. Y. Srinivasan   Staging: hv: vmbu...
543
  	msg = &channel->close_msg.msg;
3e7ee4902   Hank Janssen   Staging: hv: add ...
544

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
545
546
  	msg->header.msgtype = CHANNELMSG_CLOSECHANNEL;
  	msg->child_relid = channel->offermsg.child_relid;
3e7ee4902   Hank Janssen   Staging: hv: add ...
547

c69776771   Haiyang Zhang   staging: hv: Conv...
548
  	ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel));
3e7ee4902   Hank Janssen   Staging: hv: add ...
549

98d731bb0   K. Y. Srinivasan   Drivers: hv: vmbu...
550
551
552
553
554
555
556
  	if (ret) {
  		pr_err("Close failed: close post msg return is %d
  ", ret);
  		/*
  		 * If we failed to post the close msg,
  		 * it is perhaps better to leak memory.
  		 */
63d55b2ae   Dexuan Cui   Drivers: hv: vmbu...
557
  		goto out;
98d731bb0   K. Y. Srinivasan   Drivers: hv: vmbu...
558
  	}
454f18a96   Bill Pemberton   Staging: hv: Remo...
559
  	/* Tear down the gpadl for the channel's ring buffer */
98d731bb0   K. Y. Srinivasan   Drivers: hv: vmbu...
560
561
562
563
564
565
566
567
568
569
  	if (channel->ringbuffer_gpadlhandle) {
  		ret = vmbus_teardown_gpadl(channel,
  					   channel->ringbuffer_gpadlhandle);
  		if (ret) {
  			pr_err("Close failed: teardown gpadl return %d
  ", ret);
  			/*
  			 * If we failed to teardown gpadl,
  			 * it is perhaps better to leak memory.
  			 */
63d55b2ae   Dexuan Cui   Drivers: hv: vmbu...
570
  			goto out;
98d731bb0   K. Y. Srinivasan   Drivers: hv: vmbu...
571
572
  		}
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
573

454f18a96   Bill Pemberton   Staging: hv: Remo...
574
  	/* Cleanup the ring buffers for this channel */
2dba688ba   K. Y. Srinivasan   Staging: hv: Rena...
575
576
  	hv_ringbuffer_cleanup(&channel->outbound);
  	hv_ringbuffer_cleanup(&channel->inbound);
3e7ee4902   Hank Janssen   Staging: hv: add ...
577

df3493e0b   K. Y. Srinivasan   Staging: hv: Use ...
578
579
  	free_pages((unsigned long)channel->ringbuffer_pages,
  		get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
3e7ee4902   Hank Janssen   Staging: hv: add ...
580

63d55b2ae   Dexuan Cui   Drivers: hv: vmbu...
581
  out:
638fea33a   Dexuan Cui   Drivers: hv: vmbu...
582
  	hv_event_tasklet_enable(channel);
63d55b2ae   Dexuan Cui   Drivers: hv: vmbu...
583

98d731bb0   K. Y. Srinivasan   Drivers: hv: vmbu...
584
  	return ret;
3e7ee4902   Hank Janssen   Staging: hv: add ...
585
  }
e68d2971d   K. Y. Srinivasan   Drivers: hv: vmbu...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
  
  /*
   * vmbus_close - Close the specified channel
   */
  void vmbus_close(struct vmbus_channel *channel)
  {
  	struct list_head *cur, *tmp;
  	struct vmbus_channel *cur_channel;
  
  	if (channel->primary_channel != NULL) {
  		/*
  		 * We will only close sub-channels when
  		 * the primary is closed.
  		 */
  		return;
  	}
  	/*
  	 * Close all the sub-channels first and then close the
  	 * primary channel.
  	 */
  	list_for_each_safe(cur, tmp, &channel->sc_list) {
  		cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
  		if (cur_channel->state != CHANNEL_OPENED_STATE)
  			continue;
  		vmbus_close_internal(cur_channel);
  	}
  	/*
  	 * Now close the primary.
  	 */
  	vmbus_close_internal(channel);
  }
70bfa3078   Greg Kroah-Hartman   Staging: hv: chan...
617
  EXPORT_SYMBOL_GPL(vmbus_close);
3e7ee4902   Hank Janssen   Staging: hv: add ...
618

e9395e3f8   K. Y. Srinivasan   Drivers: hv: vmbu...
619
  int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
620
  			   u32 bufferlen, u64 requestid,
e9395e3f8   K. Y. Srinivasan   Drivers: hv: vmbu...
621
  			   enum vmbus_packet_type type, u32 flags, bool kick_q)
3e7ee4902   Hank Janssen   Staging: hv: add ...
622
  {
8dc0a06ad   Greg Kroah-Hartman   Staging: hv: remo...
623
  	struct vmpacket_descriptor desc;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
624
  	u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen;
735096819   Uwe Kleine-König   staging/hv/osd: d...
625
  	u32 packetlen_aligned = ALIGN(packetlen, sizeof(u64));
011a7c3cc   K. Y. Srinivasan   Drivers: hv: vmbu...
626
  	struct kvec bufferlist[3];
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
627
  	u64 aligned_data = 0;
fe760e4d6   K. Y. Srinivasan   Drivers: hv: vmbu...
628
  	bool lock = channel->acquire_ring_lock;
b81658cf5   K. Y. Srinivasan   Drivers: hv: vmbu...
629
  	int num_vecs = ((bufferlen != 0) ? 3 : 1);
3e7ee4902   Hank Janssen   Staging: hv: add ...
630

3e7ee4902   Hank Janssen   Staging: hv: add ...
631

454f18a96   Bill Pemberton   Staging: hv: Remo...
632
  	/* Setup the descriptor */
415f22871   Haiyang Zhang   staging: hv: Conv...
633
634
  	desc.type = type; /* VmbusPacketTypeDataInBand; */
  	desc.flags = flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
635
  	/* in 8-bytes granularity */
415f22871   Haiyang Zhang   staging: hv: Conv...
636
637
638
  	desc.offset8 = sizeof(struct vmpacket_descriptor) >> 3;
  	desc.len8 = (u16)(packetlen_aligned >> 3);
  	desc.trans_id = requestid;
3e7ee4902   Hank Janssen   Staging: hv: add ...
639

011a7c3cc   K. Y. Srinivasan   Drivers: hv: vmbu...
640
641
642
643
644
645
  	bufferlist[0].iov_base = &desc;
  	bufferlist[0].iov_len = sizeof(struct vmpacket_descriptor);
  	bufferlist[1].iov_base = buffer;
  	bufferlist[1].iov_len = bufferlen;
  	bufferlist[2].iov_base = &aligned_data;
  	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
3e7ee4902   Hank Janssen   Staging: hv: add ...
646

e2fdf7841   K. Y. Srinivasan   Drivers: hv: vmbu...
647
648
  	return hv_ringbuffer_write(channel, bufferlist, num_vecs,
  				   lock, kick_q);
3e7ee4902   Hank Janssen   Staging: hv: add ...
649

3e7ee4902   Hank Janssen   Staging: hv: add ...
650
  }
e9395e3f8   K. Y. Srinivasan   Drivers: hv: vmbu...
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
  EXPORT_SYMBOL(vmbus_sendpacket_ctl);
  
  /**
   * vmbus_sendpacket() - Send the specified buffer on the given channel
   * @channel: Pointer to vmbus_channel structure.
   * @buffer: Pointer to the buffer you want to receive the data into.
   * @bufferlen: Maximum size of what the the buffer will hold
   * @requestid: Identifier of the request
   * @type: Type of packet that is being send e.g. negotiate, time
   * packet etc.
   *
   * Sends data in @buffer directly to hyper-v via the vmbus
   * This will send the data unparsed to hyper-v.
   *
   * Mainly used by Hyper-V drivers.
   */
  int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
  			   u32 bufferlen, u64 requestid,
  			   enum vmbus_packet_type type, u32 flags)
  {
  	return vmbus_sendpacket_ctl(channel, buffer, bufferlen, requestid,
  				    type, flags, true);
  }
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
674
  EXPORT_SYMBOL(vmbus_sendpacket);
3e7ee4902   Hank Janssen   Staging: hv: add ...
675

3e1895195   Hank Janssen   staging: hv: Corr...
676
  /*
87e93d617   K. Y. Srinivasan   Drivers: hv: vmbu...
677
678
679
680
681
   * vmbus_sendpacket_pagebuffer_ctl - Send a range of single-page buffer
   * packets using a GPADL Direct packet type. This interface allows you
   * to control notifying the host. This will be useful for sending
   * batched data. Also the sender can control the send flags
   * explicitly.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
682
   */
87e93d617   K. Y. Srinivasan   Drivers: hv: vmbu...
683
  int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
684
685
  				     struct hv_page_buffer pagebuffers[],
  				     u32 pagecount, void *buffer, u32 bufferlen,
87e93d617   K. Y. Srinivasan   Drivers: hv: vmbu...
686
687
688
  				     u64 requestid,
  				     u32 flags,
  				     bool kick_q)
3e7ee4902   Hank Janssen   Staging: hv: add ...
689
  {
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
690
  	int i;
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
691
  	struct vmbus_channel_packet_page_buffer desc;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
692
693
694
  	u32 descsize;
  	u32 packetlen;
  	u32 packetlen_aligned;
011a7c3cc   K. Y. Srinivasan   Drivers: hv: vmbu...
695
  	struct kvec bufferlist[3];
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
696
  	u64 aligned_data = 0;
fe760e4d6   K. Y. Srinivasan   Drivers: hv: vmbu...
697
  	bool lock = channel->acquire_ring_lock;
3e7ee4902   Hank Janssen   Staging: hv: add ...
698

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
699
  	if (pagecount > MAX_PAGE_BUFFER_COUNT)
002b53ea5   Bill Pemberton   Staging: hv: retu...
700
  		return -EINVAL;
3e7ee4902   Hank Janssen   Staging: hv: add ...
701

3e7ee4902   Hank Janssen   Staging: hv: add ...
702

f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
703
  	/*
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
704
  	 * Adjust the size down since vmbus_channel_packet_page_buffer is the
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
705
706
  	 * largest size we support
  	 */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
707
708
  	descsize = sizeof(struct vmbus_channel_packet_page_buffer) -
  			  ((MAX_PAGE_BUFFER_COUNT - pagecount) *
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
709
  			  sizeof(struct hv_page_buffer));
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
710
  	packetlen = descsize + bufferlen;
735096819   Uwe Kleine-König   staging/hv/osd: d...
711
  	packetlen_aligned = ALIGN(packetlen, sizeof(u64));
3e7ee4902   Hank Janssen   Staging: hv: add ...
712

454f18a96   Bill Pemberton   Staging: hv: Remo...
713
  	/* Setup the descriptor */
415f22871   Haiyang Zhang   staging: hv: Conv...
714
  	desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
87e93d617   K. Y. Srinivasan   Drivers: hv: vmbu...
715
  	desc.flags = flags;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
716
717
718
719
720
721
  	desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */
  	desc.length8 = (u16)(packetlen_aligned >> 3);
  	desc.transactionid = requestid;
  	desc.rangecount = pagecount;
  
  	for (i = 0; i < pagecount; i++) {
ca623ad35   Haiyang Zhang   staging: hv: Conv...
722
723
724
  		desc.range[i].len = pagebuffers[i].len;
  		desc.range[i].offset = pagebuffers[i].offset;
  		desc.range[i].pfn	 = pagebuffers[i].pfn;
3e7ee4902   Hank Janssen   Staging: hv: add ...
725
  	}
011a7c3cc   K. Y. Srinivasan   Drivers: hv: vmbu...
726
727
728
729
730
731
  	bufferlist[0].iov_base = &desc;
  	bufferlist[0].iov_len = descsize;
  	bufferlist[1].iov_base = buffer;
  	bufferlist[1].iov_len = bufferlen;
  	bufferlist[2].iov_base = &aligned_data;
  	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
3e7ee4902   Hank Janssen   Staging: hv: add ...
732

e2fdf7841   K. Y. Srinivasan   Drivers: hv: vmbu...
733
734
  	return hv_ringbuffer_write(channel, bufferlist, 3,
  				   lock, kick_q);
3e7ee4902   Hank Janssen   Staging: hv: add ...
735
  }
b3a19b36a   K. Y. Srinivasan   Drivers: hv: vmbu...
736
  EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer_ctl);
87e93d617   K. Y. Srinivasan   Drivers: hv: vmbu...
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
  
  /*
   * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
   * packets using a GPADL Direct packet type.
   */
  int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
  				     struct hv_page_buffer pagebuffers[],
  				     u32 pagecount, void *buffer, u32 bufferlen,
  				     u64 requestid)
  {
  	u32 flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
  	return vmbus_sendpacket_pagebuffer_ctl(channel, pagebuffers, pagecount,
  					       buffer, bufferlen, requestid,
  					       flags, true);
  
  }
713efeb4d   Greg Kroah-Hartman   Staging: hv: chan...
753
  EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
3e7ee4902   Hank Janssen   Staging: hv: add ...
754

3e1895195   Hank Janssen   staging: hv: Corr...
755
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
756
   * vmbus_sendpacket_multipagebuffer - Send a multi-page buffer packet
3e1895195   Hank Janssen   staging: hv: Corr...
757
   * using a GPADL Direct packet type.
d61031ee8   K. Y. Srinivasan   Drivers: hv: vmbu...
758
759
760
761
762
763
764
   * The buffer includes the vmbus descriptor.
   */
  int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
  			      struct vmbus_packet_mpb_array *desc,
  			      u32 desc_size,
  			      void *buffer, u32 bufferlen, u64 requestid)
  {
d61031ee8   K. Y. Srinivasan   Drivers: hv: vmbu...
765
766
767
768
  	u32 packetlen;
  	u32 packetlen_aligned;
  	struct kvec bufferlist[3];
  	u64 aligned_data = 0;
fe760e4d6   K. Y. Srinivasan   Drivers: hv: vmbu...
769
  	bool lock = channel->acquire_ring_lock;
d61031ee8   K. Y. Srinivasan   Drivers: hv: vmbu...
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
  
  	packetlen = desc_size + bufferlen;
  	packetlen_aligned = ALIGN(packetlen, sizeof(u64));
  
  	/* Setup the descriptor */
  	desc->type = VM_PKT_DATA_USING_GPA_DIRECT;
  	desc->flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
  	desc->dataoffset8 = desc_size >> 3; /* in 8-bytes grandularity */
  	desc->length8 = (u16)(packetlen_aligned >> 3);
  	desc->transactionid = requestid;
  	desc->rangecount = 1;
  
  	bufferlist[0].iov_base = desc;
  	bufferlist[0].iov_len = desc_size;
  	bufferlist[1].iov_base = buffer;
  	bufferlist[1].iov_len = bufferlen;
  	bufferlist[2].iov_base = &aligned_data;
  	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
e2fdf7841   K. Y. Srinivasan   Drivers: hv: vmbu...
788
789
  	return hv_ringbuffer_write(channel, bufferlist, 3,
  				   lock, true);
d61031ee8   K. Y. Srinivasan   Drivers: hv: vmbu...
790
791
792
793
794
795
  }
  EXPORT_SYMBOL_GPL(vmbus_sendpacket_mpb_desc);
  
  /*
   * vmbus_sendpacket_multipagebuffer - Send a multi-page buffer packet
   * using a GPADL Direct packet type.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
796
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
797
  int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
798
799
  				struct hv_multipage_buffer *multi_pagebuffer,
  				void *buffer, u32 bufferlen, u64 requestid)
3e7ee4902   Hank Janssen   Staging: hv: add ...
800
  {
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
801
  	struct vmbus_channel_packet_multipage_buffer desc;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
802
803
804
  	u32 descsize;
  	u32 packetlen;
  	u32 packetlen_aligned;
011a7c3cc   K. Y. Srinivasan   Drivers: hv: vmbu...
805
  	struct kvec bufferlist[3];
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
806
  	u64 aligned_data = 0;
fe760e4d6   K. Y. Srinivasan   Drivers: hv: vmbu...
807
  	bool lock = channel->acquire_ring_lock;
ca623ad35   Haiyang Zhang   staging: hv: Conv...
808
809
  	u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset,
  					 multi_pagebuffer->len);
3e7ee4902   Hank Janssen   Staging: hv: add ...
810

24b8a406b   Tobias Klauser   hv: Remove unnece...
811
  	if (pfncount > MAX_MULTIPAGE_BUFFER_COUNT)
002b53ea5   Bill Pemberton   Staging: hv: retu...
812
  		return -EINVAL;
3e7ee4902   Hank Janssen   Staging: hv: add ...
813

f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
814
  	/*
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
815
  	 * Adjust the size down since vmbus_channel_packet_multipage_buffer is
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
816
817
  	 * the largest size we support
  	 */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
818
819
  	descsize = sizeof(struct vmbus_channel_packet_multipage_buffer) -
  			  ((MAX_MULTIPAGE_BUFFER_COUNT - pfncount) *
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
820
  			  sizeof(u64));
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
821
  	packetlen = descsize + bufferlen;
735096819   Uwe Kleine-König   staging/hv/osd: d...
822
  	packetlen_aligned = ALIGN(packetlen, sizeof(u64));
3e7ee4902   Hank Janssen   Staging: hv: add ...
823

3e7ee4902   Hank Janssen   Staging: hv: add ...
824

454f18a96   Bill Pemberton   Staging: hv: Remo...
825
  	/* Setup the descriptor */
415f22871   Haiyang Zhang   staging: hv: Conv...
826
  	desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
827
  	desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
828
829
830
  	desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */
  	desc.length8 = (u16)(packetlen_aligned >> 3);
  	desc.transactionid = requestid;
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
831
  	desc.rangecount = 1;
3e7ee4902   Hank Janssen   Staging: hv: add ...
832

ca623ad35   Haiyang Zhang   staging: hv: Conv...
833
834
  	desc.range.len = multi_pagebuffer->len;
  	desc.range.offset = multi_pagebuffer->offset;
3e7ee4902   Hank Janssen   Staging: hv: add ...
835

ca623ad35   Haiyang Zhang   staging: hv: Conv...
836
  	memcpy(desc.range.pfn_array, multi_pagebuffer->pfn_array,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
837
  	       pfncount * sizeof(u64));
3e7ee4902   Hank Janssen   Staging: hv: add ...
838

011a7c3cc   K. Y. Srinivasan   Drivers: hv: vmbu...
839
840
841
842
843
844
  	bufferlist[0].iov_base = &desc;
  	bufferlist[0].iov_len = descsize;
  	bufferlist[1].iov_base = buffer;
  	bufferlist[1].iov_len = bufferlen;
  	bufferlist[2].iov_base = &aligned_data;
  	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
3e7ee4902   Hank Janssen   Staging: hv: add ...
845

e2fdf7841   K. Y. Srinivasan   Drivers: hv: vmbu...
846
847
  	return hv_ringbuffer_write(channel, bufferlist, 3,
  				   lock, true);
3e7ee4902   Hank Janssen   Staging: hv: add ...
848
  }
4cb106faf   Greg Kroah-Hartman   Staging: hv: chan...
849
  EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
850
851
  
  /**
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
852
   * vmbus_recvpacket() - Retrieve the user packet on the specified channel
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
853
854
855
856
857
   * @channel: Pointer to vmbus_channel structure.
   * @buffer: Pointer to the buffer you want to receive the data into.
   * @bufferlen: Maximum size of what the the buffer will hold
   * @buffer_actual_len: The actual size of the data after it was received
   * @requestid: Identifier of the request
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
858
859
860
861
862
   *
   * Receives directly from the hyper-v vmbus and puts the data it received
   * into Buffer. This will receive the data unparsed from hyper-v.
   *
   * Mainly used by Hyper-V drivers.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
863
   */
667d37406   Vitaly Kuznetsov   Drivers: hv: remo...
864
865
866
867
  static inline int
  __vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
  		   u32 bufferlen, u32 *buffer_actual_len, u64 *requestid,
  		   bool raw)
3e7ee4902   Hank Janssen   Staging: hv: add ...
868
  {
964dfbe3d   K. Y. Srinivasan   Drivers: hv: vmbu...
869
870
  	return hv_ringbuffer_read(channel, buffer, bufferlen,
  				  buffer_actual_len, requestid, raw);
3e7ee4902   Hank Janssen   Staging: hv: add ...
871

667d37406   Vitaly Kuznetsov   Drivers: hv: remo...
872
873
874
875
876
877
878
879
  }
  
  int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
  		     u32 bufferlen, u32 *buffer_actual_len,
  		     u64 *requestid)
  {
  	return __vmbus_recvpacket(channel, buffer, bufferlen,
  				  buffer_actual_len, requestid, false);
3e7ee4902   Hank Janssen   Staging: hv: add ...
880
  }
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
881
  EXPORT_SYMBOL(vmbus_recvpacket);
3e7ee4902   Hank Janssen   Staging: hv: add ...
882

3e1895195   Hank Janssen   staging: hv: Corr...
883
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
884
   * vmbus_recvpacket_raw - Retrieve the raw packet on the specified channel
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
885
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
886
  int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
887
888
  			      u32 bufferlen, u32 *buffer_actual_len,
  			      u64 *requestid)
3e7ee4902   Hank Janssen   Staging: hv: add ...
889
  {
667d37406   Vitaly Kuznetsov   Drivers: hv: remo...
890
891
  	return __vmbus_recvpacket(channel, buffer, bufferlen,
  				  buffer_actual_len, requestid, true);
3e7ee4902   Hank Janssen   Staging: hv: add ...
892
  }
adaee6bd4   Greg Kroah-Hartman   Staging: hv: chan...
893
  EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);