xref: /openbmc/linux/drivers/hv/vmbus_drv.c (revision 615c36f5)
1 /*
2  * Copyright (c) 2009, Microsoft Corporation.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15  * Place - Suite 330, Boston, MA 02111-1307 USA.
16  *
17  * Authors:
18  *   Haiyang Zhang <haiyangz@microsoft.com>
19  *   Hank Janssen  <hjanssen@microsoft.com>
20  *   K. Y. Srinivasan <kys@microsoft.com>
21  *
22  */
23 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24 
25 #include <linux/init.h>
26 #include <linux/module.h>
27 #include <linux/device.h>
28 #include <linux/irq.h>
29 #include <linux/interrupt.h>
30 #include <linux/sysctl.h>
31 #include <linux/slab.h>
32 #include <linux/acpi.h>
33 #include <acpi/acpi_bus.h>
34 #include <linux/completion.h>
35 #include <linux/hyperv.h>
36 #include <asm/hyperv.h>
37 #include "hyperv_vmbus.h"
38 
39 
40 static struct acpi_device  *hv_acpi_dev;
41 
42 static struct tasklet_struct msg_dpc;
43 static struct tasklet_struct event_dpc;
44 static struct completion probe_event;
45 static int irq;
46 
47 struct hv_device_info {
48 	u32 chn_id;
49 	u32 chn_state;
50 	uuid_le chn_type;
51 	uuid_le chn_instance;
52 
53 	u32 monitor_id;
54 	u32 server_monitor_pending;
55 	u32 server_monitor_latency;
56 	u32 server_monitor_conn_id;
57 	u32 client_monitor_pending;
58 	u32 client_monitor_latency;
59 	u32 client_monitor_conn_id;
60 
61 	struct hv_dev_port_info inbound;
62 	struct hv_dev_port_info outbound;
63 };
64 
65 
66 static void get_channel_info(struct hv_device *device,
67 			     struct hv_device_info *info)
68 {
69 	struct vmbus_channel_debug_info debug_info;
70 
71 	if (!device->channel)
72 		return;
73 
74 	vmbus_get_debug_info(device->channel, &debug_info);
75 
76 	info->chn_id = debug_info.relid;
77 	info->chn_state = debug_info.state;
78 	memcpy(&info->chn_type, &debug_info.interfacetype,
79 	       sizeof(uuid_le));
80 	memcpy(&info->chn_instance, &debug_info.interface_instance,
81 	       sizeof(uuid_le));
82 
83 	info->monitor_id = debug_info.monitorid;
84 
85 	info->server_monitor_pending = debug_info.servermonitor_pending;
86 	info->server_monitor_latency = debug_info.servermonitor_latency;
87 	info->server_monitor_conn_id = debug_info.servermonitor_connectionid;
88 
89 	info->client_monitor_pending = debug_info.clientmonitor_pending;
90 	info->client_monitor_latency = debug_info.clientmonitor_latency;
91 	info->client_monitor_conn_id = debug_info.clientmonitor_connectionid;
92 
93 	info->inbound.int_mask = debug_info.inbound.current_interrupt_mask;
94 	info->inbound.read_idx = debug_info.inbound.current_read_index;
95 	info->inbound.write_idx = debug_info.inbound.current_write_index;
96 	info->inbound.bytes_avail_toread =
97 		debug_info.inbound.bytes_avail_toread;
98 	info->inbound.bytes_avail_towrite =
99 		debug_info.inbound.bytes_avail_towrite;
100 
101 	info->outbound.int_mask =
102 		debug_info.outbound.current_interrupt_mask;
103 	info->outbound.read_idx = debug_info.outbound.current_read_index;
104 	info->outbound.write_idx = debug_info.outbound.current_write_index;
105 	info->outbound.bytes_avail_toread =
106 		debug_info.outbound.bytes_avail_toread;
107 	info->outbound.bytes_avail_towrite =
108 		debug_info.outbound.bytes_avail_towrite;
109 }
110 
111 #define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2)
112 static void print_alias_name(struct hv_device *hv_dev, char *alias_name)
113 {
114 	int i;
115 	for (i = 0; i < VMBUS_ALIAS_LEN; i += 2)
116 		sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]);
117 }
118 
119 /*
120  * vmbus_show_device_attr - Show the device attribute in sysfs.
121  *
122  * This is invoked when user does a
123  * "cat /sys/bus/vmbus/devices/<busdevice>/<attr name>"
124  */
125 static ssize_t vmbus_show_device_attr(struct device *dev,
126 				      struct device_attribute *dev_attr,
127 				      char *buf)
128 {
129 	struct hv_device *hv_dev = device_to_hv_device(dev);
130 	struct hv_device_info *device_info;
131 	char alias_name[VMBUS_ALIAS_LEN + 1];
132 	int ret = 0;
133 
134 	device_info = kzalloc(sizeof(struct hv_device_info), GFP_KERNEL);
135 	if (!device_info)
136 		return ret;
137 
138 	get_channel_info(hv_dev, device_info);
139 
140 	if (!strcmp(dev_attr->attr.name, "class_id")) {
141 		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
142 			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
143 			       device_info->chn_type.b[3],
144 			       device_info->chn_type.b[2],
145 			       device_info->chn_type.b[1],
146 			       device_info->chn_type.b[0],
147 			       device_info->chn_type.b[5],
148 			       device_info->chn_type.b[4],
149 			       device_info->chn_type.b[7],
150 			       device_info->chn_type.b[6],
151 			       device_info->chn_type.b[8],
152 			       device_info->chn_type.b[9],
153 			       device_info->chn_type.b[10],
154 			       device_info->chn_type.b[11],
155 			       device_info->chn_type.b[12],
156 			       device_info->chn_type.b[13],
157 			       device_info->chn_type.b[14],
158 			       device_info->chn_type.b[15]);
159 	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
160 		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
161 			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
162 			       device_info->chn_instance.b[3],
163 			       device_info->chn_instance.b[2],
164 			       device_info->chn_instance.b[1],
165 			       device_info->chn_instance.b[0],
166 			       device_info->chn_instance.b[5],
167 			       device_info->chn_instance.b[4],
168 			       device_info->chn_instance.b[7],
169 			       device_info->chn_instance.b[6],
170 			       device_info->chn_instance.b[8],
171 			       device_info->chn_instance.b[9],
172 			       device_info->chn_instance.b[10],
173 			       device_info->chn_instance.b[11],
174 			       device_info->chn_instance.b[12],
175 			       device_info->chn_instance.b[13],
176 			       device_info->chn_instance.b[14],
177 			       device_info->chn_instance.b[15]);
178 	} else if (!strcmp(dev_attr->attr.name, "modalias")) {
179 		print_alias_name(hv_dev, alias_name);
180 		ret = sprintf(buf, "vmbus:%s\n", alias_name);
181 	} else if (!strcmp(dev_attr->attr.name, "state")) {
182 		ret = sprintf(buf, "%d\n", device_info->chn_state);
183 	} else if (!strcmp(dev_attr->attr.name, "id")) {
184 		ret = sprintf(buf, "%d\n", device_info->chn_id);
185 	} else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
186 		ret = sprintf(buf, "%d\n", device_info->outbound.int_mask);
187 	} else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
188 		ret = sprintf(buf, "%d\n", device_info->outbound.read_idx);
189 	} else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
190 		ret = sprintf(buf, "%d\n", device_info->outbound.write_idx);
191 	} else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
192 		ret = sprintf(buf, "%d\n",
193 			       device_info->outbound.bytes_avail_toread);
194 	} else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
195 		ret = sprintf(buf, "%d\n",
196 			       device_info->outbound.bytes_avail_towrite);
197 	} else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
198 		ret = sprintf(buf, "%d\n", device_info->inbound.int_mask);
199 	} else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
200 		ret = sprintf(buf, "%d\n", device_info->inbound.read_idx);
201 	} else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
202 		ret = sprintf(buf, "%d\n", device_info->inbound.write_idx);
203 	} else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
204 		ret = sprintf(buf, "%d\n",
205 			       device_info->inbound.bytes_avail_toread);
206 	} else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
207 		ret = sprintf(buf, "%d\n",
208 			       device_info->inbound.bytes_avail_towrite);
209 	} else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
210 		ret = sprintf(buf, "%d\n", device_info->monitor_id);
211 	} else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
212 		ret = sprintf(buf, "%d\n", device_info->server_monitor_pending);
213 	} else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
214 		ret = sprintf(buf, "%d\n", device_info->server_monitor_latency);
215 	} else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
216 		ret = sprintf(buf, "%d\n",
217 			       device_info->server_monitor_conn_id);
218 	} else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
219 		ret = sprintf(buf, "%d\n", device_info->client_monitor_pending);
220 	} else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
221 		ret = sprintf(buf, "%d\n", device_info->client_monitor_latency);
222 	} else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
223 		ret = sprintf(buf, "%d\n",
224 			       device_info->client_monitor_conn_id);
225 	}
226 
227 	kfree(device_info);
228 	return ret;
229 }
230 
231 /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
232 static struct device_attribute vmbus_device_attrs[] = {
233 	__ATTR(id, S_IRUGO, vmbus_show_device_attr, NULL),
234 	__ATTR(state, S_IRUGO, vmbus_show_device_attr, NULL),
235 	__ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL),
236 	__ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL),
237 	__ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL),
238 	__ATTR(modalias, S_IRUGO, vmbus_show_device_attr, NULL),
239 
240 	__ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
241 	__ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
242 	__ATTR(server_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
243 
244 	__ATTR(client_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
245 	__ATTR(client_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
246 	__ATTR(client_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
247 
248 	__ATTR(out_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
249 	__ATTR(out_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
250 	__ATTR(out_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
251 	__ATTR(out_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
252 	__ATTR(out_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
253 
254 	__ATTR(in_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
255 	__ATTR(in_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
256 	__ATTR(in_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
257 	__ATTR(in_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
258 	__ATTR(in_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
259 	__ATTR_NULL
260 };
261 
262 
263 /*
264  * vmbus_uevent - add uevent for our device
265  *
266  * This routine is invoked when a device is added or removed on the vmbus to
267  * generate a uevent to udev in the userspace. The udev will then look at its
268  * rule and the uevent generated here to load the appropriate driver
269  *
270  * The alias string will be of the form vmbus:guid where guid is the string
271  * representation of the device guid (each byte of the guid will be
272  * represented with two hex characters.
273  */
274 static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
275 {
276 	struct hv_device *dev = device_to_hv_device(device);
277 	int ret;
278 	char alias_name[VMBUS_ALIAS_LEN + 1];
279 
280 	print_alias_name(dev, alias_name);
281 	ret = add_uevent_var(env, "MODALIAS=vmbus:%s", alias_name);
282 	return ret;
283 }
284 
285 static uuid_le null_guid;
286 
287 static inline bool is_null_guid(const __u8 *guid)
288 {
289 	if (memcmp(guid, &null_guid, sizeof(uuid_le)))
290 		return false;
291 	return true;
292 }
293 
294 /*
295  * Return a matching hv_vmbus_device_id pointer.
296  * If there is no match, return NULL.
297  */
298 static const struct hv_vmbus_device_id *hv_vmbus_get_id(
299 					const struct hv_vmbus_device_id *id,
300 					__u8 *guid)
301 {
302 	for (; !is_null_guid(id->guid); id++)
303 		if (!memcmp(&id->guid, guid, sizeof(uuid_le)))
304 			return id;
305 
306 	return NULL;
307 }
308 
309 
310 
311 /*
312  * vmbus_match - Attempt to match the specified device to the specified driver
313  */
314 static int vmbus_match(struct device *device, struct device_driver *driver)
315 {
316 	struct hv_driver *drv = drv_to_hv_drv(driver);
317 	struct hv_device *hv_dev = device_to_hv_device(device);
318 
319 	if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b))
320 		return 1;
321 
322 	return 0;
323 }
324 
325 /*
326  * vmbus_probe - Add the new vmbus's child device
327  */
328 static int vmbus_probe(struct device *child_device)
329 {
330 	int ret = 0;
331 	struct hv_driver *drv =
332 			drv_to_hv_drv(child_device->driver);
333 	struct hv_device *dev = device_to_hv_device(child_device);
334 	const struct hv_vmbus_device_id *dev_id;
335 
336 	dev_id = hv_vmbus_get_id(drv->id_table, dev->dev_type.b);
337 	if (drv->probe) {
338 		ret = drv->probe(dev, dev_id);
339 		if (ret != 0)
340 			pr_err("probe failed for device %s (%d)\n",
341 			       dev_name(child_device), ret);
342 
343 	} else {
344 		pr_err("probe not set for driver %s\n",
345 		       dev_name(child_device));
346 		ret = -ENODEV;
347 	}
348 	return ret;
349 }
350 
351 /*
352  * vmbus_remove - Remove a vmbus device
353  */
354 static int vmbus_remove(struct device *child_device)
355 {
356 	struct hv_driver *drv = drv_to_hv_drv(child_device->driver);
357 	struct hv_device *dev = device_to_hv_device(child_device);
358 
359 	if (drv->remove)
360 		drv->remove(dev);
361 	else
362 		pr_err("remove not set for driver %s\n",
363 			dev_name(child_device));
364 
365 	return 0;
366 }
367 
368 
369 /*
370  * vmbus_shutdown - Shutdown a vmbus device
371  */
372 static void vmbus_shutdown(struct device *child_device)
373 {
374 	struct hv_driver *drv;
375 	struct hv_device *dev = device_to_hv_device(child_device);
376 
377 
378 	/* The device may not be attached yet */
379 	if (!child_device->driver)
380 		return;
381 
382 	drv = drv_to_hv_drv(child_device->driver);
383 
384 	if (drv->shutdown)
385 		drv->shutdown(dev);
386 
387 	return;
388 }
389 
390 
391 /*
392  * vmbus_device_release - Final callback release of the vmbus child device
393  */
394 static void vmbus_device_release(struct device *device)
395 {
396 	struct hv_device *hv_dev = device_to_hv_device(device);
397 
398 	kfree(hv_dev);
399 
400 }
401 
402 /* The one and only one */
403 static struct bus_type  hv_bus = {
404 	.name =		"vmbus",
405 	.match =		vmbus_match,
406 	.shutdown =		vmbus_shutdown,
407 	.remove =		vmbus_remove,
408 	.probe =		vmbus_probe,
409 	.uevent =		vmbus_uevent,
410 	.dev_attrs =	vmbus_device_attrs,
411 };
412 
413 static const char *driver_name = "hyperv";
414 
415 
416 struct onmessage_work_context {
417 	struct work_struct work;
418 	struct hv_message msg;
419 };
420 
421 static void vmbus_onmessage_work(struct work_struct *work)
422 {
423 	struct onmessage_work_context *ctx;
424 
425 	ctx = container_of(work, struct onmessage_work_context,
426 			   work);
427 	vmbus_onmessage(&ctx->msg);
428 	kfree(ctx);
429 }
430 
431 static void vmbus_on_msg_dpc(unsigned long data)
432 {
433 	int cpu = smp_processor_id();
434 	void *page_addr = hv_context.synic_message_page[cpu];
435 	struct hv_message *msg = (struct hv_message *)page_addr +
436 				  VMBUS_MESSAGE_SINT;
437 	struct onmessage_work_context *ctx;
438 
439 	while (1) {
440 		if (msg->header.message_type == HVMSG_NONE) {
441 			/* no msg */
442 			break;
443 		} else {
444 			ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
445 			if (ctx == NULL)
446 				continue;
447 			INIT_WORK(&ctx->work, vmbus_onmessage_work);
448 			memcpy(&ctx->msg, msg, sizeof(*msg));
449 			queue_work(vmbus_connection.work_queue, &ctx->work);
450 		}
451 
452 		msg->header.message_type = HVMSG_NONE;
453 
454 		/*
455 		 * Make sure the write to MessageType (ie set to
456 		 * HVMSG_NONE) happens before we read the
457 		 * MessagePending and EOMing. Otherwise, the EOMing
458 		 * will not deliver any more messages since there is
459 		 * no empty slot
460 		 */
461 		smp_mb();
462 
463 		if (msg->header.message_flags.msg_pending) {
464 			/*
465 			 * This will cause message queue rescan to
466 			 * possibly deliver another msg from the
467 			 * hypervisor
468 			 */
469 			wrmsrl(HV_X64_MSR_EOM, 0);
470 		}
471 	}
472 }
473 
474 static irqreturn_t vmbus_isr(int irq, void *dev_id)
475 {
476 	int cpu = smp_processor_id();
477 	void *page_addr;
478 	struct hv_message *msg;
479 	union hv_synic_event_flags *event;
480 	bool handled = false;
481 
482 	/*
483 	 * Check for events before checking for messages. This is the order
484 	 * in which events and messages are checked in Windows guests on
485 	 * Hyper-V, and the Windows team suggested we do the same.
486 	 */
487 
488 	page_addr = hv_context.synic_event_page[cpu];
489 	event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
490 
491 	/* Since we are a child, we only need to check bit 0 */
492 	if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) {
493 		handled = true;
494 		tasklet_schedule(&event_dpc);
495 	}
496 
497 	page_addr = hv_context.synic_message_page[cpu];
498 	msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
499 
500 	/* Check if there are actual msgs to be processed */
501 	if (msg->header.message_type != HVMSG_NONE) {
502 		handled = true;
503 		tasklet_schedule(&msg_dpc);
504 	}
505 
506 	if (handled)
507 		return IRQ_HANDLED;
508 	else
509 		return IRQ_NONE;
510 }
511 
512 /*
513  * vmbus_bus_init -Main vmbus driver initialization routine.
514  *
515  * Here, we
516  *	- initialize the vmbus driver context
517  *	- invoke the vmbus hv main init routine
518  *	- get the irq resource
519  *	- retrieve the channel offers
520  */
521 static int vmbus_bus_init(int irq)
522 {
523 	int ret;
524 	unsigned int vector;
525 
526 	/* Hypervisor initialization...setup hypercall page..etc */
527 	ret = hv_init();
528 	if (ret != 0) {
529 		pr_err("Unable to initialize the hypervisor - 0x%x\n", ret);
530 		return ret;
531 	}
532 
533 	tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0);
534 	tasklet_init(&event_dpc, vmbus_on_event, 0);
535 
536 	ret = bus_register(&hv_bus);
537 	if (ret)
538 		goto err_cleanup;
539 
540 	ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
541 			driver_name, hv_acpi_dev);
542 
543 	if (ret != 0) {
544 		pr_err("Unable to request IRQ %d\n",
545 			   irq);
546 		goto err_unregister;
547 	}
548 
549 	vector = IRQ0_VECTOR + irq;
550 
551 	/*
552 	 * Notify the hypervisor of our irq and
553 	 * connect to the host.
554 	 */
555 	on_each_cpu(hv_synic_init, (void *)&vector, 1);
556 	ret = vmbus_connect();
557 	if (ret)
558 		goto err_irq;
559 
560 	vmbus_request_offers();
561 
562 	return 0;
563 
564 err_irq:
565 	free_irq(irq, hv_acpi_dev);
566 
567 err_unregister:
568 	bus_unregister(&hv_bus);
569 
570 err_cleanup:
571 	hv_cleanup();
572 
573 	return ret;
574 }
575 
576 /**
577  * __vmbus_child_driver_register - Register a vmbus's driver
578  * @drv: Pointer to driver structure you want to register
579  * @owner: owner module of the drv
580  * @mod_name: module name string
581  *
582  * Registers the given driver with Linux through the 'driver_register()' call
583  * and sets up the hyper-v vmbus handling for this driver.
584  * It will return the state of the 'driver_register()' call.
585  *
586  */
587 int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, const char *mod_name)
588 {
589 	int ret;
590 
591 	pr_info("registering driver %s\n", hv_driver->name);
592 
593 	hv_driver->driver.name = hv_driver->name;
594 	hv_driver->driver.owner = owner;
595 	hv_driver->driver.mod_name = mod_name;
596 	hv_driver->driver.bus = &hv_bus;
597 
598 	ret = driver_register(&hv_driver->driver);
599 
600 	vmbus_request_offers();
601 
602 	return ret;
603 }
604 EXPORT_SYMBOL_GPL(__vmbus_driver_register);
605 
606 /**
607  * vmbus_driver_unregister() - Unregister a vmbus's driver
608  * @drv: Pointer to driver structure you want to un-register
609  *
610  * Un-register the given driver that was previous registered with a call to
611  * vmbus_driver_register()
612  */
613 void vmbus_driver_unregister(struct hv_driver *hv_driver)
614 {
615 	pr_info("unregistering driver %s\n", hv_driver->name);
616 
617 	driver_unregister(&hv_driver->driver);
618 
619 }
620 EXPORT_SYMBOL_GPL(vmbus_driver_unregister);
621 
622 /*
623  * vmbus_device_create - Creates and registers a new child device
624  * on the vmbus.
625  */
626 struct hv_device *vmbus_device_create(uuid_le *type,
627 					    uuid_le *instance,
628 					    struct vmbus_channel *channel)
629 {
630 	struct hv_device *child_device_obj;
631 
632 	child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL);
633 	if (!child_device_obj) {
634 		pr_err("Unable to allocate device object for child device\n");
635 		return NULL;
636 	}
637 
638 	child_device_obj->channel = channel;
639 	memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
640 	memcpy(&child_device_obj->dev_instance, instance,
641 	       sizeof(uuid_le));
642 
643 
644 	return child_device_obj;
645 }
646 
647 /*
648  * vmbus_device_register - Register the child device
649  */
650 int vmbus_device_register(struct hv_device *child_device_obj)
651 {
652 	int ret = 0;
653 
654 	static atomic_t device_num = ATOMIC_INIT(0);
655 
656 	dev_set_name(&child_device_obj->device, "vmbus_0_%d",
657 		     atomic_inc_return(&device_num));
658 
659 	child_device_obj->device.bus = &hv_bus;
660 	child_device_obj->device.parent = &hv_acpi_dev->dev;
661 	child_device_obj->device.release = vmbus_device_release;
662 
663 	/*
664 	 * Register with the LDM. This will kick off the driver/device
665 	 * binding...which will eventually call vmbus_match() and vmbus_probe()
666 	 */
667 	ret = device_register(&child_device_obj->device);
668 
669 	if (ret)
670 		pr_err("Unable to register child device\n");
671 	else
672 		pr_info("child device %s registered\n",
673 			dev_name(&child_device_obj->device));
674 
675 	return ret;
676 }
677 
678 /*
679  * vmbus_device_unregister - Remove the specified child device
680  * from the vmbus.
681  */
682 void vmbus_device_unregister(struct hv_device *device_obj)
683 {
684 	/*
685 	 * Kick off the process of unregistering the device.
686 	 * This will call vmbus_remove() and eventually vmbus_device_release()
687 	 */
688 	device_unregister(&device_obj->device);
689 
690 	pr_info("child device %s unregistered\n",
691 		dev_name(&device_obj->device));
692 }
693 
694 
695 /*
696  * VMBUS is an acpi enumerated device. Get the the IRQ information
697  * from DSDT.
698  */
699 
700 static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *irq)
701 {
702 
703 	if (res->type == ACPI_RESOURCE_TYPE_IRQ) {
704 		struct acpi_resource_irq *irqp;
705 		irqp = &res->data.irq;
706 
707 		*((unsigned int *)irq) = irqp->interrupts[0];
708 	}
709 
710 	return AE_OK;
711 }
712 
713 static int vmbus_acpi_add(struct acpi_device *device)
714 {
715 	acpi_status result;
716 
717 	hv_acpi_dev = device;
718 
719 	result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
720 					vmbus_walk_resources, &irq);
721 
722 	if (ACPI_FAILURE(result)) {
723 		complete(&probe_event);
724 		return -ENODEV;
725 	}
726 	complete(&probe_event);
727 	return 0;
728 }
729 
730 static const struct acpi_device_id vmbus_acpi_device_ids[] = {
731 	{"VMBUS", 0},
732 	{"VMBus", 0},
733 	{"", 0},
734 };
735 MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids);
736 
737 static struct acpi_driver vmbus_acpi_driver = {
738 	.name = "vmbus",
739 	.ids = vmbus_acpi_device_ids,
740 	.ops = {
741 		.add = vmbus_acpi_add,
742 	},
743 };
744 
745 static int __init hv_acpi_init(void)
746 {
747 	int ret, t;
748 
749 	init_completion(&probe_event);
750 
751 	/*
752 	 * Get irq resources first.
753 	 */
754 
755 	ret = acpi_bus_register_driver(&vmbus_acpi_driver);
756 
757 	if (ret)
758 		return ret;
759 
760 	t = wait_for_completion_timeout(&probe_event, 5*HZ);
761 	if (t == 0) {
762 		ret = -ETIMEDOUT;
763 		goto cleanup;
764 	}
765 
766 	if (irq <= 0) {
767 		ret = -ENODEV;
768 		goto cleanup;
769 	}
770 
771 	ret = vmbus_bus_init(irq);
772 	if (ret)
773 		goto cleanup;
774 
775 	return 0;
776 
777 cleanup:
778 	acpi_bus_unregister_driver(&vmbus_acpi_driver);
779 	return ret;
780 }
781 
782 
783 MODULE_LICENSE("GPL");
784 MODULE_VERSION(HV_DRV_VERSION);
785 
786 module_init(hv_acpi_init);
787