Blame view

drivers/hv/channel.c 22.5 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>
3f335ea21   K. Y. Srinivasan   Staging: hv: Incl...
29

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

e3fe0bb65   K. Y. Srinivasan   Staging: hv: Remo...
32
33
  #define NUM_PAGES_SPANNED(addr, len) \
  ((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - (addr >> PAGE_SHIFT))
454f18a96   Bill Pemberton   Staging: hv: Remo...
34
  /* Internal routines */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
35
  static int create_gpadl_header(
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
36
37
38
39
  	void *kbuffer,	/* must be phys and virt contiguous */
  	u32 size,	/* page-size multiple */
  	struct vmbus_channel_msginfo **msginfo,
  	u32 *messagecount);
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
40
  static void vmbus_setevent(struct vmbus_channel *channel);
3e7ee4902   Hank Janssen   Staging: hv: add ...
41

3e1895195   Hank Janssen   staging: hv: Corr...
42
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
43
   * vmbus_setevent- Trigger an event notification on the specified
3e1895195   Hank Janssen   staging: hv: Corr...
44
   * channel.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
45
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
46
  static void vmbus_setevent(struct vmbus_channel *channel)
3e7ee4902   Hank Janssen   Staging: hv: add ...
47
  {
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
48
  	struct hv_monitor_page *monitorpage;
3e7ee4902   Hank Janssen   Staging: hv: add ...
49

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
50
  	if (channel->offermsg.monitor_allocated) {
454f18a96   Bill Pemberton   Staging: hv: Remo...
51
  		/* Each u32 represents 32 channels */
223565857   Olaf Hering   staging: hv: use ...
52
  		sync_set_bit(channel->offermsg.child_relid & 31,
da9fcb726   Haiyang Zhang   staging: hv: Conv...
53
  			(unsigned long *) vmbus_connection.send_int_page +
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
54
  			(channel->offermsg.child_relid >> 5));
3e7ee4902   Hank Janssen   Staging: hv: add ...
55

da9fcb726   Haiyang Zhang   staging: hv: Conv...
56
  		monitorpage = vmbus_connection.monitor_pages;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
57
  		monitorpage++; /* Get the child to parent monitor page */
3e7ee4902   Hank Janssen   Staging: hv: add ...
58

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

f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
63
  	} else {
c69776771   Haiyang Zhang   staging: hv: Conv...
64
  		vmbus_set_event(channel->offermsg.child_relid);
3e7ee4902   Hank Janssen   Staging: hv: add ...
65
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
66
  }
3e1895195   Hank Janssen   staging: hv: Corr...
67
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
68
   * vmbus_get_debug_info -Retrieve various channel debug info
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
69
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
70
  void vmbus_get_debug_info(struct vmbus_channel *channel,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
71
  			      struct vmbus_channel_debug_info *debuginfo)
3e7ee4902   Hank Janssen   Staging: hv: add ...
72
  {
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
73
  	struct hv_monitor_page *monitorpage;
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
74
75
  	u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
  	u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
3e7ee4902   Hank Janssen   Staging: hv: add ...
76

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
77
78
79
  	debuginfo->relid = channel->offermsg.child_relid;
  	debuginfo->state = channel->state;
  	memcpy(&debuginfo->interfacetype,
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
80
  	       &channel->offermsg.offer.if_type, sizeof(uuid_le));
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
81
  	memcpy(&debuginfo->interface_instance,
767dff685   Haiyang Zhang   staging: hv: Conv...
82
  	       &channel->offermsg.offer.if_instance,
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
83
  	       sizeof(uuid_le));
3e7ee4902   Hank Janssen   Staging: hv: add ...
84

da9fcb726   Haiyang Zhang   staging: hv: Conv...
85
  	monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
3e7ee4902   Hank Janssen   Staging: hv: add ...
86

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
87
  	debuginfo->monitorid = channel->offermsg.monitorid;
3e7ee4902   Hank Janssen   Staging: hv: add ...
88

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
89
  	debuginfo->servermonitor_pending =
f6feebe07   Haiyang Zhang   staging: hv: Conv...
90
  			monitorpage->trigger_group[monitor_group].pending;
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
91
  	debuginfo->servermonitor_latency =
f6feebe07   Haiyang Zhang   staging: hv: Conv...
92
  			monitorpage->latency[monitor_group][monitor_offset];
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
93
  	debuginfo->servermonitor_connectionid =
f6feebe07   Haiyang Zhang   staging: hv: Conv...
94
95
  			monitorpage->parameter[monitor_group]
  					[monitor_offset].connectionid.u.id;
3e7ee4902   Hank Janssen   Staging: hv: add ...
96

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
97
  	monitorpage++;
3e7ee4902   Hank Janssen   Staging: hv: add ...
98

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
99
  	debuginfo->clientmonitor_pending =
f6feebe07   Haiyang Zhang   staging: hv: Conv...
100
  			monitorpage->trigger_group[monitor_group].pending;
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
101
  	debuginfo->clientmonitor_latency =
f6feebe07   Haiyang Zhang   staging: hv: Conv...
102
  			monitorpage->latency[monitor_group][monitor_offset];
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
103
  	debuginfo->clientmonitor_connectionid =
f6feebe07   Haiyang Zhang   staging: hv: Conv...
104
105
  			monitorpage->parameter[monitor_group]
  					[monitor_offset].connectionid.u.id;
3e7ee4902   Hank Janssen   Staging: hv: add ...
106

a75b61d52   K. Y. Srinivasan   Staging: hv: Rena...
107
108
  	hv_ringbuffer_get_debuginfo(&channel->inbound, &debuginfo->inbound);
  	hv_ringbuffer_get_debuginfo(&channel->outbound, &debuginfo->outbound);
3e7ee4902   Hank Janssen   Staging: hv: add ...
109
  }
3e1895195   Hank Janssen   staging: hv: Corr...
110
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
111
   * vmbus_open - Open the specified channel.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
112
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
113
  int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
114
115
  		     u32 recv_ringbuffer_size, void *userdata, u32 userdatalen,
  		     void (*onchannelcallback)(void *context), void *context)
3e7ee4902   Hank Janssen   Staging: hv: add ...
116
  {
0987ff696   K. Y. Srinivasan   Staging: hv: vmbu...
117
  	struct vmbus_channel_open_channel *open_msg;
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
118
  	struct vmbus_channel_msginfo *open_info = NULL;
3e7ee4902   Hank Janssen   Staging: hv: add ...
119
  	void *in, *out;
dd0813b6f   Greg Kroah-Hartman   Staging: hv: make...
120
  	unsigned long flags;
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
121
  	int ret, t, err = 0;
3e7ee4902   Hank Janssen   Staging: hv: add ...
122

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
123
124
  	newchannel->onchannel_callback = onchannelcallback;
  	newchannel->channel_callback_context = context;
3e7ee4902   Hank Janssen   Staging: hv: add ...
125

454f18a96   Bill Pemberton   Staging: hv: Remo...
126
  	/* Allocate the ring buffer */
df3493e0b   K. Y. Srinivasan   Staging: hv: Use ...
127
128
  	out = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
  		get_order(send_ringbuffer_size + recv_ringbuffer_size));
7e052d98f   Bill Pemberton   Staging: hv: chec...
129
130
  	if (!out)
  		return -ENOMEM;
3e7ee4902   Hank Janssen   Staging: hv: add ...
131

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
132
  	in = (void *)((unsigned long)out + send_ringbuffer_size);
3e7ee4902   Hank Janssen   Staging: hv: add ...
133

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
134
135
  	newchannel->ringbuffer_pages = out;
  	newchannel->ringbuffer_pagecount = (send_ringbuffer_size +
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
136
  					   recv_ringbuffer_size) >> PAGE_SHIFT;
3e7ee4902   Hank Janssen   Staging: hv: add ...
137

72a95cbcb   K. Y. Srinivasan   Staging: hv: Rena...
138
139
  	ret = hv_ringbuffer_init(
  		&newchannel->outbound, out, send_ringbuffer_size);
fd4dc88e4   Haiyang Zhang   staging: hv: Fix ...
140
  	if (ret != 0) {
3324fb405   Bill Pemberton   staging: hv: chec...
141
142
143
  		err = ret;
  		goto errorout;
  	}
72a95cbcb   K. Y. Srinivasan   Staging: hv: Rena...
144
145
  	ret = hv_ringbuffer_init(
  		&newchannel->inbound, in, recv_ringbuffer_size);
fd4dc88e4   Haiyang Zhang   staging: hv: Fix ...
146
  	if (ret != 0) {
3324fb405   Bill Pemberton   staging: hv: chec...
147
148
149
  		err = ret;
  		goto errorout;
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
150

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

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

fff41b2e3   Haiyang Zhang   staging: hv: Rena...
155
  	ret = vmbus_establish_gpadl(newchannel,
82f8bd40a   Haiyang Zhang   staging: hv: Conv...
156
  					 newchannel->outbound.ring_buffer,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
157
158
  					 send_ringbuffer_size +
  					 recv_ringbuffer_size,
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
159
  					 &newchannel->ringbuffer_gpadlhandle);
b94ef345b   Bill Pemberton   Staging: hv: test...
160

fd4dc88e4   Haiyang Zhang   staging: hv: Fix ...
161
  	if (ret != 0) {
b94ef345b   Bill Pemberton   Staging: hv: test...
162
163
164
  		err = ret;
  		goto errorout;
  	}
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
165

454f18a96   Bill Pemberton   Staging: hv: Remo...
166
  	/* Create and init the channel open message */
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
167
  	open_info = kmalloc(sizeof(*open_info) +
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
168
169
  			   sizeof(struct vmbus_channel_open_channel),
  			   GFP_KERNEL);
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
170
  	if (!open_info) {
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
171
172
173
  		err = -ENOMEM;
  		goto errorout;
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
174

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

176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
177
  	open_msg = (struct vmbus_channel_open_channel *)open_info->msg;
0987ff696   K. Y. Srinivasan   Staging: hv: vmbu...
178
179
180
181
182
  	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...
183
  						  PAGE_SHIFT;
0987ff696   K. Y. Srinivasan   Staging: hv: vmbu...
184
  	open_msg->server_contextarea_gpadlhandle = 0;
3e7ee4902   Hank Janssen   Staging: hv: add ...
185

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
186
  	if (userdatalen > MAX_USER_DEFINED_BYTES) {
c827f944f   Bill Pemberton   Staging: hv: remo...
187
188
189
  		err = -EINVAL;
  		goto errorout;
  	}
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
190
  	if (userdatalen)
0987ff696   K. Y. Srinivasan   Staging: hv: vmbu...
191
  		memcpy(open_msg->userdata, userdata, userdatalen);
3e7ee4902   Hank Janssen   Staging: hv: add ...
192

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

0987ff696   K. Y. Srinivasan   Staging: hv: vmbu...
198
  	ret = vmbus_post_msg(open_msg,
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
199
  			       sizeof(struct vmbus_channel_open_channel));
98e087022   Hank Janssen   staging: hv: Remo...
200
201
  
  	if (ret != 0)
00d760b05   K. Y. Srinivasan   Staging: hv: vmbu...
202
  		goto cleanup;
3e7ee4902   Hank Janssen   Staging: hv: add ...
203

176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
204
  	t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
205
  	if (t == 0) {
0c3b7b2f7   K. Y. Srinivasan   Staging: hv: Use ...
206
207
208
  		err = -ETIMEDOUT;
  		goto errorout;
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
209

176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
210
211
  	if (open_info->response.open_result.status)
  		err = open_info->response.open_result.status;
3e7ee4902   Hank Janssen   Staging: hv: add ...
212

00d760b05   K. Y. Srinivasan   Staging: hv: vmbu...
213
  cleanup:
15b2f6479   Haiyang Zhang   staging: hv: Conv...
214
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
215
  	list_del(&open_info->msglistentry);
15b2f6479   Haiyang Zhang   staging: hv: Conv...
216
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
217

176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
218
  	kfree(open_info);
98e087022   Hank Janssen   staging: hv: Remo...
219
  	return err;
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
220
221
  
  errorout:
2dba688ba   K. Y. Srinivasan   Staging: hv: Rena...
222
223
  	hv_ringbuffer_cleanup(&newchannel->outbound);
  	hv_ringbuffer_cleanup(&newchannel->inbound);
df3493e0b   K. Y. Srinivasan   Staging: hv: Use ...
224
225
  	free_pages((unsigned long)out,
  		get_order(send_ringbuffer_size + recv_ringbuffer_size));
176fb9e3f   K. Y. Srinivasan   Staging: hv: vmbu...
226
  	kfree(open_info);
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
227
  	return err;
3e7ee4902   Hank Janssen   Staging: hv: add ...
228
  }
36ceadfc6   Greg Kroah-Hartman   Staging: hv: chan...
229
  EXPORT_SYMBOL_GPL(vmbus_open);
3e7ee4902   Hank Janssen   Staging: hv: add ...
230

3e1895195   Hank Janssen   staging: hv: Corr...
231
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
232
   * create_gpadl_header - Creates a gpadl for the specified buffer
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
233
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
234
  static int create_gpadl_header(void *kbuffer, u32 size,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
235
236
  					 struct vmbus_channel_msginfo **msginfo,
  					 u32 *messagecount)
3e7ee4902   Hank Janssen   Staging: hv: add ...
237
238
  {
  	int i;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
239
  	int pagecount;
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
240
  	unsigned long long pfn;
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
250
  	pagecount = size >> PAGE_SHIFT;
  	pfn = virt_to_phys(kbuffer) >> PAGE_SHIFT;
3e7ee4902   Hank Janssen   Staging: hv: add ...
251

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

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

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

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

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

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

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

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
298
  			msgsize = sizeof(struct vmbus_channel_msginfo) +
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
299
  				  sizeof(struct vmbus_channel_gpadl_body) +
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
300
301
  				  pfncurr * sizeof(u64);
  			msgbody = kzalloc(msgsize, GFP_KERNEL);
f38cf9ccd   K. Y. Srinivasan   Staging: hv: vmbu...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
  
  			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...
316
  				goto nomem;
f38cf9ccd   K. Y. Srinivasan   Staging: hv: vmbu...
317
  			}
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
318
  			msgbody->msgsize = msgsize;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
319
320
  			(*messagecount)++;
  			gpadl_body =
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
321
  				(struct vmbus_channel_gpadl_body *)msgbody->msg;
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
322
323
  
  			/*
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
324
325
  			 * Gpadl is u32 and we are using a pointer which could
  			 * be 64-bit
f27df643d   K. Y. Srinivasan   Staging: hv: vmbu...
326
327
  			 * This is governed by the guest/host protocol and
  			 * so the hypervisor gurantees that this is ok.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
328
  			 */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
329
  			for (i = 0; i < pfncurr; i++)
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
330
  				gpadl_body->pfn[i] = pfn + pfnsum + i;
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;
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
346
  		msgheader->msgsize = msgsize;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
347
348
  
  		gpadl_header = (struct vmbus_channel_gpadl_header *)
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
349
350
351
  			msgheader->msg;
  		gpadl_header->rangecount = 1;
  		gpadl_header->range_buflen = sizeof(struct gpa_range) +
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
352
  					 pagecount * sizeof(u64);
415f22871   Haiyang Zhang   staging: hv: Conv...
353
354
  		gpadl_header->range[0].byte_offset = 0;
  		gpadl_header->range[0].byte_count = size;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
355
  		for (i = 0; i < pagecount; i++)
415f22871   Haiyang Zhang   staging: hv: Conv...
356
  			gpadl_header->range[0].pfn_array[i] = pfn+i;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
357
358
359
  
  		*msginfo = msgheader;
  		*messagecount = 1;
3e7ee4902   Hank Janssen   Staging: hv: add ...
360
361
362
  	}
  
  	return 0;
d1c250bb5   Bill Pemberton   Staging: hv: remo...
363
  nomem:
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
364
365
  	kfree(msgheader);
  	kfree(msgbody);
d1c250bb5   Bill Pemberton   Staging: hv: remo...
366
  	return -ENOMEM;
3e7ee4902   Hank Janssen   Staging: hv: add ...
367
  }
3e1895195   Hank Janssen   staging: hv: Corr...
368
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
369
   * vmbus_establish_gpadl - Estabish a GPADL for the specified buffer
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
370
   *
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
371
372
373
374
   * @channel: a channel
   * @kbuffer: from kmalloc
   * @size: page-size multiple
   * @gpadl_handle: some funky thing
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
375
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
376
  int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
377
  			       u32 size, u32 *gpadl_handle)
