Blame view

drivers/hv/channel_mgmt.c 17.4 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
a0086dc51   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>
53af545b2   Bill Pemberton   Staging: hv: remo...
27
  #include <linux/list.h>
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
28
  #include <linux/module.h>
8b5d6d3bd   Haiyang Zhang   staging: hv: Fix ...
29
  #include <linux/completion.h>
46a971913   Greg Kroah-Hartman   Staging: hv: move...
30
  #include <linux/hyperv.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

1d7e907fb   Greg Kroah-Hartman   Staging: hv: remo...
34
  struct vmbus_channel_message_table_entry {
cf9dcba7f   K. Y. Srinivasan   Staging: hv: vmbu...
35
  	enum vmbus_channel_message_type message_type;
fa90f1de2   K. Y. Srinivasan   Staging: hv: vmbu...
36
  	void (*message_handler)(struct vmbus_channel_message_header *msg);
1d7e907fb   Greg Kroah-Hartman   Staging: hv: remo...
37
  };
3e7ee4902   Hank Janssen   Staging: hv: add ...
38

245ba56a5   Ky Srinivasan   Staging: hv: Impl...
39
40
  #define MAX_MSG_TYPES                    4
  #define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
41

358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
42
  static const uuid_le
50b03266b   K. Y. Srinivasan   Staging: hv: vmbu...
43
  	supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
454f18a96   Bill Pemberton   Staging: hv: Remo...
44
  	/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
caf26a31b   Greg Kroah-Hartman   Staging: hv: osd....
45
46
  	/* Storage - SCSI */
  	{
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
47
  		.b  = {
caf26a31b   Greg Kroah-Hartman   Staging: hv: osd....
48
49
50
51
  			0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
  			0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
  		}
  	},
454f18a96   Bill Pemberton   Staging: hv: Remo...
52
  	/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
caf26a31b   Greg Kroah-Hartman   Staging: hv: osd....
53
54
  	/* Network */
  	{
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
55
  		.b = {
caf26a31b   Greg Kroah-Hartman   Staging: hv: osd....
56
57
58
59
  			0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
  			0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
  		}
  	},
454f18a96   Bill Pemberton   Staging: hv: Remo...
60
  	/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
caf26a31b   Greg Kroah-Hartman   Staging: hv: osd....
61
62
  	/* Input */
  	{
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
63
  		.b = {
caf26a31b   Greg Kroah-Hartman   Staging: hv: osd....
64
65
66
67
  			0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
  			0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A
  		}
  	},
3e7ee4902   Hank Janssen   Staging: hv: add ...
68

caf26a31b   Greg Kroah-Hartman   Staging: hv: osd....
69
70
71
  	/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
  	/* IDE */
  	{
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
72
  		.b = {
caf26a31b   Greg Kroah-Hartman   Staging: hv: osd....
73
74
75
76
  			0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
  			0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
  		}
  	},
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
77
78
79
  	/* 0E0B6031-5213-4934-818B-38D90CED39DB */
  	/* Shutdown */
  	{
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
80
  		.b = {
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
81
82
83
84
  			0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
  			0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
  		}
  	},
39c4e9c37   Haiyang Zhang   Staging: hv: Add ...
85
86
87
  	/* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
  	/* TimeSync */
  	{
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
88
  		.b = {
39c4e9c37   Haiyang Zhang   Staging: hv: Add ...
89
90
91
92
  			0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
  			0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
  		}
  	},
9153f7b99   Hank Janssen   staging: hv: Adde...
93
94
95
  	/* {57164f39-9115-4e78-ab55-382f3bd5422d} */
  	/* Heartbeat */
  	{
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
96
  		.b = {
9153f7b99   Hank Janssen   staging: hv: Adde...
97
98
99
100
  			0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
  			0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
  		}
  	},
245ba56a5   Ky Srinivasan   Staging: hv: Impl...
101
102
103
  	/* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
  	/* KVP */
  	{
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
104
  		.b = {
245ba56a5   Ky Srinivasan   Staging: hv: Impl...
105
106
107
108
  			0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
  			0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3,  0xe6
  	}
  	},
3e7ee4902   Hank Janssen   Staging: hv: add ...
109
  };
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
110
111
  
  /**
da0e96315   Greg Kroah-Hartman   hv: rename prep_n...
112
   * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
113
114
115
116
117
118
119
120
121
122
123
124
125
   * @icmsghdrp: Pointer to msg header structure
   * @icmsg_negotiate: Pointer to negotiate message structure
   * @buf: Raw buffer channel data
   *
   * @icmsghdrp is of type &struct icmsg_hdr.
   * @negop is of type &struct icmsg_negotiate.
   * Set up and fill in default negotiate response message. This response can
   * come from both the vmbus driver and the hv_utils driver. The current api
   * will respond properly to both Windows 2008 and Windows 2008-R2 operating
   * systems.
   *
   * Mainly used by Hyper-V drivers.
   */
