3 * Copyright (c) 2009, Microsoft Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
19 * Haiyang Zhang <haiyangz@microsoft.com>
20 * Hank Janssen <hjanssen@microsoft.com>
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>
39 /* FIXME! We need to do this dynamically for PIC and APIC system */
41 #define VMBUS_IRQ_VECTOR IRQ5_VECTOR
46 /* Main vmbus driver data structure */
47 struct vmbus_driver_context {
48 /* !! These must be the first 2 fields !! */
49 /* The driver field is not used in here. Instead, the bus field is */
50 /* used to represent the driver */
51 struct driver_context drv_ctx;
52 struct vmbus_driver drv_obj;
55 struct tasklet_struct msg_dpc;
56 struct tasklet_struct event_dpc;
58 /* The bus root device */
59 struct device_context device_ctx;
65 static int vmbus_match(struct device *device, struct device_driver *driver);
66 static int vmbus_probe(struct device *device);
67 static int vmbus_remove(struct device *device);
68 static void vmbus_shutdown(struct device *device);
69 static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env);
70 static void vmbus_msg_dpc(unsigned long data);
71 static void vmbus_event_dpc(unsigned long data);
73 static irqreturn_t vmbus_isr(int irq, void* dev_id);
75 static void vmbus_device_release(struct device *device);
76 static void vmbus_bus_release(struct device *device);
78 static struct hv_device *vmbus_child_device_create(struct hv_guid *type, struct hv_guid *instance, void *context);
79 static void vmbus_child_device_destroy(struct hv_device *device_obj);
80 static int vmbus_child_device_register(struct hv_device *root_device_obj, struct hv_device *child_device_obj);
81 static void vmbus_child_device_unregister(struct hv_device *child_device_obj);
82 static void vmbus_child_device_get_info(struct hv_device *device_obj, struct hv_device_info *device_info);
84 /* static ssize_t vmbus_show_class_id(struct device *dev, struct device_attribute *attr, char *buf); */
85 /* static ssize_t vmbus_show_device_id(struct device *dev, struct device_attribute *attr, char *buf); */
87 static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf);
93 /* Global logging setting */
95 /* unsigned int vmbus_loglevel= (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */
96 /* unsigned int vmbus_loglevel= (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */
97 unsigned int vmbus_loglevel= (ALL_MODULES << 16 | INFO_LVL);
98 EXPORT_SYMBOL(vmbus_loglevel);
100 static int vmbus_irq = VMBUS_IRQ;
102 /* Setup /proc/sys/bus/vmbus/vmbus_loglevel */
103 /* Allow usage of sysctl cmd to set the logging level */
105 /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
107 static struct device_attribute vmbus_device_attrs[] = {
108 __ATTR(id, S_IRUGO, vmbus_show_device_attr, NULL),
109 __ATTR(state, S_IRUGO, vmbus_show_device_attr, NULL),
110 __ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL),
111 __ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL),
112 __ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL),
114 __ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
115 __ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
116 __ATTR(server_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
118 __ATTR(client_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
119 __ATTR(client_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
120 __ATTR(client_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
122 __ATTR(out_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
123 __ATTR(out_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
124 __ATTR(out_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
125 __ATTR(out_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
126 __ATTR(out_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
128 __ATTR(in_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
129 __ATTR(in_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
130 __ATTR(in_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
131 __ATTR(in_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
132 __ATTR(in_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
136 /* The one and only one */
137 static struct vmbus_driver_context g_vmbus_drv={
139 .bus.match = vmbus_match,
140 .bus.shutdown = vmbus_shutdown,
141 .bus.remove = vmbus_remove,
142 .bus.probe = vmbus_probe,
143 .bus.uevent = vmbus_uevent,
144 .bus.dev_attrs = vmbus_device_attrs,
154 Name: vmbus_show_device_attr()
156 Desc: Show the device attribute in sysfs. This is invoked when user does a "cat /sys/bus/vmbus/devices/<bus device>/<attr name>"
159 static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf)
161 struct device_context *device_ctx = device_to_device_context(dev);
162 struct hv_device_info device_info;
164 memset(&device_info, 0, sizeof(struct hv_device_info));
166 vmbus_child_device_get_info(&device_ctx->device_obj, &device_info);
168 if (!strcmp(dev_attr->attr.name, "class_id"))
170 return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n",
171 device_info.ChannelType.data[3], device_info.ChannelType.data[2],
172 device_info.ChannelType.data[1], device_info.ChannelType.data[0],
173 device_info.ChannelType.data[5], device_info.ChannelType.data[4],
174 device_info.ChannelType.data[7], device_info.ChannelType.data[6],
175 device_info.ChannelType.data[8], device_info.ChannelType.data[9],
176 device_info.ChannelType.data[10], device_info.ChannelType.data[11],
177 device_info.ChannelType.data[12], device_info.ChannelType.data[13],
178 device_info.ChannelType.data[14], device_info.ChannelType.data[15]);
181 else if (!strcmp(dev_attr->attr.name, "device_id"))
183 return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n",
184 device_info.ChannelInstance.data[3], device_info.ChannelInstance.data[2],
185 device_info.ChannelInstance.data[1], device_info.ChannelInstance.data[0],
186 device_info.ChannelInstance.data[5], device_info.ChannelInstance.data[4],
187 device_info.ChannelInstance.data[7], device_info.ChannelInstance.data[6],
188 device_info.ChannelInstance.data[8], device_info.ChannelInstance.data[9],
189 device_info.ChannelInstance.data[10], device_info.ChannelInstance.data[11],
190 device_info.ChannelInstance.data[12], device_info.ChannelInstance.data[13],
191 device_info.ChannelInstance.data[14], device_info.ChannelInstance.data[15]);
193 else if (!strcmp(dev_attr->attr.name, "state"))
195 return sprintf(buf, "%d\n", device_info.ChannelState);
197 else if (!strcmp(dev_attr->attr.name, "id"))
199 return sprintf(buf, "%d\n", device_info.ChannelId);
201 else if (!strcmp(dev_attr->attr.name, "out_intr_mask"))
203 return sprintf(buf, "%d\n", device_info.Outbound.InterruptMask);
205 else if (!strcmp(dev_attr->attr.name, "out_read_index"))
207 return sprintf(buf, "%d\n", device_info.Outbound.ReadIndex);
209 else if (!strcmp(dev_attr->attr.name, "out_write_index"))
211 return sprintf(buf, "%d\n", device_info.Outbound.WriteIndex);
213 else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail"))
215 return sprintf(buf, "%d\n", device_info.Outbound.BytesAvailToRead);
217 else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail"))
219 return sprintf(buf, "%d\n", device_info.Outbound.BytesAvailToWrite);
221 else if (!strcmp(dev_attr->attr.name, "in_intr_mask"))
223 return sprintf(buf, "%d\n", device_info.Inbound.InterruptMask);
225 else if (!strcmp(dev_attr->attr.name, "in_read_index"))
227 return sprintf(buf, "%d\n", device_info.Inbound.ReadIndex);
229 else if (!strcmp(dev_attr->attr.name, "in_write_index"))
231 return sprintf(buf, "%d\n", device_info.Inbound.WriteIndex);
233 else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail"))
235 return sprintf(buf, "%d\n", device_info.Inbound.BytesAvailToRead);
237 else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail"))
239 return sprintf(buf, "%d\n", device_info.Inbound.BytesAvailToWrite);
241 else if (!strcmp(dev_attr->attr.name, "monitor_id"))
243 return sprintf(buf, "%d\n", device_info.MonitorId);
245 else if (!strcmp(dev_attr->attr.name, "server_monitor_pending"))
247 return sprintf(buf, "%d\n", device_info.ServerMonitorPending);
249 else if (!strcmp(dev_attr->attr.name, "server_monitor_latency"))
251 return sprintf(buf, "%d\n", device_info.ServerMonitorLatency);
253 else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id"))
255 return sprintf(buf, "%d\n", device_info.ServerMonitorConnectionId);
257 else if (!strcmp(dev_attr->attr.name, "client_monitor_pending"))
259 return sprintf(buf, "%d\n", device_info.ClientMonitorPending);
261 else if (!strcmp(dev_attr->attr.name, "client_monitor_latency"))
263 return sprintf(buf, "%d\n", device_info.ClientMonitorLatency);
265 else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id"))
267 return sprintf(buf, "%d\n", device_info.ClientMonitorConnectionId);
277 Name: vmbus_show_class_id()
279 Desc: Show the device class id in sysfs
282 /* static ssize_t vmbus_show_class_id(struct device *dev, struct device_attribute *attr, char *buf) */
284 /* struct device_context *device_ctx = device_to_device_context(dev); */
285 /* return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n", */
286 /* device_ctx->class_id[3], device_ctx->class_id[2], device_ctx->class_id[1], device_ctx->class_id[0], */
287 /* device_ctx->class_id[5], device_ctx->class_id[4], */
288 /* device_ctx->class_id[7], device_ctx->class_id[6], */
289 /* device_ctx->class_id[8], device_ctx->class_id[9], device_ctx->class_id[10], device_ctx->class_id[11], device_ctx->class_id[12], device_ctx->class_id[13], device_ctx->class_id[14], device_ctx->class_id[15]); */
294 Name: vmbus_show_device_id()
296 Desc: Show the device instance id in sysfs
299 /* static ssize_t vmbus_show_device_id(struct device *dev, struct device_attribute *attr, char *buf) */
301 /* struct device_context *device_ctx = device_to_device_context(dev); */
302 /* return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n", */
303 /* device_ctx->device_id[3], device_ctx->device_id[2], device_ctx->device_id[1], device_ctx->device_id[0], */
304 /* device_ctx->device_id[5], device_ctx->device_id[4], */
305 /* device_ctx->device_id[7], device_ctx->device_id[6], */
306 /* device_ctx->device_id[8], device_ctx->device_id[9], device_ctx->device_id[10], device_ctx->device_id[11], device_ctx->device_id[12], device_ctx->device_id[13], device_ctx->device_id[14], device_ctx->device_id[15]); */
311 Name: vmbus_bus_init()
313 Desc: Main vmbus driver initialization routine. Here, we
314 - initialize the vmbus driver context
315 - setup various driver entry points
316 - invoke the vmbus hv main init routine
317 - get the irq resource
318 - invoke the vmbus to add the vmbus root device
319 - setup the vmbus root device
320 - retrieve the channel offers
322 static int vmbus_bus_init(PFN_DRIVERINITIALIZE pfn_drv_init)
325 unsigned int vector=0;
327 struct vmbus_driver_context *vmbus_drv_ctx=&g_vmbus_drv;
328 struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
330 struct device_context *dev_ctx=&g_vmbus_drv.device_ctx;
332 DPRINT_ENTER(VMBUS_DRV);
334 /* Set this up to allow lower layer to callback to add/remove child devices on the bus */
335 vmbus_drv_obj->OnChildDeviceCreate = vmbus_child_device_create;
336 vmbus_drv_obj->OnChildDeviceDestroy = vmbus_child_device_destroy;
337 vmbus_drv_obj->OnChildDeviceAdd = vmbus_child_device_register;
338 vmbus_drv_obj->OnChildDeviceRemove = vmbus_child_device_unregister;
340 /* Call to bus driver to initialize */
341 ret = pfn_drv_init(&vmbus_drv_obj->Base);
344 DPRINT_ERR(VMBUS_DRV, "Unable to initialize vmbus (%d)", ret);
349 if (!vmbus_drv_obj->Base.OnDeviceAdd)
351 DPRINT_ERR(VMBUS_DRV, "OnDeviceAdd() routine not set");
356 vmbus_drv_ctx->bus.name = vmbus_drv_obj->Base.name;
358 /* Initialize the bus context */
359 tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_msg_dpc, (unsigned long)vmbus_drv_obj);
360 tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc, (unsigned long)vmbus_drv_obj);
362 /* Now, register the bus driver with LDM */
363 ret = bus_register(&vmbus_drv_ctx->bus);
370 /* Get the interrupt resource */
371 ret = request_irq(vmbus_irq,
374 vmbus_drv_obj->Base.name,
379 DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d", vmbus_irq);
381 bus_unregister(&vmbus_drv_ctx->bus);
386 vector = VMBUS_IRQ_VECTOR;
388 DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector);
390 /* Call to bus driver to add the root device */
391 memset(dev_ctx, 0, sizeof(struct device_context));
393 ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector);
396 DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to add vmbus root device");
398 free_irq(vmbus_irq, NULL);
400 bus_unregister(&vmbus_drv_ctx->bus);
405 /* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */
406 dev_set_name(&dev_ctx->device, "vmbus_0_0");
407 memcpy(&dev_ctx->class_id, &dev_ctx->device_obj.deviceType, sizeof(struct hv_guid));
408 memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.deviceInstance, sizeof(struct hv_guid));
410 /* No need to bind a driver to the root device. */
411 dev_ctx->device.parent = NULL;
412 dev_ctx->device.bus = &vmbus_drv_ctx->bus; /* NULL; vmbus_remove() does not get invoked */
414 /* Setup the device dispatch table */
415 dev_ctx->device.release = vmbus_bus_release;
417 /* Setup the bus as root device */
418 ret = device_register(&dev_ctx->device);
421 DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to register vmbus root device");
423 free_irq(vmbus_irq, NULL);
424 bus_unregister(&vmbus_drv_ctx->bus);
431 vmbus_drv_obj->GetChannelOffers();
434 DPRINT_EXIT(VMBUS_DRV);
442 Name: vmbus_bus_exit()
444 Desc: Terminate the vmbus driver. This routine is opposite of vmbus_bus_init()
447 static void vmbus_bus_exit(void)
449 struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
450 struct vmbus_driver_context *vmbus_drv_ctx=&g_vmbus_drv;
452 struct device_context *dev_ctx=&g_vmbus_drv.device_ctx;
454 DPRINT_ENTER(VMBUS_DRV);
456 /* Remove the root device */
457 if (vmbus_drv_obj->Base.OnDeviceRemove)
458 vmbus_drv_obj->Base.OnDeviceRemove(&dev_ctx->device_obj);
460 if (vmbus_drv_obj->Base.OnCleanup)
461 vmbus_drv_obj->Base.OnCleanup(&vmbus_drv_obj->Base);
463 /* Unregister the root bus device */
464 device_unregister(&dev_ctx->device);
466 bus_unregister(&vmbus_drv_ctx->bus);
468 free_irq(vmbus_irq, NULL);
470 tasklet_kill(&vmbus_drv_ctx->msg_dpc);
471 tasklet_kill(&vmbus_drv_ctx->event_dpc);
473 DPRINT_EXIT(VMBUS_DRV);
480 Name: vmbus_child_driver_register()
482 Desc: Register a vmbus's child driver
485 int vmbus_child_driver_register(struct driver_context* driver_ctx)
487 struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
490 DPRINT_ENTER(VMBUS_DRV);
492 DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s", driver_ctx, driver_ctx->driver.name);
494 /* The child driver on this vmbus */
495 driver_ctx->driver.bus = &g_vmbus_drv.bus;
497 ret = driver_register(&driver_ctx->driver);
499 vmbus_drv_obj->GetChannelOffers();
501 DPRINT_EXIT(VMBUS_DRV);
506 EXPORT_SYMBOL(vmbus_child_driver_register);
510 Name: vmbus_child_driver_unregister()
512 Desc: Unregister a vmbus's child driver
515 void vmbus_child_driver_unregister(struct driver_context* driver_ctx)
517 DPRINT_ENTER(VMBUS_DRV);
519 DPRINT_INFO(VMBUS_DRV, "child driver (%p) unregistering - name %s", driver_ctx, driver_ctx->driver.name);
521 driver_unregister(&driver_ctx->driver);
523 driver_ctx->driver.bus = NULL;
525 DPRINT_EXIT(VMBUS_DRV);
528 EXPORT_SYMBOL(vmbus_child_driver_unregister);
532 Name: vmbus_get_interface()
534 Desc: Get the vmbus channel interface. This is invoked by child/client driver that sits
537 void vmbus_get_interface(struct vmbus_channel_interface *interface)
539 struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
541 vmbus_drv_obj->GetChannelInterface(interface);
544 EXPORT_SYMBOL(vmbus_get_interface);
549 Name: vmbus_child_device_get_info()
551 Desc: Get the vmbus child device info. This is invoked to display various device attributes in sysfs.
553 static void vmbus_child_device_get_info(struct hv_device *device_obj, struct hv_device_info *device_info)
555 struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
557 vmbus_drv_obj->GetChannelInfo(device_obj, device_info);
563 Name: vmbus_child_device_create()
565 Desc: Creates and registers a new child device on the vmbus.
568 static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
569 struct hv_guid *instance,
572 struct device_context *child_device_ctx;
573 struct hv_device *child_device_obj;
575 DPRINT_ENTER(VMBUS_DRV);
577 /* Allocate the new child device */
578 child_device_ctx = kzalloc(sizeof(struct device_context), GFP_KERNEL);
579 if (!child_device_ctx)
581 DPRINT_ERR(VMBUS_DRV, "unable to allocate device_context for child device");
582 DPRINT_EXIT(VMBUS_DRV);
587 DPRINT_DBG(VMBUS_DRV, "child device (%p) allocated - "
588 "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x},"
589 "id {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}",
590 &child_device_ctx->device,
591 type->data[3], type->data[2], type->data[1], type->data[0],
592 type->data[5], type->data[4], type->data[7], type->data[6],
593 type->data[8], type->data[9], type->data[10], type->data[11],
594 type->data[12], type->data[13], type->data[14], type->data[15],
595 instance->data[3], instance->data[2], instance->data[1], instance->data[0],
596 instance->data[5], instance->data[4], instance->data[7], instance->data[6],
597 instance->data[8], instance->data[9], instance->data[10], instance->data[11],
598 instance->data[12], instance->data[13], instance->data[14], instance->data[15]);
600 child_device_obj = &child_device_ctx->device_obj;
601 child_device_obj->context = context;
602 memcpy(&child_device_obj->deviceType, &type, sizeof(struct hv_guid));
603 memcpy(&child_device_obj->deviceInstance, &instance, sizeof(struct hv_guid));
605 memcpy(&child_device_ctx->class_id, &type, sizeof(struct hv_guid));
606 memcpy(&child_device_ctx->device_id, &instance, sizeof(struct hv_guid));
608 DPRINT_EXIT(VMBUS_DRV);
610 return child_device_obj;
615 Name: vmbus_child_device_register()
617 Desc: Register the child device on the specified bus
620 static int vmbus_child_device_register(struct hv_device *root_device_obj, struct hv_device *child_device_obj)
623 struct device_context *root_device_ctx = to_device_context(root_device_obj);
624 struct device_context *child_device_ctx = to_device_context(child_device_obj);
625 static atomic_t device_num = ATOMIC_INIT(0);
627 DPRINT_ENTER(VMBUS_DRV);
629 DPRINT_DBG(VMBUS_DRV, "child device (%p) registering", child_device_ctx);
631 /* Make sure we are not registered already */
633 if (strlen(dev_name(&child_device_ctx->device)) != 0)
635 DPRINT_ERR(VMBUS_DRV, "child device (%p) already registered - busid %s", child_device_ctx, dev_name(&child_device_ctx->device));
641 /* Set the device bus id. Otherwise, device_register()will fail. */
642 dev_set_name(&child_device_ctx->device, "vmbus_0_%d", atomic_inc_return(&device_num));
644 /* The new device belongs to this bus */
645 child_device_ctx->device.bus = &g_vmbus_drv.bus; /* device->dev.bus; */
646 child_device_ctx->device.parent = &root_device_ctx->device;
647 child_device_ctx->device.release = vmbus_device_release;
649 /* Register with the LDM. This will kick off the driver/device binding...which will */
650 /* eventually call vmbus_match() and vmbus_probe() */
651 ret = device_register(&child_device_ctx->device);
653 /* vmbus_probe() error does not get propergate to device_register(). */
654 ret = child_device_ctx->probe_error;
657 DPRINT_ERR(VMBUS_DRV, "unable to register child device (%p)", &child_device_ctx->device);
659 DPRINT_INFO(VMBUS_DRV, "child device (%p) registered", &child_device_ctx->device);
662 DPRINT_EXIT(VMBUS_DRV);
669 Name: vmbus_child_device_unregister()
671 Desc: Remove the specified child device from the vmbus.
674 static void vmbus_child_device_unregister(struct hv_device *device_obj)
676 struct device_context *device_ctx = to_device_context(device_obj);
678 DPRINT_ENTER(VMBUS_DRV);
680 DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)", &device_ctx->device);
682 /* Kick off the process of unregistering the device. */
683 /* This will call vmbus_remove() and eventually vmbus_device_release() */
684 device_unregister(&device_ctx->device);
686 DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered", &device_ctx->device);
688 DPRINT_EXIT(VMBUS_DRV);
694 Name: vmbus_child_device_destroy()
696 Desc: Destroy the specified child device on the vmbus.
699 static void vmbus_child_device_destroy(struct hv_device *device_obj)
701 DPRINT_ENTER(VMBUS_DRV);
703 DPRINT_EXIT(VMBUS_DRV);
710 Desc: This routine is invoked when a device is added or removed on the vmbus to generate a uevent to udev in the
711 userspace. The udev will then look at its rule and the uevent generated here to load the appropriate driver
714 static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
716 struct device_context *device_ctx = device_to_device_context(device);
721 DPRINT_ENTER(VMBUS_DRV);
723 DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}",
724 device_ctx->class_id.data[3], device_ctx->class_id.data[2],
725 device_ctx->class_id.data[1], device_ctx->class_id.data[0],
726 device_ctx->class_id.data[5], device_ctx->class_id.data[4],
727 device_ctx->class_id.data[7], device_ctx->class_id.data[6],
728 device_ctx->class_id.data[8], device_ctx->class_id.data[9],
729 device_ctx->class_id.data[10], device_ctx->class_id.data[11],
730 device_ctx->class_id.data[12], device_ctx->class_id.data[13],
731 device_ctx->class_id.data[14], device_ctx->class_id.data[15]);
735 ret = add_uevent_var(env,
736 "VMBUS_DEVICE_CLASS_GUID={%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}",
737 device_ctx->class_id.data[3], device_ctx->class_id.data[2],
738 device_ctx->class_id.data[1], device_ctx->class_id.data[0],
739 device_ctx->class_id.data[5], device_ctx->class_id.data[4],
740 device_ctx->class_id.data[7], device_ctx->class_id.data[6],
741 device_ctx->class_id.data[8], device_ctx->class_id.data[9],
742 device_ctx->class_id.data[10], device_ctx->class_id.data[11],
743 device_ctx->class_id.data[12], device_ctx->class_id.data[13],
744 device_ctx->class_id.data[14], device_ctx->class_id.data[15]);
751 ret = add_uevent_var(env,
752 "VMBUS_DEVICE_DEVICE_GUID={%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}",
753 device_ctx->device_id.data[3], device_ctx->device_id.data[2],
754 device_ctx->device_id.data[1], device_ctx->device_id.data[0],
755 device_ctx->device_id.data[5], device_ctx->device_id.data[4],
756 device_ctx->device_id.data[7], device_ctx->device_id.data[6],
757 device_ctx->device_id.data[8], device_ctx->device_id.data[9],
758 device_ctx->device_id.data[10], device_ctx->device_id.data[11],
759 device_ctx->device_id.data[12], device_ctx->device_id.data[13],
760 device_ctx->device_id.data[14], device_ctx->device_id.data[15]);
767 env->envp[env->envp_idx] = NULL;
769 DPRINT_EXIT(VMBUS_DRV);
778 Desc: Attempt to match the specified device to the specified driver
781 static int vmbus_match(struct device *device, struct device_driver *driver)
784 struct driver_context *driver_ctx = driver_to_driver_context(driver);
785 struct device_context *device_ctx = device_to_device_context(device);
787 DPRINT_ENTER(VMBUS_DRV);
789 /* We found our driver ? */
790 if (memcmp(&device_ctx->class_id, &driver_ctx->class_id, sizeof(struct hv_guid)) == 0)
792 /* !! NOTE: The driver_ctx is not a vmbus_drv_ctx. We typecast it here to access the */
793 /* struct hv_driver field */
794 struct vmbus_driver_context *vmbus_drv_ctx = (struct vmbus_driver_context*)driver_ctx;
795 device_ctx->device_obj.Driver = &vmbus_drv_ctx->drv_obj.Base;
796 DPRINT_INFO(VMBUS_DRV, "device object (%p) set to driver object (%p)", &device_ctx->device_obj, device_ctx->device_obj.Driver);
801 DPRINT_EXIT(VMBUS_DRV);
809 Name: vmbus_probe_failed_cb()
811 Desc: Callback when a driver probe failed in vmbus_probe(). We need a callback because
812 we cannot invoked device_unregister() inside vmbus_probe() since vmbus_probe() may be
813 invoked inside device_register() i.e. we cannot call device_unregister() inside
816 static void vmbus_probe_failed_cb(struct work_struct *context)
818 struct device_context *device_ctx = (struct device_context*)context;
821 DPRINT_ENTER(VMBUS_DRV);
823 /* Kick off the process of unregistering the device. */
824 /* This will call vmbus_remove() and eventually vmbus_device_release() */
825 device_unregister(&device_ctx->device);
827 /* put_device(&device_ctx->device); */
828 DPRINT_EXIT(VMBUS_DRV);
836 Desc: Add the new vmbus's child device
839 static int vmbus_probe(struct device *child_device)
842 struct driver_context *driver_ctx = driver_to_driver_context(child_device->driver);
843 struct device_context *device_ctx = device_to_device_context(child_device);
845 DPRINT_ENTER(VMBUS_DRV);
847 /* Let the specific open-source driver handles the probe if it can */
848 if (driver_ctx->probe)
850 ret = device_ctx->probe_error = driver_ctx->probe(child_device);
853 DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s (%p) on driver %s (%d)...", dev_name(child_device), child_device, child_device->driver->name, ret);
855 INIT_WORK(&device_ctx->probe_failed_work_item, vmbus_probe_failed_cb);
856 schedule_work(&device_ctx->probe_failed_work_item);
861 DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s", child_device->driver->name);
865 DPRINT_EXIT(VMBUS_DRV);
874 Desc: Remove a vmbus device
877 static int vmbus_remove(struct device *child_device)
880 struct driver_context *driver_ctx;
882 DPRINT_ENTER(VMBUS_DRV);
884 /* Special case root bus device */
885 if (child_device->parent == NULL)
887 /* No-op since it is statically defined and handle in vmbus_bus_exit() */
888 DPRINT_EXIT(VMBUS_DRV);
892 if (child_device->driver)
894 driver_ctx = driver_to_driver_context(child_device->driver);
896 /* Let the specific open-source driver handles the removal if it can */
897 if (driver_ctx->remove)
899 ret = driver_ctx->remove(child_device);
903 DPRINT_ERR(VMBUS_DRV, "remove() method not set for driver - %s", child_device->driver->name);
912 DPRINT_EXIT(VMBUS_DRV);
919 Name: vmbus_shutdown()
921 Desc: Shutdown a vmbus device
924 static void vmbus_shutdown(struct device *child_device)
926 struct driver_context *driver_ctx;
928 DPRINT_ENTER(VMBUS_DRV);
930 /* Special case root bus device */
931 if (child_device->parent == NULL)
933 /* No-op since it is statically defined and handle in vmbus_bus_exit() */
934 DPRINT_EXIT(VMBUS_DRV);
938 /* The device may not be attached yet */
939 if (!child_device->driver)
941 DPRINT_EXIT(VMBUS_DRV);
945 driver_ctx = driver_to_driver_context(child_device->driver);
947 /* Let the specific open-source driver handles the removal if it can */
948 if (driver_ctx->shutdown)
950 driver_ctx->shutdown(child_device);
953 DPRINT_EXIT(VMBUS_DRV);
960 Name: vmbus_bus_release()
962 Desc: Final callback release of the vmbus root device
965 static void vmbus_bus_release(struct device *device)
967 DPRINT_ENTER(VMBUS_DRV);
968 DPRINT_EXIT(VMBUS_DRV);
973 Name: vmbus_device_release()
975 Desc: Final callback release of the vmbus child device
978 static void vmbus_device_release(struct device *device)
980 struct device_context *device_ctx = device_to_device_context(device);
982 DPRINT_ENTER(VMBUS_DRV);
984 /* vmbus_child_device_destroy(&device_ctx->device_obj); */
987 /* !!DO NOT REFERENCE device_ctx anymore at this point!! */
989 DPRINT_EXIT(VMBUS_DRV);
996 Name: vmbus_msg_dpc()
998 Desc: Tasklet routine to handle hypervisor messages
1001 static void vmbus_msg_dpc(unsigned long data)
1003 struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data;
1005 DPRINT_ENTER(VMBUS_DRV);
1007 ASSERT(vmbus_drv_obj->OnMsgDpc != NULL);
1009 /* Call to bus driver to handle interrupt */
1010 vmbus_drv_obj->OnMsgDpc(&vmbus_drv_obj->Base);
1012 DPRINT_EXIT(VMBUS_DRV);
1017 Name: vmbus_msg_dpc()
1019 Desc: Tasklet routine to handle hypervisor events
1022 static void vmbus_event_dpc(unsigned long data)
1024 struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data;
1026 DPRINT_ENTER(VMBUS_DRV);
1028 ASSERT(vmbus_drv_obj->OnEventDpc != NULL);
1030 /* Call to bus driver to handle interrupt */
1031 vmbus_drv_obj->OnEventDpc(&vmbus_drv_obj->Base);
1033 DPRINT_EXIT(VMBUS_DRV);
1038 Name: vmbus_msg_dpc()
1043 static irqreturn_t vmbus_isr(int irq, void* dev_id)
1046 struct vmbus_driver *vmbus_driver_obj = &g_vmbus_drv.drv_obj;
1048 DPRINT_ENTER(VMBUS_DRV);
1050 ASSERT(vmbus_driver_obj->OnIsr != NULL);
1052 /* Call to bus driver to handle interrupt */
1053 ret = vmbus_driver_obj->OnIsr(&vmbus_driver_obj->Base);
1055 /* Schedules a dpc if necessary */
1058 if (test_bit(0, (unsigned long*)&ret))
1060 tasklet_schedule(&g_vmbus_drv.msg_dpc);
1063 if (test_bit(1, (unsigned long*)&ret))
1065 tasklet_schedule(&g_vmbus_drv.event_dpc);
1068 DPRINT_EXIT(VMBUS_DRV);
1073 DPRINT_EXIT(VMBUS_DRV);
1078 MODULE_LICENSE("GPL");
1085 Desc: Main vmbus driver entry routine
1088 static int __init vmbus_init(void)
1092 DPRINT_ENTER(VMBUS_DRV);
1094 DPRINT_INFO(VMBUS_DRV,
1095 "Vmbus initializing.... current log level 0x%x (%x,%x)",
1096 vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
1097 /* Todo: it is used for loglevel, to be ported to new kernel. */
1099 ret = vmbus_bus_init(VmbusInitialize);
1101 DPRINT_EXIT(VMBUS_DRV);
1111 Desc: Main vmbus driver exit routine
1114 static void __exit vmbus_exit(void)
1116 DPRINT_ENTER(VMBUS_DRV);
1119 /* Todo: it is used for loglevel, to be ported to new kernel. */
1120 DPRINT_EXIT(VMBUS_DRV);
1125 module_param(vmbus_irq, int, S_IRUGO);
1126 module_param(vmbus_loglevel, int, S_IRUGO);
1128 module_init(vmbus_init);
1129 module_exit(vmbus_exit);