3e7ee4902   Hank Janssen   Staging: hv: add ...
378
  {
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
379
380
  	struct vmbus_channel_gpadl_header *gpadlmsg;
  	struct vmbus_channel_gpadl_body *gpadl_body;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
381
382
383
  	struct vmbus_channel_msginfo *msginfo = NULL;
  	struct vmbus_channel_msginfo *submsginfo;
  	u32 msgcount;
53af545b2   Bill Pemberton   Staging: hv: remo...
384
  	struct list_head *curr;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
385
  	u32 next_gpadl_handle;
dd0813b6f   Greg Kroah-Hartman   Staging: hv: make...
386
  	unsigned long flags;
c3bf2e26b   Bill Pemberton   Staging: hv: remo...
387
  	int ret = 0;
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
388
  	int t;
3e7ee4902   Hank Janssen   Staging: hv: add ...
389

da9fcb726   Haiyang Zhang   staging: hv: Conv...
390
391
  	next_gpadl_handle = atomic_read(&vmbus_connection.next_gpadl_handle);
  	atomic_inc(&vmbus_connection.next_gpadl_handle);
3e7ee4902   Hank Janssen   Staging: hv: add ...
392

fff41b2e3   Haiyang Zhang   staging: hv: Rena...
393
  	ret = create_gpadl_header(kbuffer, size, &msginfo, &msgcount);
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

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
416
  	if (msgcount > 1) {
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
417
  		list_for_each(curr, &msginfo->submsglist) {
53af545b2   Bill Pemberton   Staging: hv: remo...
418

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
419
420
  			submsginfo = (struct vmbus_channel_msginfo *)curr;
  			gpadl_body =
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
421
  			     (struct vmbus_channel_gpadl_body *)submsginfo->msg;
3e7ee4902   Hank Janssen   Staging: hv: add ...
422

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
423
424
425
  			gpadl_body->header.msgtype =
  				CHANNELMSG_GPADL_BODY;
  			gpadl_body->gpadl = next_gpadl_handle;
3e7ee4902   Hank Janssen   Staging: hv: add ...
426

c69776771   Haiyang Zhang   staging: hv: Conv...
427
  			ret = vmbus_post_msg(gpadl_body,
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
428
  					       submsginfo->msgsize -
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
429
  					       sizeof(*submsginfo));
fd4dc88e4   Haiyang Zhang   staging: hv: Fix ...
430
  			if (ret != 0)
00d760b05   K. Y. Srinivasan   Staging: hv: vmbu...
431
  				goto cleanup;
99259159c   Bill Pemberton   Staging: hv: remo...
432

3e7ee4902   Hank Janssen   Staging: hv: add ...
433
434
  		}
  	}
40961de33   K. Y. Srinivasan   Staging: hv: vmbu...
435
  	t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
436
  	BUG_ON(t == 0);
0c3b7b2f7   K. Y. Srinivasan   Staging: hv: Use ...
437

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

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

00d760b05   K. Y. Srinivasan   Staging: hv: vmbu...
442
  cleanup:
15b2f6479   Haiyang Zhang   staging: hv: Conv...
443
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
444
  	list_del(&msginfo->msglistentry);
15b2f6479   Haiyang Zhang   staging: hv: Conv...
445
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
446

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

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

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

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

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

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

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

0c3b7b2f7   K. Y. Srinivasan   Staging: hv: Use ...
482
  	BUG_ON(ret != 0);
40961de33   K. Y. Srinivasan   Staging: hv: vmbu...
483
  	t = wait_for_completion_timeout(&info->waitevent, 5*HZ);
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
484
  	BUG_ON(t == 0);
3e7ee4902   Hank Janssen   Staging: hv: add ...
485

454f18a96   Bill Pemberton   Staging: hv: Remo...
486
  	/* Received a torndown response */
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

3e1895195   Hank Janssen   staging: hv: Corr...
496
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
497
   * vmbus_close - Close the specified channel
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
498
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
499
  void vmbus_close(struct vmbus_channel *channel)
3e7ee4902   Hank Janssen   Staging: hv: add ...
500
  {
82250213d   Greg Kroah-Hartman   Staging: hv: type...
501
  	struct vmbus_channel_close_channel *msg;
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
502
  	int ret;
dad76bf73   K. Y. Srinivasan   Staging: hv: vmbu...
503
  	unsigned long flags;
3e7ee4902   Hank Janssen   Staging: hv: add ...
504

454f18a96   Bill Pemberton   Staging: hv: Remo...
505
  	/* Stop callback and cancel the timer asap */
dad76bf73   K. Y. Srinivasan   Staging: hv: vmbu...
506
  	spin_lock_irqsave(&channel->inbound_lock, flags);
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
507
  	channel->onchannel_callback = NULL;
dad76bf73   K. Y. Srinivasan   Staging: hv: vmbu...
508
  	spin_unlock_irqrestore(&channel->inbound_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
509

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

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

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

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

0c3b7b2f7   K. Y. Srinivasan   Staging: hv: Use ...
519
  	BUG_ON(ret != 0);
454f18a96   Bill Pemberton   Staging: hv: Remo...
520
  	/* Tear down the gpadl for the channel's ring buffer */
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
521
  	if (channel->ringbuffer_gpadlhandle)
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
522
  		vmbus_teardown_gpadl(channel,
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
523
  					  channel->ringbuffer_gpadlhandle);
3e7ee4902   Hank Janssen   Staging: hv: add ...
524

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

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

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

3e7ee4902   Hank Janssen   Staging: hv: add ...
533
  }
70bfa3078   Greg Kroah-Hartman   Staging: hv: chan...
534
  EXPORT_SYMBOL_GPL(vmbus_close);
3e7ee4902   Hank Janssen   Staging: hv: add ...
535

c88c4e4c7   Hank Janssen   Staging: hv: Adde...
536
  /**
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
537
   * vmbus_sendpacket() - Send the specified buffer on the given channel
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
538
539
540
541
542
   * @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
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
543
544
   * packet etc.
   *
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
545
   * Sends data in @buffer directly to hyper-v via the vmbus
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
546
547
548
   * This will send the data unparsed to hyper-v.
   *
   * Mainly used by Hyper-V drivers.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
549
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
550
  int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
551
552
  			   u32 bufferlen, u64 requestid,
  			   enum vmbus_packet_type type, u32 flags)
3e7ee4902   Hank Janssen   Staging: hv: add ...
553
  {
8dc0a06ad   Greg Kroah-Hartman   Staging: hv: remo...
554
  	struct vmpacket_descriptor desc;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
555
  	u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen;
735096819   Uwe Kleine-König   staging/hv/osd: d...
556
  	u32 packetlen_aligned = ALIGN(packetlen, sizeof(u64));
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
557
558
  	struct scatterlist bufferlist[3];
  	u64 aligned_data = 0;
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
559
  	int ret;
3e7ee4902   Hank Janssen   Staging: hv: add ...
560

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

454f18a96   Bill Pemberton   Staging: hv: Remo...
562
  	/* Setup the descriptor */
415f22871   Haiyang Zhang   staging: hv: Conv...
563
564
  	desc.type = type; /* VmbusPacketTypeDataInBand; */
  	desc.flags = flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
565
  	/* in 8-bytes granularity */
415f22871   Haiyang Zhang   staging: hv: Conv...
566
567
568
  	desc.offset8 = sizeof(struct vmpacket_descriptor) >> 3;
  	desc.len8 = (u16)(packetlen_aligned >> 3);
  	desc.trans_id = requestid;
3e7ee4902   Hank Janssen   Staging: hv: add ...
569

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
570
571
572
573
574
  	sg_init_table(bufferlist, 3);
  	sg_set_buf(&bufferlist[0], &desc, sizeof(struct vmpacket_descriptor));
  	sg_set_buf(&bufferlist[1], buffer, bufferlen);
  	sg_set_buf(&bufferlist[2], &aligned_data,
  		   packetlen_aligned - packetlen);
3e7ee4902   Hank Janssen   Staging: hv: add ...
575

633c4dce4   K. Y. Srinivasan   Staging: hv: Rena...
576
  	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
3e7ee4902   Hank Janssen   Staging: hv: add ...
577

decc49dac   K. Y. Srinivasan   Staging: hv: Rena...
578
  	if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
579
  		vmbus_setevent(channel);
3e7ee4902   Hank Janssen   Staging: hv: add ...
580

3e7ee4902   Hank Janssen   Staging: hv: add ...
581
582
  	return ret;
  }
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
583
  EXPORT_SYMBOL(vmbus_sendpacket);
3e7ee4902   Hank Janssen   Staging: hv: add ...
584

3e1895195   Hank Janssen   staging: hv: Corr...
585
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
586
   * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
3e1895195   Hank Janssen   staging: hv: Corr...
587
   * packets using a GPADL Direct packet type.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
588
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
589
  int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
590
591
592
  				     struct hv_page_buffer pagebuffers[],
  				     u32 pagecount, void *buffer, u32 bufferlen,
  				     u64 requestid)