da0e96315   Greg Kroah-Hartman   hv: rename prep_n...
126
127
  void vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
  			       struct icmsg_negotiate *negop, u8 *buf)
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
  {
  	if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
  		icmsghdrp->icmsgsize = 0x10;
  
  		negop = (struct icmsg_negotiate *)&buf[
  			sizeof(struct vmbuspipe_hdr) +
  			sizeof(struct icmsg_hdr)];
  
  		if (negop->icframe_vercnt == 2 &&
  		   negop->icversion_data[1].major == 3) {
  			negop->icversion_data[0].major = 3;
  			negop->icversion_data[0].minor = 0;
  			negop->icversion_data[1].major = 3;
  			negop->icversion_data[1].minor = 0;
  		} else {
  			negop->icversion_data[0].major = 1;
  			negop->icversion_data[0].minor = 0;
  			negop->icversion_data[1].major = 1;
  			negop->icversion_data[1].minor = 0;
  		}
  
  		negop->icframe_vercnt = 1;
  		negop->icmsg_vercnt = 1;
  	}
  }
da0e96315   Greg Kroah-Hartman   hv: rename prep_n...
153
  EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
154

3e1895195   Hank Janssen   staging: hv: Corr...
155
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
156
   * alloc_channel - Allocate and initialize a vmbus channel object
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
157
   */
50fe56d24   Greg Kroah-Hartman   Staging: hv: make...
158
  static struct vmbus_channel *alloc_channel(void)
3e7ee4902   Hank Janssen   Staging: hv: add ...
159
  {
aded7165f   Greg Kroah-Hartman   Staging: hv: clea...
160
  	struct vmbus_channel *channel;
3e7ee4902   Hank Janssen   Staging: hv: add ...
161

aded7165f   Greg Kroah-Hartman   Staging: hv: clea...
162
  	channel = kzalloc(sizeof(*channel), GFP_ATOMIC);
3e7ee4902   Hank Janssen   Staging: hv: add ...
163
  	if (!channel)
3e7ee4902   Hank Janssen   Staging: hv: add ...
164
  		return NULL;
3e7ee4902   Hank Janssen   Staging: hv: add ...
165

54411c425   Greg Kroah-Hartman   Staging: hv: make...
166
  	spin_lock_init(&channel->inbound_lock);
3e7ee4902   Hank Janssen   Staging: hv: add ...
167

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
168
169
  	channel->controlwq = create_workqueue("hv_vmbus_ctl");
  	if (!channel->controlwq) {
8c69f52ab   Greg Kroah-Hartman   Staging: hv: osd:...
170
  		kfree(channel);
3e7ee4902   Hank Janssen   Staging: hv: add ...
171
172
173
174
175
  		return NULL;
  	}
  
  	return channel;
  }
3e1895195   Hank Janssen   staging: hv: Corr...
176
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
177
   * release_hannel - Release the vmbus channel object itself
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
178
   */
4b2f9abea   Timo Teräs   staging: hv: conv...
179
  static void release_channel(struct work_struct *work)
3e7ee4902   Hank Janssen   Staging: hv: add ...
180
  {
4b2f9abea   Timo Teräs   staging: hv: conv...
181
182
183
  	struct vmbus_channel *channel = container_of(work,
  						     struct vmbus_channel,
  						     work);
3e7ee4902   Hank Janssen   Staging: hv: add ...
184

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
185
  	destroy_workqueue(channel->controlwq);
3e7ee4902   Hank Janssen   Staging: hv: add ...
186

8c69f52ab   Greg Kroah-Hartman   Staging: hv: osd:...
187
  	kfree(channel);
3e7ee4902   Hank Janssen   Staging: hv: add ...
188
  }
3e1895195   Hank Janssen   staging: hv: Corr...
189
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
190
   * free_channel - Release the resources used by the vmbus channel object
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
191
   */
9f3e28e37   Greg Kroah-Hartman   hv: remove free_c...
192
  static void free_channel(struct vmbus_channel *channel)
3e7ee4902   Hank Janssen   Staging: hv: add ...
193
  {
3e7ee4902   Hank Janssen   Staging: hv: add ...
194

bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
195
196
197
198
199
  	/*
  	 * We have to release the channel's workqueue/thread in the vmbus's
  	 * workqueue/thread context
  	 * ie we can't destroy ourselves.
  	 */
4b2f9abea   Timo Teräs   staging: hv: conv...
200
  	INIT_WORK(&channel->work, release_channel);
da9fcb726   Haiyang Zhang   staging: hv: Conv...
201
  	queue_work(vmbus_connection.work_queue, &channel->work);
3e7ee4902   Hank Janssen   Staging: hv: add ...
202
  }
8b5d6d3bd   Haiyang Zhang   staging: hv: Fix ...
203

8b5d6d3bd   Haiyang Zhang   staging: hv: Fix ...
204

