scsi: zfcp: trace HBA FSF response by default on dismiss or timedout late response
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / hv / vmbus_drv.c
CommitLineData
3e7ee490 1/*
3e7ee490
HJ
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>
b0069f43 20 * K. Y. Srinivasan <kys@microsoft.com>
52e5c1ce 21 *
3e7ee490 22 */
0a46618d
HJ
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
3e7ee490
HJ
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>
5a0e3ad6 31#include <linux/slab.h>
b0069f43
S
32#include <linux/acpi.h>
33#include <acpi/acpi_bus.h>
8b5d6d3b 34#include <linux/completion.h>
70415182 35#include <linux/cpu.h>
46a97191 36#include <linux/hyperv.h>
b0209501 37#include <linux/kernel_stat.h>
407dd164 38#include <asm/hyperv.h>
1f94ea81 39#include <asm/hypervisor.h>
302a3c0f 40#include <asm/mshyperv.h>
0f2a6619 41#include "hyperv_vmbus.h"
3e7ee490 42
3e7ee490 43
607c1a11 44static struct acpi_device *hv_acpi_dev;
1168ac22 45
59c0e4f0 46static struct tasklet_struct msg_dpc;
71a6655d 47static struct completion probe_event;
b0069f43 48static int irq;
98db4335 49
15b80d64
GKH
50struct hv_device_info {
51 u32 chn_id;
52 u32 chn_state;
53 uuid_le chn_type;
54 uuid_le chn_instance;
55
56 u32 monitor_id;
57 u32 server_monitor_pending;
58 u32 server_monitor_latency;
59 u32 server_monitor_conn_id;
60 u32 client_monitor_pending;
61 u32 client_monitor_latency;
62 u32 client_monitor_conn_id;
63
64 struct hv_dev_port_info inbound;
65 struct hv_dev_port_info outbound;
66};
67
cf6a2eac
S
68static int vmbus_exists(void)
69{
70 if (hv_acpi_dev == NULL)
71 return -ENODEV;
72
73 return 0;
74}
75
15b80d64 76
98db4335
S
77static void get_channel_info(struct hv_device *device,
78 struct hv_device_info *info)
79{
80 struct vmbus_channel_debug_info debug_info;
81
82 if (!device->channel)
83 return;
84
85 vmbus_get_debug_info(device->channel, &debug_info);
86
87 info->chn_id = debug_info.relid;
88 info->chn_state = debug_info.state;
89 memcpy(&info->chn_type, &debug_info.interfacetype,
358d2ee2 90 sizeof(uuid_le));
98db4335 91 memcpy(&info->chn_instance, &debug_info.interface_instance,
358d2ee2 92 sizeof(uuid_le));
98db4335
S
93
94 info->monitor_id = debug_info.monitorid;
95
96 info->server_monitor_pending = debug_info.servermonitor_pending;
97 info->server_monitor_latency = debug_info.servermonitor_latency;
98 info->server_monitor_conn_id = debug_info.servermonitor_connectionid;
99
100 info->client_monitor_pending = debug_info.clientmonitor_pending;
101 info->client_monitor_latency = debug_info.clientmonitor_latency;
102 info->client_monitor_conn_id = debug_info.clientmonitor_connectionid;
103
104 info->inbound.int_mask = debug_info.inbound.current_interrupt_mask;
105 info->inbound.read_idx = debug_info.inbound.current_read_index;
106 info->inbound.write_idx = debug_info.inbound.current_write_index;
107 info->inbound.bytes_avail_toread =
108 debug_info.inbound.bytes_avail_toread;
109 info->inbound.bytes_avail_towrite =
110 debug_info.inbound.bytes_avail_towrite;
3e7ee490 111
98db4335
S
112 info->outbound.int_mask =
113 debug_info.outbound.current_interrupt_mask;
114 info->outbound.read_idx = debug_info.outbound.current_read_index;
115 info->outbound.write_idx = debug_info.outbound.current_write_index;
116 info->outbound.bytes_avail_toread =
117 debug_info.outbound.bytes_avail_toread;
118 info->outbound.bytes_avail_towrite =
119 debug_info.outbound.bytes_avail_towrite;
120}
3e7ee490 121
fd776ba9
OH
122#define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2)
123static void print_alias_name(struct hv_device *hv_dev, char *alias_name)
124{
125 int i;
126 for (i = 0; i < VMBUS_ALIAS_LEN; i += 2)
127 sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]);
128}
129
98db4335
S
130/*
131 * vmbus_show_device_attr - Show the device attribute in sysfs.
132 *
133 * This is invoked when user does a
134 * "cat /sys/bus/vmbus/devices/<busdevice>/<attr name>"
135 */
90c9960e
GKH
136static ssize_t vmbus_show_device_attr(struct device *dev,
137 struct device_attribute *dev_attr,
98db4335
S
138 char *buf)
139{
e8e27047 140 struct hv_device *hv_dev = device_to_hv_device(dev);
7bb52384 141 struct hv_device_info *device_info;
fd776ba9 142 char alias_name[VMBUS_ALIAS_LEN + 1];
7bb52384 143 int ret = 0;
3e7ee490 144
7bb52384
S
145 device_info = kzalloc(sizeof(struct hv_device_info), GFP_KERNEL);
146 if (!device_info)
147 return ret;
3e7ee490 148
7bb52384 149 get_channel_info(hv_dev, device_info);
3e7ee490 150
98db4335 151 if (!strcmp(dev_attr->attr.name, "class_id")) {
2221f6ef 152 ret = sprintf(buf, "{%pUl}\n", device_info->chn_type.b);
98db4335 153 } else if (!strcmp(dev_attr->attr.name, "device_id")) {
2221f6ef 154 ret = sprintf(buf, "{%pUl}\n", device_info->chn_instance.b);
fd776ba9
OH
155 } else if (!strcmp(dev_attr->attr.name, "modalias")) {
156 print_alias_name(hv_dev, alias_name);
7bb52384 157 ret = sprintf(buf, "vmbus:%s\n", alias_name);
98db4335 158 } else if (!strcmp(dev_attr->attr.name, "state")) {
7bb52384 159 ret = sprintf(buf, "%d\n", device_info->chn_state);
98db4335 160 } else if (!strcmp(dev_attr->attr.name, "id")) {
7bb52384 161 ret = sprintf(buf, "%d\n", device_info->chn_id);
98db4335 162 } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
7bb52384 163 ret = sprintf(buf, "%d\n", device_info->outbound.int_mask);
98db4335 164 } else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
7bb52384 165 ret = sprintf(buf, "%d\n", device_info->outbound.read_idx);
98db4335 166 } else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
7bb52384 167 ret = sprintf(buf, "%d\n", device_info->outbound.write_idx);
98db4335 168 } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
7bb52384
S
169 ret = sprintf(buf, "%d\n",
170 device_info->outbound.bytes_avail_toread);
98db4335 171 } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
7bb52384
S
172 ret = sprintf(buf, "%d\n",
173 device_info->outbound.bytes_avail_towrite);
98db4335 174 } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
7bb52384 175 ret = sprintf(buf, "%d\n", device_info->inbound.int_mask);
98db4335 176 } else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
7bb52384 177 ret = sprintf(buf, "%d\n", device_info->inbound.read_idx);
98db4335 178 } else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
7bb52384 179 ret = sprintf(buf, "%d\n", device_info->inbound.write_idx);
98db4335 180 } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
7bb52384
S
181 ret = sprintf(buf, "%d\n",
182 device_info->inbound.bytes_avail_toread);
98db4335 183 } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
7bb52384
S
184 ret = sprintf(buf, "%d\n",
185 device_info->inbound.bytes_avail_towrite);
98db4335 186 } else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
7bb52384 187 ret = sprintf(buf, "%d\n", device_info->monitor_id);
98db4335 188 } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
7bb52384 189 ret = sprintf(buf, "%d\n", device_info->server_monitor_pending);
98db4335 190 } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
7bb52384 191 ret = sprintf(buf, "%d\n", device_info->server_monitor_latency);
98db4335 192 } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
7bb52384
S
193 ret = sprintf(buf, "%d\n",
194 device_info->server_monitor_conn_id);
98db4335 195 } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
7bb52384 196 ret = sprintf(buf, "%d\n", device_info->client_monitor_pending);
98db4335 197 } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
7bb52384 198 ret = sprintf(buf, "%d\n", device_info->client_monitor_latency);
98db4335 199 } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
7bb52384
S
200 ret = sprintf(buf, "%d\n",
201 device_info->client_monitor_conn_id);
98db4335 202 }
7bb52384
S
203
204 kfree(device_info);
205 return ret;
98db4335 206}
3e7ee490 207
454f18a9 208/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
3e7ee490
HJ
209static struct device_attribute vmbus_device_attrs[] = {
210 __ATTR(id, S_IRUGO, vmbus_show_device_attr, NULL),
211 __ATTR(state, S_IRUGO, vmbus_show_device_attr, NULL),
212 __ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL),
213 __ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL),
214 __ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL),
fd776ba9 215 __ATTR(modalias, S_IRUGO, vmbus_show_device_attr, NULL),
3e7ee490
HJ
216
217 __ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
218 __ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
219 __ATTR(server_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
220
221 __ATTR(client_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
222 __ATTR(client_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
223 __ATTR(client_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
224
225 __ATTR(out_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
226 __ATTR(out_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
227 __ATTR(out_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
228 __ATTR(out_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
229 __ATTR(out_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
230
231 __ATTR(in_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
232 __ATTR(in_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
233 __ATTR(in_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
234 __ATTR(in_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
235 __ATTR(in_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
236 __ATTR_NULL
237};
3e7ee490 238
793be9c7 239
adde2487
S
240/*
241 * vmbus_uevent - add uevent for our device
242 *
243 * This routine is invoked when a device is added or removed on the vmbus to
244 * generate a uevent to udev in the userspace. The udev will then look at its
245 * rule and the uevent generated here to load the appropriate driver
0ddda660
S
246 *
247 * The alias string will be of the form vmbus:guid where guid is the string
248 * representation of the device guid (each byte of the guid will be
249 * represented with two hex characters.
adde2487
S
250 */
251static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
252{
253 struct hv_device *dev = device_to_hv_device(device);
fd776ba9
OH
254 int ret;
255 char alias_name[VMBUS_ALIAS_LEN + 1];
0ddda660 256
fd776ba9 257 print_alias_name(dev, alias_name);
0ddda660
S
258 ret = add_uevent_var(env, "MODALIAS=vmbus:%s", alias_name);
259 return ret;
adde2487
S
260}
261
5841a829
S
262static uuid_le null_guid;
263
264static inline bool is_null_guid(const __u8 *guid)
265{
266 if (memcmp(guid, &null_guid, sizeof(uuid_le)))
267 return false;
268 return true;
269}
270
3037a7b6
S
271/*
272 * Return a matching hv_vmbus_device_id pointer.
273 * If there is no match, return NULL.
274 */
275static const struct hv_vmbus_device_id *hv_vmbus_get_id(
276 const struct hv_vmbus_device_id *id,
277 __u8 *guid)
278{
279 for (; !is_null_guid(id->guid); id++)
280 if (!memcmp(&id->guid, guid, sizeof(uuid_le)))
281 return id;
282
283 return NULL;
284}
285
286
b7fc147b
S
287
288/*
289 * vmbus_match - Attempt to match the specified device to the specified driver
290 */
291static int vmbus_match(struct device *device, struct device_driver *driver)
292{
b7fc147b 293 struct hv_driver *drv = drv_to_hv_drv(driver);
e8e27047 294 struct hv_device *hv_dev = device_to_hv_device(device);
b7fc147b 295
3037a7b6
S
296 if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b))
297 return 1;
de632a2b 298
5841a829 299 return 0;
b7fc147b
S
300}
301
f1f0d67b
S
302/*
303 * vmbus_probe - Add the new vmbus's child device
304 */
305static int vmbus_probe(struct device *child_device)
306{
307 int ret = 0;
308 struct hv_driver *drv =
309 drv_to_hv_drv(child_device->driver);
9efd21e1 310 struct hv_device *dev = device_to_hv_device(child_device);
84946899 311 const struct hv_vmbus_device_id *dev_id;
f1f0d67b 312
84946899 313 dev_id = hv_vmbus_get_id(drv->id_table, dev->dev_type.b);
9efd21e1 314 if (drv->probe) {
84946899 315 ret = drv->probe(dev, dev_id);
b14a7b30 316 if (ret != 0)
0a46618d
HJ
317 pr_err("probe failed for device %s (%d)\n",
318 dev_name(child_device), ret);
f1f0d67b 319
f1f0d67b 320 } else {
0a46618d
HJ
321 pr_err("probe not set for driver %s\n",
322 dev_name(child_device));
6de925b1 323 ret = -ENODEV;
f1f0d67b
S
324 }
325 return ret;
326}
327
c5dce3db
S
328/*
329 * vmbus_remove - Remove a vmbus device
330 */
331static int vmbus_remove(struct device *child_device)
332{
d4372179 333 struct hv_driver *drv = drv_to_hv_drv(child_device->driver);
415b023a 334 struct hv_device *dev = device_to_hv_device(child_device);
c5dce3db 335
d4372179
S
336 if (drv->remove)
337 drv->remove(dev);
338 else
339 pr_err("remove not set for driver %s\n",
340 dev_name(child_device));
c5dce3db
S
341
342 return 0;
343}
344
eb1bb259
S
345
346/*
347 * vmbus_shutdown - Shutdown a vmbus device
348 */
349static void vmbus_shutdown(struct device *child_device)
350{
351 struct hv_driver *drv;
ca6887fb 352 struct hv_device *dev = device_to_hv_device(child_device);
eb1bb259
S
353
354
355 /* The device may not be attached yet */
356 if (!child_device->driver)
357 return;
358
359 drv = drv_to_hv_drv(child_device->driver);
360
ca6887fb
S
361 if (drv->shutdown)
362 drv->shutdown(dev);
eb1bb259
S
363
364 return;
365}
366
086e7a56
S
367
368/*
369 * vmbus_device_release - Final callback release of the vmbus child device
370 */
371static void vmbus_device_release(struct device *device)
372{
e8e27047 373 struct hv_device *hv_dev = device_to_hv_device(device);
086e7a56 374
e8e27047 375 kfree(hv_dev);
086e7a56
S
376
377}
378
454f18a9 379/* The one and only one */
9adcac5c
S
380static struct bus_type hv_bus = {
381 .name = "vmbus",
382 .match = vmbus_match,
383 .shutdown = vmbus_shutdown,
384 .remove = vmbus_remove,
385 .probe = vmbus_probe,
386 .uevent = vmbus_uevent,
387 .dev_attrs = vmbus_device_attrs,
3e7ee490
HJ
388};
389
adf874cb 390static const char *driver_name = "hyperv";
36199a99 391
36199a99 392
bf6506f6
TT
393struct onmessage_work_context {
394 struct work_struct work;
395 struct hv_message msg;
396};
397
398static void vmbus_onmessage_work(struct work_struct *work)
399{
400 struct onmessage_work_context *ctx;
401
402 ctx = container_of(work, struct onmessage_work_context,
403 work);
404 vmbus_onmessage(&ctx->msg);
405 kfree(ctx);
406}
407
62c1059d 408static void vmbus_on_msg_dpc(unsigned long data)
36199a99
GKH
409{
410 int cpu = smp_processor_id();
411 void *page_addr = hv_context.synic_message_page[cpu];
412 struct hv_message *msg = (struct hv_message *)page_addr +
413 VMBUS_MESSAGE_SINT;
bf6506f6 414 struct onmessage_work_context *ctx;
36199a99
GKH
415
416 while (1) {
417 if (msg->header.message_type == HVMSG_NONE) {
418 /* no msg */
419 break;
420 } else {
bf6506f6
TT
421 ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
422 if (ctx == NULL)
36199a99 423 continue;
bf6506f6
TT
424 INIT_WORK(&ctx->work, vmbus_onmessage_work);
425 memcpy(&ctx->msg, msg, sizeof(*msg));
da9fcb72 426 queue_work(vmbus_connection.work_queue, &ctx->work);
36199a99
GKH
427 }
428
429 msg->header.message_type = HVMSG_NONE;
430
431 /*
432 * Make sure the write to MessageType (ie set to
433 * HVMSG_NONE) happens before we read the
434 * MessagePending and EOMing. Otherwise, the EOMing
435 * will not deliver any more messages since there is
436 * no empty slot
437 */
540005dc 438 mb();
36199a99
GKH
439
440 if (msg->header.message_flags.msg_pending) {
441 /*
442 * This will cause message queue rescan to
443 * possibly deliver another msg from the
444 * hypervisor
445 */
446 wrmsrl(HV_X64_MSR_EOM, 0);
447 }
448 }
449}
450
ae4636e6 451static irqreturn_t vmbus_isr(int irq, void *dev_id)
36199a99 452{
36199a99
GKH
453 int cpu = smp_processor_id();
454 void *page_addr;
455 struct hv_message *msg;
456 union hv_synic_event_flags *event;
ae4636e6 457 bool handled = false;
36199a99 458
5ab05951
S
459 page_addr = hv_context.synic_event_page[cpu];
460 if (page_addr == NULL)
461 return IRQ_NONE;
462
463 event = (union hv_synic_event_flags *)page_addr +
464 VMBUS_MESSAGE_SINT;
7341d908
S
465 /*
466 * Check for events before checking for messages. This is the order
467 * in which events and messages are checked in Windows guests on
468 * Hyper-V, and the Windows team suggested we do the same.
469 */
36199a99 470
6552ecd7
S
471 if ((vmbus_proto_version == VERSION_WS2008) ||
472 (vmbus_proto_version == VERSION_WIN7)) {
36199a99 473
6552ecd7
S
474 /* Since we are a child, we only need to check bit 0 */
475 if (sync_test_and_clear_bit(0,
476 (unsigned long *) &event->flags32[0])) {
477 handled = true;
478 }
479 } else {
480 /*
481 * Our host is win8 or above. The signaling mechanism
482 * has changed and we can directly look at the event page.
483 * If bit n is set then we have an interrup on the channel
484 * whose id is n.
485 */
ae4636e6 486 handled = true;
ae4636e6 487 }
793be9c7 488
6552ecd7 489 if (handled)
db11f12a 490 tasklet_schedule(hv_context.event_dpc[cpu]);
6552ecd7
S
491
492
7341d908
S
493 page_addr = hv_context.synic_message_page[cpu];
494 msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
495
496 /* Check if there are actual msgs to be processed */
497 if (msg->header.message_type != HVMSG_NONE) {
498 handled = true;
499 tasklet_schedule(&msg_dpc);
500 }
501
ae4636e6 502 if (handled)
793be9c7 503 return IRQ_HANDLED;
ae4636e6 504 else
793be9c7 505 return IRQ_NONE;
793be9c7
S
506}
507
b0209501
S
508/*
509 * vmbus interrupt flow handler:
510 * vmbus interrupts can concurrently occur on multiple CPUs and
511 * can be handled concurrently.
512 */
513
83ebf6e5 514static void vmbus_flow_handler(unsigned int irq, struct irq_desc *desc)
b0209501
S
515{
516 kstat_incr_irqs_this_cpu(irq, desc);
517
518 desc->action->handler(irq, desc->action->dev_id);
519}
520
70415182
VK
521#ifdef CONFIG_HOTPLUG_CPU
522static int hyperv_cpu_disable(void)
523{
524 return -ENOSYS;
525}
526
527static void hv_cpu_hotplug_quirk(bool vmbus_loaded)
528{
529 static void *previous_cpu_disable;
530
531 /*
532 * Offlining a CPU when running on newer hypervisors (WS2012R2, Win8,
533 * ...) is not supported at this moment as channel interrupts are
534 * distributed across all of them.
535 */
536
537 if ((vmbus_proto_version == VERSION_WS2008) ||
538 (vmbus_proto_version == VERSION_WIN7))
539 return;
540
541 if (vmbus_loaded) {
542 previous_cpu_disable = smp_ops.cpu_disable;
543 smp_ops.cpu_disable = hyperv_cpu_disable;
544 pr_notice("CPU offlining is not supported by hypervisor\n");
545 } else if (previous_cpu_disable)
546 smp_ops.cpu_disable = previous_cpu_disable;
547}
548#else
549static void hv_cpu_hotplug_quirk(bool vmbus_loaded)
550{
551}
552#endif
553
3e189519 554/*
90c9960e
GKH
555 * vmbus_bus_init -Main vmbus driver initialization routine.
556 *
557 * Here, we
0686e4f4 558 * - initialize the vmbus driver context
0686e4f4
LL
559 * - invoke the vmbus hv main init routine
560 * - get the irq resource
0686e4f4 561 * - retrieve the channel offers
90c9960e 562 */
9aaa995e 563static int vmbus_bus_init(int irq)
3e7ee490 564{
90c9960e 565 int ret;
3e7ee490 566
6d26e38f
GKH
567 /* Hypervisor initialization...setup hypercall page..etc */
568 ret = hv_init();
90c9960e 569 if (ret != 0) {
0a46618d 570 pr_err("Unable to initialize the hypervisor - 0x%x\n", ret);
d6c1c5de 571 return ret;
3e7ee490
HJ
572 }
573
59c0e4f0 574 tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0);
3e7ee490 575
9adcac5c 576 ret = bus_register(&hv_bus);
d6c1c5de 577 if (ret)
8b9987e9 578 goto err_cleanup;
3e7ee490 579
20ed3ef7 580 ret = request_irq(irq, vmbus_isr, 0, driver_name, hv_acpi_dev);
3e7ee490 581
90c9960e 582 if (ret != 0) {
0a46618d 583 pr_err("Unable to request IRQ %d\n",
9aaa995e 584 irq);
8b9987e9 585 goto err_unregister;
3e7ee490 586 }
3e7ee490 587
b0209501
S
588 /*
589 * Vmbus interrupts can be handled concurrently on
590 * different CPUs. Establish an appropriate interrupt flow
591 * handler that can support this model.
592 */
593 irq_set_handler(irq, vmbus_flow_handler);
594
302a3c0f
S
595 /*
596 * Register our interrupt handler.
597 */
598 hv_register_vmbus_handler(irq, vmbus_isr);
3e7ee490 599
800b6902 600 /*
302a3c0f 601 * Initialize the per-cpu interrupt state and
800b6902
S
602 * connect to the host.
603 */
302a3c0f 604 on_each_cpu(hv_synic_init, NULL, 1);
800b6902 605 ret = vmbus_connect();
8b9987e9
S
606 if (ret)
607 goto err_irq;
800b6902 608
70415182 609 hv_cpu_hotplug_quirk(true);
2d6e882b 610 vmbus_request_offers();
8b5d6d3b 611
d6c1c5de 612 return 0;
8b9987e9
S
613
614err_irq:
615 free_irq(irq, hv_acpi_dev);
616
617err_unregister:
618 bus_unregister(&hv_bus);
619
620err_cleanup:
9391c802 621 hv_cleanup(false);
8b9987e9
S
622
623 return ret;
3e7ee490
HJ
624}
625
90c9960e 626/**
768fa219
GKH
627 * __vmbus_child_driver_register - Register a vmbus's driver
628 * @drv: Pointer to driver structure you want to register
629 * @owner: owner module of the drv
630 * @mod_name: module name string
3e189519
HJ
631 *
632 * Registers the given driver with Linux through the 'driver_register()' call
768fa219 633 * and sets up the hyper-v vmbus handling for this driver.
3e189519
HJ
634 * It will return the state of the 'driver_register()' call.
635 *
90c9960e 636 */
768fa219 637int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, const char *mod_name)
3e7ee490 638{
5d48a1c2 639 int ret;
3e7ee490 640
768fa219 641 pr_info("registering driver %s\n", hv_driver->name);
3e7ee490 642
cf6a2eac
S
643 ret = vmbus_exists();
644 if (ret < 0)
645 return ret;
646
768fa219
GKH
647 hv_driver->driver.name = hv_driver->name;
648 hv_driver->driver.owner = owner;
649 hv_driver->driver.mod_name = mod_name;
650 hv_driver->driver.bus = &hv_bus;
3e7ee490 651
768fa219 652 ret = driver_register(&hv_driver->driver);
3e7ee490 653
5d48a1c2 654 return ret;
3e7ee490 655}
768fa219 656EXPORT_SYMBOL_GPL(__vmbus_driver_register);
3e7ee490 657
90c9960e 658/**
768fa219
GKH
659 * vmbus_driver_unregister() - Unregister a vmbus's driver
660 * @drv: Pointer to driver structure you want to un-register
3e189519 661 *
768fa219
GKH
662 * Un-register the given driver that was previous registered with a call to
663 * vmbus_driver_register()
90c9960e 664 */
768fa219 665void vmbus_driver_unregister(struct hv_driver *hv_driver)
3e7ee490 666{
768fa219 667 pr_info("unregistering driver %s\n", hv_driver->name);
3e7ee490 668
cf6a2eac 669 if (!vmbus_exists())
8f257a14 670 driver_unregister(&hv_driver->driver);
3e7ee490 671}
768fa219 672EXPORT_SYMBOL_GPL(vmbus_driver_unregister);
3e7ee490 673
3e189519 674/*
f2c73011 675 * vmbus_device_create - Creates and registers a new child device
3e189519 676 * on the vmbus.
90c9960e 677 */
f2c73011 678struct hv_device *vmbus_device_create(uuid_le *type,
358d2ee2 679 uuid_le *instance,
89733aa9 680 struct vmbus_channel *channel)
3e7ee490 681{
3d3b5518 682 struct hv_device *child_device_obj;
3e7ee490 683
6bad88da
S
684 child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL);
685 if (!child_device_obj) {
0a46618d 686 pr_err("Unable to allocate device object for child device\n");
3e7ee490
HJ
687 return NULL;
688 }
689
cae5b843 690 child_device_obj->channel = channel;
358d2ee2 691 memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
ca623ad3 692 memcpy(&child_device_obj->dev_instance, instance,
358d2ee2 693 sizeof(uuid_le));
3e7ee490 694
3e7ee490 695
3e7ee490
HJ
696 return child_device_obj;
697}
698
3e189519 699/*
22794281 700 * vmbus_device_register - Register the child device
90c9960e 701 */
22794281 702int vmbus_device_register(struct hv_device *child_device_obj)
3e7ee490 703{
90c9960e 704 int ret = 0;
6bad88da 705
f4888417 706 static atomic_t device_num = ATOMIC_INIT(0);
3e7ee490 707
6bad88da 708 dev_set_name(&child_device_obj->device, "vmbus_0_%d",
90c9960e 709 atomic_inc_return(&device_num));
3e7ee490 710
0bce28b6 711 child_device_obj->device.bus = &hv_bus;
607c1a11 712 child_device_obj->device.parent = &hv_acpi_dev->dev;
6bad88da 713 child_device_obj->device.release = vmbus_device_release;
3e7ee490 714
90c9960e
GKH
715 /*
716 * Register with the LDM. This will kick off the driver/device
717 * binding...which will eventually call vmbus_match() and vmbus_probe()
718 */
6bad88da 719 ret = device_register(&child_device_obj->device);
3e7ee490 720
3e7ee490 721 if (ret)
0a46618d 722 pr_err("Unable to register child device\n");
3e7ee490 723 else
a370f956 724 pr_debug("child device %s registered\n",
0a46618d 725 dev_name(&child_device_obj->device));
3e7ee490 726
3e7ee490
HJ
727 return ret;
728}
729
3e189519 730/*
696453ba 731 * vmbus_device_unregister - Remove the specified child device
3e189519 732 * from the vmbus.
90c9960e 733 */
696453ba 734void vmbus_device_unregister(struct hv_device *device_obj)
3e7ee490 735{
a370f956
FS
736 pr_debug("child device %s unregistered\n",
737 dev_name(&device_obj->device));
738
90c9960e
GKH
739 /*
740 * Kick off the process of unregistering the device.
741 * This will call vmbus_remove() and eventually vmbus_device_release()
742 */
6bad88da 743 device_unregister(&device_obj->device);
3e7ee490
HJ
744}
745
3e7ee490 746
b0069f43
S
747/*
748 * VMBUS is an acpi enumerated device. Get the the IRQ information
749 * from DSDT.
750 */
751
752static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *irq)
753{
754
755 if (res->type == ACPI_RESOURCE_TYPE_IRQ) {
756 struct acpi_resource_irq *irqp;
757 irqp = &res->data.irq;
758
759 *((unsigned int *)irq) = irqp->interrupts[0];
760 }
761
762 return AE_OK;
763}
764
765static int vmbus_acpi_add(struct acpi_device *device)
766{
767 acpi_status result;
768
607c1a11
S
769 hv_acpi_dev = device;
770
0a4425b6
S
771 result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
772 vmbus_walk_resources, &irq);
b0069f43
S
773
774 if (ACPI_FAILURE(result)) {
775 complete(&probe_event);
776 return -ENODEV;
777 }
778 complete(&probe_event);
779 return 0;
780}
781
782static const struct acpi_device_id vmbus_acpi_device_ids[] = {
783 {"VMBUS", 0},
9d7b18d1 784 {"VMBus", 0},
b0069f43
S
785 {"", 0},
786};
787MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids);
788
789static struct acpi_driver vmbus_acpi_driver = {
790 .name = "vmbus",
791 .ids = vmbus_acpi_device_ids,
792 .ops = {
793 .add = vmbus_acpi_add,
794 },
795};
796
607c1a11 797static int __init hv_acpi_init(void)
1168ac22 798{
2dda95f8 799 int ret, t;
b0069f43 800
1f94ea81 801 if (x86_hyper != &x86_hyper_ms_hyperv)
0592969e
JW
802 return -ENODEV;
803
b0069f43
S
804 init_completion(&probe_event);
805
806 /*
807 * Get irq resources first.
808 */
809
0246604c
S
810 ret = acpi_bus_register_driver(&vmbus_acpi_driver);
811
b0069f43
S
812 if (ret)
813 return ret;
814
2dda95f8
S
815 t = wait_for_completion_timeout(&probe_event, 5*HZ);
816 if (t == 0) {
817 ret = -ETIMEDOUT;
818 goto cleanup;
819 }
b0069f43
S
820
821 if (irq <= 0) {
2dda95f8
S
822 ret = -ENODEV;
823 goto cleanup;
b0069f43
S
824 }
825
91fd799e
S
826 ret = vmbus_bus_init(irq);
827 if (ret)
2dda95f8
S
828 goto cleanup;
829
830 return 0;
831
832cleanup:
833 acpi_bus_unregister_driver(&vmbus_acpi_driver);
cf6a2eac 834 hv_acpi_dev = NULL;
91fd799e 835 return ret;
1168ac22
S
836}
837
93e5bd06
S
838static void __exit vmbus_exit(void)
839{
840
841 free_irq(irq, hv_acpi_dev);
842 vmbus_free_channels();
843 bus_unregister(&hv_bus);
9391c802 844 hv_cleanup(false);
93e5bd06 845 acpi_bus_unregister_driver(&vmbus_acpi_driver);
70415182 846 hv_cpu_hotplug_quirk(false);
93e5bd06
S
847}
848
1168ac22 849
90c9960e 850MODULE_LICENSE("GPL");
26c14cc1 851MODULE_VERSION(HV_DRV_VERSION);
3e7ee490 852
43d4e119 853subsys_initcall(hv_acpi_init);
93e5bd06 854module_exit(vmbus_exit);