3e7ee4902   Hank Janssen   Staging: hv: add ...
593
  {
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
594
595
  	int ret;
  	int i;
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
596
  	struct vmbus_channel_packet_page_buffer desc;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
597
598
599
600
601
  	u32 descsize;
  	u32 packetlen;
  	u32 packetlen_aligned;
  	struct scatterlist bufferlist[3];
  	u64 aligned_data = 0;
3e7ee4902   Hank Janssen   Staging: hv: add ...
602

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

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

f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
607
  	/*
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
608
  	 * Adjust the size down since vmbus_channel_packet_page_buffer is the
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
609
610
  	 * largest size we support
  	 */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
611
612
  	descsize = sizeof(struct vmbus_channel_packet_page_buffer) -
  			  ((MAX_PAGE_BUFFER_COUNT - pagecount) *
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
613
  			  sizeof(struct hv_page_buffer));
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
614
  	packetlen = descsize + bufferlen;
735096819   Uwe Kleine-König   staging/hv/osd: d...
615
  	packetlen_aligned = ALIGN(packetlen, sizeof(u64));
3e7ee4902   Hank Janssen   Staging: hv: add ...
616

454f18a96   Bill Pemberton   Staging: hv: Remo...
617
  	/* Setup the descriptor */
415f22871   Haiyang Zhang   staging: hv: Conv...
618
  	desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
619
  	desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
620
621
622
623
624
625
  	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...
626
627
628
  		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 ...
629
  	}
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
630
631
632
633
634
  	sg_init_table(bufferlist, 3);
  	sg_set_buf(&bufferlist[0], &desc, descsize);
  	sg_set_buf(&bufferlist[1], buffer, bufferlen);
  	sg_set_buf(&bufferlist[2], &aligned_data,
  		packetlen_aligned - packetlen);