4b2f9abea   Timo Teräs   staging: hv: conv...
205
206
207
208
209
210
211
212
213
  /*
   * vmbus_process_rescind_offer -
   * Rescind the offer by initiating a device removal
   */
  static void vmbus_process_rescind_offer(struct work_struct *work)
  {
  	struct vmbus_channel *channel = container_of(work,
  						     struct vmbus_channel,
  						     work);
696453ba2   K. Y. Srinivasan   Staging: hv: vmbu...
214
  	vmbus_device_unregister(channel->device_obj);
4b2f9abea   Timo Teräs   staging: hv: conv...
215
  }
8b5d6d3bd   Haiyang Zhang   staging: hv: Fix ...
216

93e5bd06a   K. Y. Srinivasan   Drivers: hv: Make...
217
218
219
220
221
222
223
224
225
226
  void vmbus_free_channels(void)
  {
  	struct vmbus_channel *channel;
  
  	list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
  		vmbus_device_unregister(channel->device_obj);
  		kfree(channel->device_obj);
  		free_channel(channel);
  	}
  }
3e1895195   Hank Janssen   staging: hv: Corr...
227
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
228
   * vmbus_process_offer - Process the offer by creating a channel/device
c88c4e4c7   Hank Janssen   Staging: hv: Adde...
229
   * associated with this offer
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
230
   */
4b2f9abea   Timo Teräs   staging: hv: conv...
231
  static void vmbus_process_offer(struct work_struct *work)
3e7ee4902   Hank Janssen   Staging: hv: add ...
232
  {
4b2f9abea   Timo Teräs   staging: hv: conv...
233
234
235
  	struct vmbus_channel *newchannel = container_of(work,
  							struct vmbus_channel,
  							work);
aded7165f   Greg Kroah-Hartman   Staging: hv: clea...
236
  	struct vmbus_channel *channel;
188963ec7   Haiyang Zhang   staging: hv: Conv...
237
  	bool fnew = true;
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
238
  	int ret;
0f5e44ca6   Greg Kroah-Hartman   Staging: hv: make...
239
  	unsigned long flags;
3e7ee4902   Hank Janssen   Staging: hv: add ...
240

4b2f9abea   Timo Teräs   staging: hv: conv...
241
242
  	/* The next possible work is rescind handling */
  	INIT_WORK(&newchannel->work, vmbus_process_rescind_offer);
454f18a96   Bill Pemberton   Staging: hv: Remo...
243
  	/* Make sure this is a new offer */
15b2f6479   Haiyang Zhang   staging: hv: Conv...
244
  	spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
245

da9fcb726   Haiyang Zhang   staging: hv: Conv...
246
  	list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
247
248
249
250
  		if (!uuid_le_cmp(channel->offermsg.offer.if_type,
  			newchannel->offermsg.offer.if_type) &&
  			!uuid_le_cmp(channel->offermsg.offer.if_instance,
  				newchannel->offermsg.offer.if_instance)) {
188963ec7   Haiyang Zhang   staging: hv: Conv...
251
  			fnew = false;
3e7ee4902   Hank Janssen   Staging: hv: add ...
252
253
254
  			break;
  		}
  	}
188963ec7   Haiyang Zhang   staging: hv: Conv...
255
  	if (fnew)
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
256
  		list_add_tail(&newchannel->listentry,
da9fcb726   Haiyang Zhang   staging: hv: Conv...
257
  			      &vmbus_connection.chn_list);
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
258

15b2f6479   Haiyang Zhang   staging: hv: Conv...
259
  	spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
260

188963ec7   Haiyang Zhang   staging: hv: Conv...
261
  	if (!fnew) {
e98cb2768   Haiyang Zhang   staging: hv: Conv...
262
  		free_channel(newchannel);
3e7ee4902   Hank Janssen   Staging: hv: add ...
263
264
  		return;
  	}
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
265
266
267
  	/*
  	 * Start the process of binding this offer to the driver
  	 * We need to set the DeviceObject field before calling
646f1ea37   Haiyang Zhang   staging: hv: Conv...
268
  	 * vmbus_child_dev_add()
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
269
  	 */
f2c730111   K. Y. Srinivasan   Staging: hv: vmbu...
270
  	newchannel->device_obj = vmbus_device_create(
767dff685   Haiyang Zhang   staging: hv: Conv...
271
272
  		&newchannel->offermsg.offer.if_type,
  		&newchannel->offermsg.offer.if_instance,
188963ec7   Haiyang Zhang   staging: hv: Conv...
273
  		newchannel);
3e7ee4902   Hank Janssen   Staging: hv: add ...
274

454f18a96   Bill Pemberton   Staging: hv: Remo...
275
276
277
278
279
  	/*
  	 * Add the new device to the bus. This will kick off device-driver
  	 * binding which eventually invokes the device driver's AddDevice()
  	 * method.
  	 */
227942819   K. Y. Srinivasan   Staging: hv: vmbu...
280
  	ret = vmbus_device_register(newchannel->device_obj);
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
281
  	if (ret != 0) {
0a46618d5   Hank Janssen   staging: hv: Repl...
282
283
  		pr_err("unable to add child device object (relid %d)
  ",
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
284
  			   newchannel->offermsg.child_relid);
3e7ee4902   Hank Janssen   Staging: hv: add ...
285

15b2f6479   Haiyang Zhang   staging: hv: Conv...
286
  		spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
287
  		list_del(&newchannel->listentry);
15b2f6479   Haiyang Zhang   staging: hv: Conv...
288
  		spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
8b8ee6753   K. Y. Srinivasan   Drivers: hv: Fix ...
289
  		kfree(newchannel->device_obj);
3e7ee4902   Hank Janssen   Staging: hv: add ...
290

e98cb2768   Haiyang Zhang   staging: hv: Conv...
291
  		free_channel(newchannel);
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
292
  	} else {
454f18a96   Bill Pemberton   Staging: hv: Remo...
293
294
295
296
297
  		/*
  		 * This state is used to indicate a successful open
  		 * so that when we do close the channel normally, we
  		 * can cleanup properly
  		 */
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
298
  		newchannel->state = CHANNEL_OPEN_STATE;
3e7ee4902   Hank Janssen   Staging: hv: add ...
299
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
300
  }
3e1895195   Hank Janssen   staging: hv: Corr...
301
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
302
   * vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
303
   *
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
304
   */
e98cb2768   Haiyang Zhang   staging: hv: Conv...
305
  static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
3e7ee4902   Hank Janssen   Staging: hv: add ...
306
  {
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
307
  	struct vmbus_channel_offer_channel *offer;
188963ec7   Haiyang Zhang   staging: hv: Conv...
308
  	struct vmbus_channel *newchannel;
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
309
310
  	uuid_le *guidtype;
  	uuid_le *guidinstance;
3e7ee4902   Hank Janssen   Staging: hv: add ...
311
  	int i;
188963ec7   Haiyang Zhang   staging: hv: Conv...
312
  	int fsupported = 0;
3e7ee4902   Hank Janssen   Staging: hv: add ...
313

bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
314
315
  	offer = (struct vmbus_channel_offer_channel *)hdr;
  	for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
358d2ee2e   K. Y. Srinivasan   Staging: hv: Repl...
316
317
  		if (!uuid_le_cmp(offer->offer.if_type,
  				supported_device_classes[i])) {
188963ec7   Haiyang Zhang   staging: hv: Conv...
318
  			fsupported = 1;
3e7ee4902   Hank Janssen   Staging: hv: add ...
319
320
321
  			break;
  		}
  	}
98e087022   Hank Janssen   staging: hv: Remo...
322
  	if (!fsupported)
3e7ee4902   Hank Janssen   Staging: hv: add ...
323
  		return;
3e7ee4902   Hank Janssen   Staging: hv: add ...
324

767dff685   Haiyang Zhang   staging: hv: Conv...
325
326
  	guidtype = &offer->offer.if_type;
  	guidinstance = &offer->offer.if_instance;
3e7ee4902   Hank Janssen   Staging: hv: add ...
327

454f18a96   Bill Pemberton   Staging: hv: Remo...
328
  	/* Allocate the channel object and save this offer. */
e98cb2768   Haiyang Zhang   staging: hv: Conv...
329
  	newchannel = alloc_channel();
188963ec7   Haiyang Zhang   staging: hv: Conv...
330
  	if (!newchannel) {
0a46618d5   Hank Janssen   staging: hv: Repl...
331
332
  		pr_err("Unable to allocate channel object
  ");
3e7ee4902   Hank Janssen   Staging: hv: add ...
333
334
  		return;
  	}
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
335
  	memcpy(&newchannel->offermsg, offer,
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
336
  	       sizeof(struct vmbus_channel_offer_channel));
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
337
338
  	newchannel->monitor_grp = (u8)offer->monitorid / 32;
  	newchannel->monitor_bit = (u8)offer->monitorid % 32;
3e7ee4902   Hank Janssen   Staging: hv: add ...
339

4b2f9abea   Timo Teräs   staging: hv: conv...
340
341
  	INIT_WORK(&newchannel->work, vmbus_process_offer);
  	queue_work(newchannel->controlwq, &newchannel->work);
3e7ee4902   Hank Janssen   Staging: hv: add ...
342
  }
3e1895195   Hank Janssen   staging: hv: Corr...
343
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
344
   * vmbus_onoffer_rescind - Rescind offer handler.
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
345
346
347
   *
   * We queue a work item to process this offer synchronously
   */
e98cb2768   Haiyang Zhang   staging: hv: Conv...
348
  static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