3e7ee4902   Hank Janssen   Staging: hv: add ...
635

633c4dce4   K. Y. Srinivasan   Staging: hv: Rena...
636
  	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
3e7ee4902   Hank Janssen   Staging: hv: add ...
637

decc49dac   K. Y. Srinivasan   Staging: hv: Rena...
638
  	if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
639
  		vmbus_setevent(channel);
3e7ee4902   Hank Janssen   Staging: hv: add ...
640

3e7ee4902   Hank Janssen   Staging: hv: add ...
641
642
  	return ret;
  }
713efeb4d   Greg Kroah-Hartman   Staging: hv: chan...
643
  EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
3e7ee4902   Hank Janssen   Staging: hv: add ...
644

3e1895195   Hank Janssen   staging: hv: Corr...
645
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
646
   * vmbus_sendpacket_multipagebuffer - Send a multi-page buffer packet
3e1895195   Hank Janssen   staging: hv: Corr...
647
   * using a GPADL Direct packet type.
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
648
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
649
  int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
650
651
  				struct hv_multipage_buffer *multi_pagebuffer,
  				void *buffer, u32 bufferlen, u64 requestid)
3e7ee4902   Hank Janssen   Staging: hv: add ...
652
  {
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
653
  	int ret;
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
654
  	struct vmbus_channel_packet_multipage_buffer desc;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
655
656
657
658
659
  	u32 descsize;
  	u32 packetlen;
  	u32 packetlen_aligned;
  	struct scatterlist bufferlist[3];
  	u64 aligned_data = 0;
ca623ad35   Haiyang Zhang   staging: hv: Conv...
660
661
  	u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset,
  					 multi_pagebuffer->len);
3e7ee4902   Hank Janssen   Staging: hv: add ...
662

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

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
664
  	if ((pfncount < 0) || (pfncount > MAX_MULTIPAGE_BUFFER_COUNT))
002b53ea5   Bill Pemberton   Staging: hv: retu...
665
  		return -EINVAL;
3e7ee4902   Hank Janssen   Staging: hv: add ...
666

f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
667
  	/*
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
668
  	 * Adjust the size down since vmbus_channel_packet_multipage_buffer is
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
669
670
  	 * the largest size we support
  	 */
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
671
672
  	descsize = sizeof(struct vmbus_channel_packet_multipage_buffer) -
  			  ((MAX_MULTIPAGE_BUFFER_COUNT - pfncount) *
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
673
  			  sizeof(u64));
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
674
  	packetlen = descsize + bufferlen;
735096819   Uwe Kleine-König   staging/hv/osd: d...
675
  	packetlen_aligned = ALIGN(packetlen, sizeof(u64));
3e7ee4902   Hank Janssen   Staging: hv: add ...
676

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

454f18a96   Bill Pemberton   Staging: hv: Remo...
678
  	/* Setup the descriptor */
415f22871   Haiyang Zhang   staging: hv: Conv...
679
  	desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
680
  	desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
681
682
683
  	desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */
  	desc.length8 = (u16)(packetlen_aligned >> 3);
  	desc.transactionid = requestid;