3e7ee4902   Hank Janssen   Staging: hv: add ...
349
  {
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
350
  	struct vmbus_channel_rescind_offer *rescind;
aded7165f   Greg Kroah-Hartman   Staging: hv: clea...
351
  	struct vmbus_channel *channel;
3e7ee4902   Hank Janssen   Staging: hv: add ...
352

bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
353
  	rescind = (struct vmbus_channel_rescind_offer *)hdr;
c69776771   Haiyang Zhang   staging: hv: Conv...
354
  	channel = relid2channel(rescind->child_relid);
98e087022   Hank Janssen   staging: hv: Remo...
355
356
357
  
  	if (channel == NULL)
  		/* Just return here, no channel found */
3e7ee4902   Hank Janssen   Staging: hv: add ...
358
  		return;
3e7ee4902   Hank Janssen   Staging: hv: add ...
359

4b2f9abea   Timo Teräs   staging: hv: conv...
360
361
362
  	/* work is initialized for vmbus_process_rescind_offer() from
  	 * vmbus_process_offer() where the channel got created */
  	queue_work(channel->controlwq, &channel->work);
3e7ee4902   Hank Janssen   Staging: hv: add ...
363
  }
3e1895195   Hank Janssen   staging: hv: Corr...
364
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
365
366
   * vmbus_onoffers_delivered -
   * This is invoked when all offers have been delivered.
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
367
368
369
   *
   * Nothing to do here.
   */
e98cb2768   Haiyang Zhang   staging: hv: Conv...
370
  static void vmbus_onoffers_delivered(
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
371
  			struct vmbus_channel_message_header *hdr)
3e7ee4902   Hank Janssen   Staging: hv: add ...
372
  {
3e7ee4902   Hank Janssen   Staging: hv: add ...
373
  }
3e1895195   Hank Janssen   staging: hv: Corr...
374
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
375
   * vmbus_onopen_result - Open result handler.
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
376
377
378
379
380
   *
   * This is invoked when we received a response to our channel open request.
   * Find the matching request, copy the response and signal the requesting
   * thread.
   */
e98cb2768   Haiyang Zhang   staging: hv: Conv...
381
  static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr)
3e7ee4902   Hank Janssen   Staging: hv: add ...
382
  {
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
383
  	struct vmbus_channel_open_result *result;
188963ec7   Haiyang Zhang   staging: hv: Conv...
384
385
386
  	struct vmbus_channel_msginfo *msginfo;
  	struct vmbus_channel_message_header *requestheader;
  	struct vmbus_channel_open_channel *openmsg;
dd0813b6f   Greg Kroah-Hartman   Staging: hv: make...
387
  	unsigned long flags;
3e7ee4902   Hank Janssen   Staging: hv: add ...
388

bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
389
  	result = (struct vmbus_channel_open_result *)hdr;
3e7ee4902   Hank Janssen   Staging: hv: add ...
390

bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
391
392
393
  	/*
  	 * Find the open msg, copy the result and signal/unblock the wait event
  	 */
15b2f6479   Haiyang Zhang   staging: hv: Conv...
394
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
395

ebb61e5f9   Hank Janssen   Staging: hv: Fixe...
396
397
  	list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
  				msglistentry) {
188963ec7   Haiyang Zhang   staging: hv: Conv...
398
  		requestheader =
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
399
  			(struct vmbus_channel_message_header *)msginfo->msg;
188963ec7   Haiyang Zhang   staging: hv: Conv...
400

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
401
  		if (requestheader->msgtype == CHANNELMSG_OPENCHANNEL) {
188963ec7   Haiyang Zhang   staging: hv: Conv...
402
  			openmsg =
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
403
404
405
406
  			(struct vmbus_channel_open_channel *)msginfo->msg;
  			if (openmsg->child_relid == result->child_relid &&
  			    openmsg->openid == result->openid) {
  				memcpy(&msginfo->response.open_result,
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
407
  				       result,
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
408
409
410
  				       sizeof(
  					struct vmbus_channel_open_result));
  				complete(&msginfo->waitevent);
3e7ee4902   Hank Janssen   Staging: hv: add ...
411
412
413
414
  				break;
  			}
  		}
  	}
15b2f6479   Haiyang Zhang   staging: hv: Conv...
415
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
416
  }
3e1895195   Hank Janssen   staging: hv: Corr...
417
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
418
   * vmbus_ongpadl_created - GPADL created handler.
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
419
420
421
422
423
   *
   * This is invoked when we received a response to our gpadl create request.
   * Find the matching request, copy the response and signal the requesting
   * thread.
   */
e98cb2768   Haiyang Zhang   staging: hv: Conv...
424
  static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr)