430a8e9a3   Haiyang Zhang   staging: hv: Remo...
684
  	desc.rangecount = 1;
3e7ee4902   Hank Janssen   Staging: hv: add ...
685

ca623ad35   Haiyang Zhang   staging: hv: Conv...
686
687
  	desc.range.len = multi_pagebuffer->len;
  	desc.range.offset = multi_pagebuffer->offset;
3e7ee4902   Hank Janssen   Staging: hv: add ...
688

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

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
692
693
694
695
696
  	sg_init_table(bufferlist, 3);
  	sg_set_buf(&bufferlist[0], &desc, descsize);
  	sg_set_buf(&bufferlist[1], buffer, bufferlen);
  	sg_set_buf(&bufferlist[2], &aligned_data,
  		packetlen_aligned - packetlen);
3e7ee4902   Hank Janssen   Staging: hv: add ...
697

633c4dce4   K. Y. Srinivasan   Staging: hv: Rena...
698
  	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
3e7ee4902   Hank Janssen   Staging: hv: add ...
699

decc49dac   K. Y. Srinivasan   Staging: hv: Rena...
700
  	if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
701
  		vmbus_setevent(channel);
3e7ee4902   Hank Janssen   Staging: hv: add ...
702

3e7ee4902   Hank Janssen   Staging: hv: add ...
703
704
  	return ret;
  }
4cb106faf   Greg Kroah-Hartman   Staging: hv: chan...
705
  EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
706
707
  
  /**
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
708
   * vmbus_recvpacket() - Retrieve the user packet on the specified channel
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
709
710
711
712
713
   * @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...
714
715
716
717
718
   *
   * 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...
719
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
720
  int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
721
  			u32 bufferlen, u32 *buffer_actual_len, u64 *requestid)
3e7ee4902   Hank Janssen   Staging: hv: add ...
722
  {
8dc0a06ad   Greg Kroah-Hartman   Staging: hv: remo...
723
  	struct vmpacket_descriptor desc;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
724
725
  	u32 packetlen;
  	u32 userlen;
3e7ee4902   Hank Janssen   Staging: hv: add ...
726
  	int ret;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
727
728
  	*buffer_actual_len = 0;
  	*requestid = 0;
3e7ee4902   Hank Janssen   Staging: hv: add ...
729

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

a89186c21   K. Y. Srinivasan   Staging: hv: Rena...
731
  	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
732
  			     sizeof(struct vmpacket_descriptor));
dad76bf73   K. Y. Srinivasan   Staging: hv: vmbu...
733
  	if (ret != 0)
3e7ee4902   Hank Janssen   Staging: hv: add ...
734
  		return 0;
3e7ee4902   Hank Janssen   Staging: hv: add ...
735

415f22871   Haiyang Zhang   staging: hv: Conv...
736
737
  	packetlen = desc.len8 << 3;
  	userlen = packetlen - (desc.offset8 << 3);
3e7ee4902   Hank Janssen   Staging: hv: add ...
738

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
739
  	*buffer_actual_len = userlen;
3e7ee4902   Hank Janssen   Staging: hv: add ...
740

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
741
  	if (userlen > bufferlen) {
3e7ee4902   Hank Janssen   Staging: hv: add ...
742

0a46618d5   Hank Janssen   staging: hv: Repl...
743
744
  		pr_err("Buffer too small - got %d needs %d
  ",
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
745
  			   bufferlen, userlen);
926ae5262   K. Y. Srinivasan   Staging: hv: vmbu...
746
  		return -ETOOSMALL;
3e7ee4902   Hank Janssen   Staging: hv: add ...
747
  	}
415f22871   Haiyang Zhang   staging: hv: Conv...
748
  	*requestid = desc.trans_id;
3e7ee4902   Hank Janssen   Staging: hv: add ...
749

454f18a96   Bill Pemberton   Staging: hv: Remo...
750
  	/* Copy over the packet to the user buffer */