3e7ee4902   Hank Janssen   Staging: hv: add ...
425
  {
188963ec7   Haiyang Zhang   staging: hv: Conv...
426
  	struct vmbus_channel_gpadl_created *gpadlcreated;
188963ec7   Haiyang Zhang   staging: hv: Conv...
427
428
429
  	struct vmbus_channel_msginfo *msginfo;
  	struct vmbus_channel_message_header *requestheader;
  	struct vmbus_channel_gpadl_header *gpadlheader;
dd0813b6f   Greg Kroah-Hartman   Staging: hv: make...
430
  	unsigned long flags;
3e7ee4902   Hank Janssen   Staging: hv: add ...
431

188963ec7   Haiyang Zhang   staging: hv: Conv...
432
  	gpadlcreated = (struct vmbus_channel_gpadl_created *)hdr;
3e7ee4902   Hank Janssen   Staging: hv: add ...
433

bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
434
435
436
437
  	/*
  	 * Find the establish msg, copy the result and signal/unblock the wait
  	 * event
  	 */
15b2f6479   Haiyang Zhang   staging: hv: Conv...
438
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
439

ebb61e5f9   Hank Janssen   Staging: hv: Fixe...
440
441
  	list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
  				msglistentry) {
188963ec7   Haiyang Zhang   staging: hv: Conv...
442
  		requestheader =
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
443
  			(struct vmbus_channel_message_header *)msginfo->msg;
188963ec7   Haiyang Zhang   staging: hv: Conv...
444

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
445
  		if (requestheader->msgtype == CHANNELMSG_GPADL_HEADER) {
188963ec7   Haiyang Zhang   staging: hv: Conv...
446
447
  			gpadlheader =
  			(struct vmbus_channel_gpadl_header *)requestheader;
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
448
449
450
451
  			if ((gpadlcreated->child_relid ==
  			     gpadlheader->child_relid) &&
  			    (gpadlcreated->gpadl == gpadlheader->gpadl)) {
  				memcpy(&msginfo->response.gpadl_created,
188963ec7   Haiyang Zhang   staging: hv: Conv...
452
  				       gpadlcreated,
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
453
454
455
  				       sizeof(
  					struct vmbus_channel_gpadl_created));
  				complete(&msginfo->waitevent);
3e7ee4902   Hank Janssen   Staging: hv: add ...
456
457
458
459
  				break;
  			}
  		}
  	}
15b2f6479   Haiyang Zhang   staging: hv: Conv...
460
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
461
  }
3e1895195   Hank Janssen   staging: hv: Corr...
462
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
463
   * vmbus_ongpadl_torndown - GPADL torndown handler.
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
464
465
466
467
468
   *
   * This is invoked when we received a response to our gpadl teardown request.
   * Find the matching request, copy the response and signal the requesting
   * thread.
   */
e98cb2768   Haiyang Zhang   staging: hv: Conv...
469
  static void vmbus_ongpadl_torndown(
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
470
  			struct vmbus_channel_message_header *hdr)
3e7ee4902   Hank Janssen   Staging: hv: add ...
471
  {
188963ec7   Haiyang Zhang   staging: hv: Conv...
472
  	struct vmbus_channel_gpadl_torndown *gpadl_torndown;
188963ec7   Haiyang Zhang   staging: hv: Conv...
473
474
475
  	struct vmbus_channel_msginfo *msginfo;
  	struct vmbus_channel_message_header *requestheader;
  	struct vmbus_channel_gpadl_teardown *gpadl_teardown;
dd0813b6f   Greg Kroah-Hartman   Staging: hv: make...
476
  	unsigned long flags;
3e7ee4902   Hank Janssen   Staging: hv: add ...
477

188963ec7   Haiyang Zhang   staging: hv: Conv...
478
  	gpadl_torndown = (struct vmbus_channel_gpadl_torndown *)hdr;
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
479
480
481
482
  
  	/*
  	 * Find the open msg, copy the result and signal/unblock the wait event
  	 */
15b2f6479   Haiyang Zhang   staging: hv: Conv...
483
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
484

ebb61e5f9   Hank Janssen   Staging: hv: Fixe...
485
486
  	list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
  				msglistentry) {
188963ec7   Haiyang Zhang   staging: hv: Conv...
487
  		requestheader =
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
488
  			(struct vmbus_channel_message_header *)msginfo->msg;
3e7ee4902   Hank Janssen   Staging: hv: add ...
489

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
490
  		if (requestheader->msgtype == CHANNELMSG_GPADL_TEARDOWN) {
188963ec7   Haiyang Zhang   staging: hv: Conv...
491
492
  			gpadl_teardown =
  			(struct vmbus_channel_gpadl_teardown *)requestheader;
3e7ee4902   Hank Janssen   Staging: hv: add ...
493

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
494
495
  			if (gpadl_torndown->gpadl == gpadl_teardown->gpadl) {
  				memcpy(&msginfo->response.gpadl_torndown,
188963ec7   Haiyang Zhang   staging: hv: Conv...
496
  				       gpadl_torndown,
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
497
498
499
  				       sizeof(
  					struct vmbus_channel_gpadl_torndown));
  				complete(&msginfo->waitevent);
3e7ee4902   Hank Janssen   Staging: hv: add ...
500
501
502
503
  				break;
  			}
  		}
  	}
15b2f6479   Haiyang Zhang   staging: hv: Conv...
504
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
505
  }
3e1895195   Hank Janssen   staging: hv: Corr...
506
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
507
   * vmbus_onversion_response - Version response handler
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
508
509
510
511
512
   *
   * This is invoked when we received a response to our initiate contact request.
   * Find the matching request, copy the response and signal the requesting
   * thread.
   */
e98cb2768   Haiyang Zhang   staging: hv: Conv...
513
  static void vmbus_onversion_response(
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
514
  		struct vmbus_channel_message_header *hdr)
3e7ee4902   Hank Janssen   Staging: hv: add ...
515
  {
188963ec7   Haiyang Zhang   staging: hv: Conv...
516
517
  	struct vmbus_channel_msginfo *msginfo;
  	struct vmbus_channel_message_header *requestheader;
82250213d   Greg Kroah-Hartman   Staging: hv: type...
518
  	struct vmbus_channel_initiate_contact *initiate;
188963ec7   Haiyang Zhang   staging: hv: Conv...
519
  	struct vmbus_channel_version_response *version_response;
dd0813b6f   Greg Kroah-Hartman   Staging: hv: make...
520
  	unsigned long flags;
3e7ee4902   Hank Janssen   Staging: hv: add ...
521

188963ec7   Haiyang Zhang   staging: hv: Conv...
522
  	version_response = (struct vmbus_channel_version_response *)hdr;
15b2f6479   Haiyang Zhang   staging: hv: Conv...
523
  	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
524

ebb61e5f9   Hank Janssen   Staging: hv: Fixe...
525
526
  	list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
  				msglistentry) {
188963ec7   Haiyang Zhang   staging: hv: Conv...
527
  		requestheader =
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
528
  			(struct vmbus_channel_message_header *)msginfo->msg;
3e7ee4902   Hank Janssen   Staging: hv: add ...
529

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
530
531
  		if (requestheader->msgtype ==
  		    CHANNELMSG_INITIATE_CONTACT) {
188963ec7   Haiyang Zhang   staging: hv: Conv...
532
533
  			initiate =
  			(struct vmbus_channel_initiate_contact *)requestheader;
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
534
  			memcpy(&msginfo->response.version_response,
188963ec7   Haiyang Zhang   staging: hv: Conv...
535
  			      version_response,
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
536
  			      sizeof(struct vmbus_channel_version_response));
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
537
  			complete(&msginfo->waitevent);
3e7ee4902   Hank Janssen   Staging: hv: add ...
538
539
  		}
  	}
15b2f6479   Haiyang Zhang   staging: hv: Conv...
540
  	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
3e7ee4902   Hank Janssen   Staging: hv: add ...
541
  }
c8212f04d   Greg Kroah-Hartman   Staging: hv: reor...
542
543
  /* Channel message dispatch table */
  static struct vmbus_channel_message_table_entry
b7c6b02f3   K. Y. Srinivasan   Staging: hv: vmbu...
544
  	channel_message_table[CHANNELMSG_COUNT] = {
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
  	{CHANNELMSG_INVALID,			NULL},
  	{CHANNELMSG_OFFERCHANNEL,		vmbus_onoffer},
  	{CHANNELMSG_RESCIND_CHANNELOFFER,	vmbus_onoffer_rescind},
  	{CHANNELMSG_REQUESTOFFERS,		NULL},
  	{CHANNELMSG_ALLOFFERS_DELIVERED,	vmbus_onoffers_delivered},
  	{CHANNELMSG_OPENCHANNEL,		NULL},
  	{CHANNELMSG_OPENCHANNEL_RESULT,	vmbus_onopen_result},
  	{CHANNELMSG_CLOSECHANNEL,		NULL},
  	{CHANNELMSG_GPADL_HEADER,		NULL},
  	{CHANNELMSG_GPADL_BODY,		NULL},
  	{CHANNELMSG_GPADL_CREATED,		vmbus_ongpadl_created},
  	{CHANNELMSG_GPADL_TEARDOWN,		NULL},
  	{CHANNELMSG_GPADL_TORNDOWN,		vmbus_ongpadl_torndown},
  	{CHANNELMSG_RELID_RELEASED,		NULL},
  	{CHANNELMSG_INITIATE_CONTACT,		NULL},
  	{CHANNELMSG_VERSION_RESPONSE,		vmbus_onversion_response},
  	{CHANNELMSG_UNLOAD,			NULL},
c8212f04d   Greg Kroah-Hartman   Staging: hv: reor...
562
  };
3e1895195   Hank Janssen   staging: hv: Corr...
563
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
564
   * vmbus_onmessage - Handler for channel protocol messages.
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
565
566
567
   *
   * This is invoked in the vmbus worker thread context.
   */
e98cb2768   Haiyang Zhang   staging: hv: Conv...
568
  void vmbus_onmessage(void *context)