38397c8ab   K. Y. Srinivasan   Staging: hv: Rena...
751
  	ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
415f22871   Haiyang Zhang   staging: hv: Conv...
752
  			     (desc.offset8 << 3));
3e7ee4902   Hank Janssen   Staging: hv: add ...
753

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

3e7ee4902   Hank Janssen   Staging: hv: add ...
755
756
  	return 0;
  }
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
757
  EXPORT_SYMBOL(vmbus_recvpacket);
3e7ee4902   Hank Janssen   Staging: hv: add ...
758

3e1895195   Hank Janssen   staging: hv: Corr...
759
  /*
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
760
   * vmbus_recvpacket_raw - Retrieve the raw packet on the specified channel
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
761
   */
fff41b2e3   Haiyang Zhang   staging: hv: Rena...
762
  int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
763
764
  			      u32 bufferlen, u32 *buffer_actual_len,
  			      u64 *requestid)
3e7ee4902   Hank Janssen   Staging: hv: add ...
765
  {
8dc0a06ad   Greg Kroah-Hartman   Staging: hv: remo...
766
  	struct vmpacket_descriptor desc;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
767
768
  	u32 packetlen;
  	u32 userlen;
3e7ee4902   Hank Janssen   Staging: hv: add ...
769
  	int ret;
39d70a4ab   Haiyang Zhang   staging: hv: Remo...
770
771
  	*buffer_actual_len = 0;
  	*requestid = 0;
3e7ee4902   Hank Janssen   Staging: hv: add ...
772

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

a89186c21   K. Y. Srinivasan   Staging: hv: Rena...
774
  	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
f4266e342   Greg Kroah-Hartman   Staging: hv: codi...
775
  			     sizeof(struct vmpacket_descriptor));
dad76bf73   K. Y. Srinivasan   Staging: hv: vmbu...
776
  	if (ret != 0)
3e7ee4902   Hank Janssen   Staging: hv: add ...
777
  		return 0;
3e7ee4902   Hank Janssen   Staging: hv: add ...
778

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

415f22871   Haiyang Zhang   staging: hv: Conv...
780
781
  	packetlen = desc.len8 << 3;
  	userlen = packetlen - (desc.offset8 << 3);
3e7ee4902   Hank Janssen   Staging: hv: add ...
782

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
783
  	*buffer_actual_len = packetlen;
3e7ee4902   Hank Janssen   Staging: hv: add ...
784

39d70a4ab   Haiyang Zhang   staging: hv: Remo...
785
  	if (packetlen > bufferlen) {
0a46618d5   Hank Janssen   staging: hv: Repl...
786
787
788
789
  		pr_err("Buffer too small - needed %d bytes but "
  			"got space for only %d bytes
  ",
  			packetlen, bufferlen);
3d5cad97c   K. Y. Srinivasan   Staging: hv: vmbu...
790
  		return -ENOBUFS;
3e7ee4902   Hank Janssen   Staging: hv: add ...
791
  	}
415f22871   Haiyang Zhang   staging: hv: Conv...
792
  	*requestid = desc.trans_id;
3e7ee4902   Hank Janssen   Staging: hv: add ...
793

454f18a96   Bill Pemberton   Staging: hv: Remo...
794
  	/* Copy over the entire packet to the user buffer */
38397c8ab   K. Y. Srinivasan   Staging: hv: Rena...
795
  	ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
3e7ee4902   Hank Janssen   Staging: hv: add ...
796

3e7ee4902   Hank Janssen   Staging: hv: add ...
797
798
  	return 0;
  }
adaee6bd4   Greg Kroah-Hartman   Staging: hv: chan...
799
  EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);