3e7ee4902   Hank Janssen   Staging: hv: add ...
569
  {
188963ec7   Haiyang Zhang   staging: hv: Conv...
570
  	struct hv_message *msg = context;
82250213d   Greg Kroah-Hartman   Staging: hv: type...
571
  	struct vmbus_channel_message_header *hdr;
3e7ee4902   Hank Janssen   Staging: hv: add ...
572
  	int size;
f6feebe07   Haiyang Zhang   staging: hv: Conv...
573
574
  	hdr = (struct vmbus_channel_message_header *)msg->u.payload;
  	size = msg->header.payload_size;
3e7ee4902   Hank Janssen   Staging: hv: add ...
575

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
576
  	if (hdr->msgtype >= CHANNELMSG_COUNT) {
0a46618d5   Hank Janssen   staging: hv: Repl...
577
578
  		pr_err("Received invalid channel message type %d size %d
  ",
c50f7fb28   Haiyang Zhang   staging: hv: Conv...
579
  			   hdr->msgtype, size);
04f50c4d2   Greg Kroah-Hartman   Staging: hv: osd:...
580
  		print_hex_dump_bytes("", DUMP_PREFIX_NONE,
f6feebe07   Haiyang Zhang   staging: hv: Conv...
581
  				     (unsigned char *)msg->u.payload, size);
3e7ee4902   Hank Janssen   Staging: hv: add ...
582
583
  		return;
  	}
b7c6b02f3   K. Y. Srinivasan   Staging: hv: vmbu...
584
585
  	if (channel_message_table[hdr->msgtype].message_handler)
  		channel_message_table[hdr->msgtype].message_handler(hdr);
3e7ee4902   Hank Janssen   Staging: hv: add ...
586
  	else
0a46618d5   Hank Janssen   staging: hv: Repl...
587
588
  		pr_err("Unhandled channel message type %d
  ", hdr->msgtype);
3e7ee4902   Hank Janssen   Staging: hv: add ...
589
  }
3e1895195   Hank Janssen   staging: hv: Corr...
590
  /*
e98cb2768   Haiyang Zhang   staging: hv: Conv...
591
   * vmbus_request_offers - Send a request to get all our pending offers.
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
592
   */
e98cb2768   Haiyang Zhang   staging: hv: Conv...
593
  int vmbus_request_offers(void)
3e7ee4902   Hank Janssen   Staging: hv: add ...
594
  {
82250213d   Greg Kroah-Hartman   Staging: hv: type...
595
  	struct vmbus_channel_message_header *msg;
188963ec7   Haiyang Zhang   staging: hv: Conv...
596
  	struct vmbus_channel_msginfo *msginfo;
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
597
  	int ret, t;
3e7ee4902   Hank Janssen   Staging: hv: add ...
598

188963ec7   Haiyang Zhang   staging: hv: Conv...
599
  	msginfo = kmalloc(sizeof(*msginfo) +
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
600
601
  			  sizeof(struct vmbus_channel_message_header),
  			  GFP_KERNEL);
188963ec7   Haiyang Zhang   staging: hv: Conv...
602
  	if (!msginfo)
75910f236   Bill Pemberton   Staging: hv: remo...
603
  		return -ENOMEM;
3e7ee4902   Hank Janssen   Staging: hv: add ...
604

9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
605
  	init_completion(&msginfo->waitevent);
75910f236   Bill Pemberton   Staging: hv: remo...
606

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
607
  	msg = (struct vmbus_channel_message_header *)msginfo->msg;
3e7ee4902   Hank Janssen   Staging: hv: add ...
608

c50f7fb28   Haiyang Zhang   staging: hv: Conv...
609
  	msg->msgtype = CHANNELMSG_REQUESTOFFERS;
3e7ee4902   Hank Janssen   Staging: hv: add ...
610

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

c69776771   Haiyang Zhang   staging: hv: Conv...
612
  	ret = vmbus_post_msg(msg,
bd60c33e7   Greg Kroah-Hartman   Staging: hv: codi...
613
614
  			       sizeof(struct vmbus_channel_message_header));
  	if (ret != 0) {
0a46618d5   Hank Janssen   staging: hv: Repl...
615
616
  		pr_err("Unable to request offers - %d
  ", ret);
3e7ee4902   Hank Janssen   Staging: hv: add ...
617

0c3b7b2f7   K. Y. Srinivasan   Staging: hv: Use ...
618
619
  		goto cleanup;
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
620

2dfde9644   K. Y. Srinivasan   Staging: hv: vmbu...
621
  	t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
9568a1931   K. Y. Srinivasan   Staging: hv: Use ...
622
  	if (t == 0) {
0c3b7b2f7   K. Y. Srinivasan   Staging: hv: Use ...
623
624
  		ret = -ETIMEDOUT;
  		goto cleanup;
3e7ee4902   Hank Janssen   Staging: hv: add ...
625
  	}
3e7ee4902   Hank Janssen   Staging: hv: add ...
626

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

0c3b7b2f7   K. Y. Srinivasan   Staging: hv: Use ...
628
  cleanup:
dd9b15dc0   Ilia Mirkin   staging: hv: Remo...
629
  	kfree(msginfo);
3e7ee4902   Hank Janssen   Staging: hv: add ...
630

3e7ee4902   Hank Janssen   Staging: hv: add ...
631
632
  	return ret;
  }
454f18a96   Bill Pemberton   Staging: hv: Remo...
633
  /* eof */