]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/staging/hv/vmbus_drv.c
Merge branch 'ixp4xx' of git://git.kernel.org/pub/scm/linux/kernel/git/chris/linux-2.6
[net-next-2.6.git] / drivers / staging / hv / vmbus_drv.c
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  */
21 #include <linux/init.h>
22 #include <linux/module.h>
23 #include <linux/device.h>
24 #include <linux/irq.h>
25 #include <linux/interrupt.h>
26 #include <linux/sysctl.h>
27 #include <linux/pci.h>
28 #include <linux/dmi.h>
29 #include <linux/slab.h>
30 #include <linux/completion.h>
31 #include "version_info.h"
32 #include "osd.h"
33 #include "logging.h"
34 #include "vmbus.h"
35
36
37 /* FIXME! We need to do this dynamically for PIC and APIC system */
38 #define VMBUS_IRQ               0x5
39 #define VMBUS_IRQ_VECTOR        IRQ5_VECTOR
40
41 /* Main vmbus driver data structure */
42 struct vmbus_driver_context {
43         /* !! These must be the first 2 fields !! */
44         /* FIXME, this is a bug */
45         /* The driver field is not used in here. Instead, the bus field is */
46         /* used to represent the driver */
47         struct driver_context drv_ctx;
48         struct vmbus_driver drv_obj;
49
50         struct bus_type bus;
51         struct tasklet_struct msg_dpc;
52         struct tasklet_struct event_dpc;
53
54         /* The bus root device */
55         struct vm_device device_ctx;
56 };
57
58 static int vmbus_match(struct device *device, struct device_driver *driver);
59 static int vmbus_probe(struct device *device);
60 static int vmbus_remove(struct device *device);
61 static void vmbus_shutdown(struct device *device);
62 static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env);
63 static void vmbus_msg_dpc(unsigned long data);
64 static void vmbus_event_dpc(unsigned long data);
65
66 static irqreturn_t vmbus_isr(int irq, void *dev_id);
67
68 static void vmbus_device_release(struct device *device);
69 static void vmbus_bus_release(struct device *device);
70
71 static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
72                                                    struct hv_guid *instance,
73                                                    void *context);
74 static void vmbus_child_device_destroy(struct hv_device *device_obj);
75 static int vmbus_child_device_register(struct hv_device *root_device_obj,
76                                        struct hv_device *child_device_obj);
77 static void vmbus_child_device_unregister(struct hv_device *child_device_obj);
78 static void vmbus_child_device_get_info(struct hv_device *device_obj,
79                                         struct hv_device_info *device_info);
80 static ssize_t vmbus_show_device_attr(struct device *dev,
81                                       struct device_attribute *dev_attr,
82                                       char *buf);
83
84
85 unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL);
86 EXPORT_SYMBOL(vmbus_loglevel);
87         /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */
88         /* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */
89
90 static int vmbus_irq = VMBUS_IRQ;
91
92 /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
93 static struct device_attribute vmbus_device_attrs[] = {
94         __ATTR(id, S_IRUGO, vmbus_show_device_attr, NULL),
95         __ATTR(state, S_IRUGO, vmbus_show_device_attr, NULL),
96         __ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL),
97         __ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL),
98         __ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL),
99
100         __ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
101         __ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
102         __ATTR(server_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
103
104         __ATTR(client_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
105         __ATTR(client_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
106         __ATTR(client_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
107
108         __ATTR(out_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
109         __ATTR(out_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
110         __ATTR(out_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
111         __ATTR(out_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
112         __ATTR(out_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
113
114         __ATTR(in_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
115         __ATTR(in_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
116         __ATTR(in_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
117         __ATTR(in_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
118         __ATTR(in_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
119         __ATTR_NULL
120 };
121
122 /* The one and only one */
123 static struct vmbus_driver_context g_vmbus_drv = {
124         .bus.name =             "vmbus",
125         .bus.match =            vmbus_match,
126         .bus.shutdown =         vmbus_shutdown,
127         .bus.remove =           vmbus_remove,
128         .bus.probe =            vmbus_probe,
129         .bus.uevent =           vmbus_uevent,
130         .bus.dev_attrs =        vmbus_device_attrs,
131 };
132
133 /*
134  * vmbus_show_device_attr - Show the device attribute in sysfs.
135  *
136  * This is invoked when user does a
137  * "cat /sys/bus/vmbus/devices/<busdevice>/<attr name>"
138  */
139 static ssize_t vmbus_show_device_attr(struct device *dev,
140                                       struct device_attribute *dev_attr,
141                                       char *buf)
142 {
143         struct vm_device *device_ctx = device_to_vm_device(dev);
144         struct hv_device_info device_info;
145
146         memset(&device_info, 0, sizeof(struct hv_device_info));
147
148         vmbus_child_device_get_info(&device_ctx->device_obj, &device_info);
149
150         if (!strcmp(dev_attr->attr.name, "class_id")) {
151                 return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
152                                "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
153                                device_info.ChannelType.data[3],
154                                device_info.ChannelType.data[2],
155                                device_info.ChannelType.data[1],
156                                device_info.ChannelType.data[0],
157                                device_info.ChannelType.data[5],
158                                device_info.ChannelType.data[4],
159                                device_info.ChannelType.data[7],
160                                device_info.ChannelType.data[6],
161                                device_info.ChannelType.data[8],
162                                device_info.ChannelType.data[9],
163                                device_info.ChannelType.data[10],
164                                device_info.ChannelType.data[11],
165                                device_info.ChannelType.data[12],
166                                device_info.ChannelType.data[13],
167                                device_info.ChannelType.data[14],
168                                device_info.ChannelType.data[15]);
169         } else if (!strcmp(dev_attr->attr.name, "device_id")) {
170                 return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
171                                "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
172                                device_info.ChannelInstance.data[3],
173                                device_info.ChannelInstance.data[2],
174                                device_info.ChannelInstance.data[1],
175                                device_info.ChannelInstance.data[0],
176                                device_info.ChannelInstance.data[5],
177                                device_info.ChannelInstance.data[4],
178                                device_info.ChannelInstance.data[7],
179                                device_info.ChannelInstance.data[6],
180                                device_info.ChannelInstance.data[8],
181                                device_info.ChannelInstance.data[9],
182                                device_info.ChannelInstance.data[10],
183                                device_info.ChannelInstance.data[11],
184                                device_info.ChannelInstance.data[12],
185                                device_info.ChannelInstance.data[13],
186                                device_info.ChannelInstance.data[14],
187                                device_info.ChannelInstance.data[15]);
188         } else if (!strcmp(dev_attr->attr.name, "state")) {
189                 return sprintf(buf, "%d\n", device_info.ChannelState);
190         } else if (!strcmp(dev_attr->attr.name, "id")) {
191                 return sprintf(buf, "%d\n", device_info.ChannelId);
192         } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
193                 return sprintf(buf, "%d\n", device_info.Outbound.InterruptMask);
194         } else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
195                 return sprintf(buf, "%d\n", device_info.Outbound.ReadIndex);
196         } else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
197                 return sprintf(buf, "%d\n", device_info.Outbound.WriteIndex);
198         } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
199                 return sprintf(buf, "%d\n",
200                                device_info.Outbound.BytesAvailToRead);
201         } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
202                 return sprintf(buf, "%d\n",
203                                device_info.Outbound.BytesAvailToWrite);
204         } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
205                 return sprintf(buf, "%d\n", device_info.Inbound.InterruptMask);
206         } else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
207                 return sprintf(buf, "%d\n", device_info.Inbound.ReadIndex);
208         } else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
209                 return sprintf(buf, "%d\n", device_info.Inbound.WriteIndex);
210         } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
211                 return sprintf(buf, "%d\n",
212                                device_info.Inbound.BytesAvailToRead);
213         } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
214                 return sprintf(buf, "%d\n",
215                                device_info.Inbound.BytesAvailToWrite);
216         } else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
217                 return sprintf(buf, "%d\n", device_info.MonitorId);
218         } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
219                 return sprintf(buf, "%d\n", device_info.ServerMonitorPending);
220         } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
221                 return sprintf(buf, "%d\n", device_info.ServerMonitorLatency);
222         } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
223                 return sprintf(buf, "%d\n",
224                                device_info.ServerMonitorConnectionId);
225         } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
226                 return sprintf(buf, "%d\n", device_info.ClientMonitorPending);
227         } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
228                 return sprintf(buf, "%d\n", device_info.ClientMonitorLatency);
229         } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
230                 return sprintf(buf, "%d\n",
231                                device_info.ClientMonitorConnectionId);
232         } else {
233                 return 0;
234         }
235 }
236
237 /*
238  * vmbus_bus_init -Main vmbus driver initialization routine.
239  *
240  * Here, we
241  *      - initialize the vmbus driver context
242  *      - setup various driver entry points
243  *      - invoke the vmbus hv main init routine
244  *      - get the irq resource
245  *      - invoke the vmbus to add the vmbus root device
246  *      - setup the vmbus root device
247  *      - retrieve the channel offers
248  */
249 static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv))
250 {
251         struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
252         struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
253         struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx;
254         int ret;
255         unsigned int vector;
256
257         /*
258          * Set this up to allow lower layer to callback to add/remove child
259          * devices on the bus
260          */
261         vmbus_drv_obj->OnChildDeviceCreate = vmbus_child_device_create;
262         vmbus_drv_obj->OnChildDeviceDestroy = vmbus_child_device_destroy;
263         vmbus_drv_obj->OnChildDeviceAdd = vmbus_child_device_register;
264         vmbus_drv_obj->OnChildDeviceRemove = vmbus_child_device_unregister;
265
266         /* Call to bus driver to initialize */
267         ret = drv_init(&vmbus_drv_obj->Base);
268         if (ret != 0) {
269                 DPRINT_ERR(VMBUS_DRV, "Unable to initialize vmbus (%d)", ret);
270                 goto cleanup;
271         }
272
273         /* Sanity checks */
274         if (!vmbus_drv_obj->Base.OnDeviceAdd) {
275                 DPRINT_ERR(VMBUS_DRV, "OnDeviceAdd() routine not set");
276                 ret = -1;
277                 goto cleanup;
278         }
279
280         vmbus_drv_ctx->bus.name = vmbus_drv_obj->Base.name;
281
282         /* Initialize the bus context */
283         tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_msg_dpc,
284                      (unsigned long)vmbus_drv_obj);
285         tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc,
286                      (unsigned long)vmbus_drv_obj);
287
288         /* Now, register the bus driver with LDM */
289         ret = bus_register(&vmbus_drv_ctx->bus);
290         if (ret) {
291                 ret = -1;
292                 goto cleanup;
293         }
294
295         /* Get the interrupt resource */
296         ret = request_irq(vmbus_irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
297                           vmbus_drv_obj->Base.name, NULL);
298
299         if (ret != 0) {
300                 DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d",
301                            vmbus_irq);
302
303                 bus_unregister(&vmbus_drv_ctx->bus);
304
305                 ret = -1;
306                 goto cleanup;
307         }
308         vector = VMBUS_IRQ_VECTOR;
309
310         DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector);
311
312         /* Call to bus driver to add the root device */
313         memset(dev_ctx, 0, sizeof(struct vm_device));
314
315         ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector);
316         if (ret != 0) {
317                 DPRINT_ERR(VMBUS_DRV,
318                            "ERROR - Unable to add vmbus root device");
319
320                 free_irq(vmbus_irq, NULL);
321
322                 bus_unregister(&vmbus_drv_ctx->bus);
323
324                 ret = -1;
325                 goto cleanup;
326         }
327         /* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */
328         dev_set_name(&dev_ctx->device, "vmbus_0_0");
329         memcpy(&dev_ctx->class_id, &dev_ctx->device_obj.deviceType,
330                 sizeof(struct hv_guid));
331         memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.deviceInstance,
332                 sizeof(struct hv_guid));
333
334         /* No need to bind a driver to the root device. */
335         dev_ctx->device.parent = NULL;
336         /* NULL; vmbus_remove() does not get invoked */
337         dev_ctx->device.bus = &vmbus_drv_ctx->bus;
338
339         /* Setup the device dispatch table */
340         dev_ctx->device.release = vmbus_bus_release;
341
342         /* Setup the bus as root device */
343         ret = device_register(&dev_ctx->device);
344         if (ret) {
345                 DPRINT_ERR(VMBUS_DRV,
346                            "ERROR - Unable to register vmbus root device");
347
348                 free_irq(vmbus_irq, NULL);
349                 bus_unregister(&vmbus_drv_ctx->bus);
350
351                 ret = -1;
352                 goto cleanup;
353         }
354
355
356         vmbus_drv_obj->GetChannelOffers();
357
358         wait_for_completion(&hv_channel_ready);
359
360 cleanup:
361         return ret;
362 }
363
364 /*
365  * vmbus_bus_exit - Terminate the vmbus driver.
366  *
367  * This routine is opposite of vmbus_bus_init()
368  */
369 static void vmbus_bus_exit(void)
370 {
371         struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
372         struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
373
374         struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx;
375
376         /* Remove the root device */
377         if (vmbus_drv_obj->Base.OnDeviceRemove)
378                 vmbus_drv_obj->Base.OnDeviceRemove(&dev_ctx->device_obj);
379
380         if (vmbus_drv_obj->Base.OnCleanup)
381                 vmbus_drv_obj->Base.OnCleanup(&vmbus_drv_obj->Base);
382
383         /* Unregister the root bus device */
384         device_unregister(&dev_ctx->device);
385
386         bus_unregister(&vmbus_drv_ctx->bus);
387
388         free_irq(vmbus_irq, NULL);
389
390         tasklet_kill(&vmbus_drv_ctx->msg_dpc);
391         tasklet_kill(&vmbus_drv_ctx->event_dpc);
392 }
393
394
395 /**
396  * vmbus_child_driver_register() - Register a vmbus's child driver
397  * @driver_ctx:        Pointer to driver structure you want to register
398  *
399  * @driver_ctx is of type &struct driver_context
400  *
401  * Registers the given driver with Linux through the 'driver_register()' call
402  * And sets up the hyper-v vmbus handling for this driver.
403  * It will return the state of the 'driver_register()' call.
404  *
405  * Mainly used by Hyper-V drivers.
406  */
407 int vmbus_child_driver_register(struct driver_context *driver_ctx)
408 {
409         struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
410         int ret;
411
412         DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s",
413                     driver_ctx, driver_ctx->driver.name);
414
415         /* The child driver on this vmbus */
416         driver_ctx->driver.bus = &g_vmbus_drv.bus;
417
418         ret = driver_register(&driver_ctx->driver);
419
420         vmbus_drv_obj->GetChannelOffers();
421
422         return ret;
423 }
424 EXPORT_SYMBOL(vmbus_child_driver_register);
425
426 /**
427  * vmbus_child_driver_unregister() - Unregister a vmbus's child driver
428  * @driver_ctx:        Pointer to driver structure you want to un-register
429  *
430  * @driver_ctx is of type &struct driver_context
431  *
432  * Un-register the given driver with Linux through the 'driver_unregister()'
433  * call. And ungegisters the driver from the Hyper-V vmbus handler.
434  *
435  * Mainly used by Hyper-V drivers.
436  */
437 void vmbus_child_driver_unregister(struct driver_context *driver_ctx)
438 {
439         DPRINT_INFO(VMBUS_DRV, "child driver (%p) unregistering - name %s",
440                     driver_ctx, driver_ctx->driver.name);
441
442         driver_unregister(&driver_ctx->driver);
443
444         driver_ctx->driver.bus = NULL;
445 }
446 EXPORT_SYMBOL(vmbus_child_driver_unregister);
447
448 /**
449  * vmbus_get_interface() - Get the vmbus channel interface.
450  * @interface: Pointer to channel interface structure
451  *
452  * Get the Hyper-V channel used for the driver.
453  *
454  * @interface is of type &struct vmbus_channel_interface
455  * This is invoked by child/client driver that sits above vmbus.
456  *
457  * Mainly used by Hyper-V drivers.
458  */
459 void vmbus_get_interface(struct vmbus_channel_interface *interface)
460 {
461         struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
462
463         vmbus_drv_obj->GetChannelInterface(interface);
464 }
465 EXPORT_SYMBOL(vmbus_get_interface);
466
467 /*
468  * vmbus_child_device_get_info - Get the vmbus child device info.
469  *
470  * This is invoked to display various device attributes in sysfs.
471  */
472 static void vmbus_child_device_get_info(struct hv_device *device_obj,
473                                         struct hv_device_info *device_info)
474 {
475         struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
476
477         vmbus_drv_obj->GetChannelInfo(device_obj, device_info);
478 }
479
480 /*
481  * vmbus_child_device_create - Creates and registers a new child device
482  * on the vmbus.
483  */
484 static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
485                                                    struct hv_guid *instance,
486                                                    void *context)
487 {
488         struct vm_device *child_device_ctx;
489         struct hv_device *child_device_obj;
490
491         /* Allocate the new child device */
492         child_device_ctx = kzalloc(sizeof(struct vm_device), GFP_KERNEL);
493         if (!child_device_ctx) {
494                 DPRINT_ERR(VMBUS_DRV,
495                         "unable to allocate device_context for child device");
496                 return NULL;
497         }
498
499         DPRINT_DBG(VMBUS_DRV, "child device (%p) allocated - "
500                 "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
501                 "%02x%02x%02x%02x%02x%02x%02x%02x},"
502                 "id {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
503                 "%02x%02x%02x%02x%02x%02x%02x%02x}",
504                 &child_device_ctx->device,
505                 type->data[3], type->data[2], type->data[1], type->data[0],
506                 type->data[5], type->data[4], type->data[7], type->data[6],
507                 type->data[8], type->data[9], type->data[10], type->data[11],
508                 type->data[12], type->data[13], type->data[14], type->data[15],
509                 instance->data[3], instance->data[2],
510                 instance->data[1], instance->data[0],
511                 instance->data[5], instance->data[4],
512                 instance->data[7], instance->data[6],
513                 instance->data[8], instance->data[9],
514                 instance->data[10], instance->data[11],
515                 instance->data[12], instance->data[13],
516                 instance->data[14], instance->data[15]);
517
518         child_device_obj = &child_device_ctx->device_obj;
519         child_device_obj->context = context;
520         memcpy(&child_device_obj->deviceType, type, sizeof(struct hv_guid));
521         memcpy(&child_device_obj->deviceInstance, instance,
522                sizeof(struct hv_guid));
523
524         memcpy(&child_device_ctx->class_id, type, sizeof(struct hv_guid));
525         memcpy(&child_device_ctx->device_id, instance, sizeof(struct hv_guid));
526
527         return child_device_obj;
528 }
529
530 /*
531  * vmbus_child_device_register - Register the child device on the specified bus
532  */
533 static int vmbus_child_device_register(struct hv_device *root_device_obj,
534                                        struct hv_device *child_device_obj)
535 {
536         int ret = 0;
537         struct vm_device *root_device_ctx =
538                                 to_vm_device(root_device_obj);
539         struct vm_device *child_device_ctx =
540                                 to_vm_device(child_device_obj);
541         static atomic_t device_num = ATOMIC_INIT(0);
542
543         DPRINT_DBG(VMBUS_DRV, "child device (%p) registering",
544                    child_device_ctx);
545
546         /* Set the device name. Otherwise, device_register() will fail. */
547         dev_set_name(&child_device_ctx->device, "vmbus_0_%d",
548                      atomic_inc_return(&device_num));
549
550         /* The new device belongs to this bus */
551         child_device_ctx->device.bus = &g_vmbus_drv.bus; /* device->dev.bus; */
552         child_device_ctx->device.parent = &root_device_ctx->device;
553         child_device_ctx->device.release = vmbus_device_release;
554
555         /*
556          * Register with the LDM. This will kick off the driver/device
557          * binding...which will eventually call vmbus_match() and vmbus_probe()
558          */
559         ret = device_register(&child_device_ctx->device);
560
561         /* vmbus_probe() error does not get propergate to device_register(). */
562         ret = child_device_ctx->probe_error;
563
564         if (ret)
565                 DPRINT_ERR(VMBUS_DRV, "unable to register child device (%p)",
566                            &child_device_ctx->device);
567         else
568                 DPRINT_INFO(VMBUS_DRV, "child device (%p) registered",
569                             &child_device_ctx->device);
570
571         return ret;
572 }
573
574 /*
575  * vmbus_child_device_unregister - Remove the specified child device
576  * from the vmbus.
577  */
578 static void vmbus_child_device_unregister(struct hv_device *device_obj)
579 {
580         struct vm_device *device_ctx = to_vm_device(device_obj);
581
582         DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)",
583                     &device_ctx->device);
584
585         /*
586          * Kick off the process of unregistering the device.
587          * This will call vmbus_remove() and eventually vmbus_device_release()
588          */
589         device_unregister(&device_ctx->device);
590
591         DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered",
592                     &device_ctx->device);
593 }
594
595 /*
596  * vmbus_child_device_destroy - Destroy the specified child device on the vmbus.
597  */
598 static void vmbus_child_device_destroy(struct hv_device *device_obj)
599 {
600 }
601
602 /*
603  * vmbus_uevent - add uevent for our device
604  *
605  * This routine is invoked when a device is added or removed on the vmbus to
606  * generate a uevent to udev in the userspace. The udev will then look at its
607  * rule and the uevent generated here to load the appropriate driver
608  */
609 static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
610 {
611         struct vm_device *device_ctx = device_to_vm_device(device);
612         int ret;
613
614         DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={"
615                     "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
616                     "%02x%02x%02x%02x%02x%02x%02x%02x}",
617                     device_ctx->class_id.data[3], device_ctx->class_id.data[2],
618                     device_ctx->class_id.data[1], device_ctx->class_id.data[0],
619                     device_ctx->class_id.data[5], device_ctx->class_id.data[4],
620                     device_ctx->class_id.data[7], device_ctx->class_id.data[6],
621                     device_ctx->class_id.data[8], device_ctx->class_id.data[9],
622                     device_ctx->class_id.data[10],
623                     device_ctx->class_id.data[11],
624                     device_ctx->class_id.data[12],
625                     device_ctx->class_id.data[13],
626                     device_ctx->class_id.data[14],
627                     device_ctx->class_id.data[15]);
628
629         ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={"
630                              "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
631                              "%02x%02x%02x%02x%02x%02x%02x%02x}",
632                              device_ctx->class_id.data[3],
633                              device_ctx->class_id.data[2],
634                              device_ctx->class_id.data[1],
635                              device_ctx->class_id.data[0],
636                              device_ctx->class_id.data[5],
637                              device_ctx->class_id.data[4],
638                              device_ctx->class_id.data[7],
639                              device_ctx->class_id.data[6],
640                              device_ctx->class_id.data[8],
641                              device_ctx->class_id.data[9],
642                              device_ctx->class_id.data[10],
643                              device_ctx->class_id.data[11],
644                              device_ctx->class_id.data[12],
645                              device_ctx->class_id.data[13],
646                              device_ctx->class_id.data[14],
647                              device_ctx->class_id.data[15]);
648
649         if (ret)
650                 return ret;
651
652         ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={"
653                              "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
654                              "%02x%02x%02x%02x%02x%02x%02x%02x}",
655                              device_ctx->device_id.data[3],
656                              device_ctx->device_id.data[2],
657                              device_ctx->device_id.data[1],
658                              device_ctx->device_id.data[0],
659                              device_ctx->device_id.data[5],
660                              device_ctx->device_id.data[4],
661                              device_ctx->device_id.data[7],
662                              device_ctx->device_id.data[6],
663                              device_ctx->device_id.data[8],
664                              device_ctx->device_id.data[9],
665                              device_ctx->device_id.data[10],
666                              device_ctx->device_id.data[11],
667                              device_ctx->device_id.data[12],
668                              device_ctx->device_id.data[13],
669                              device_ctx->device_id.data[14],
670                              device_ctx->device_id.data[15]);
671         if (ret)
672                 return ret;
673
674         return 0;
675 }
676
677 /*
678  * vmbus_match - Attempt to match the specified device to the specified driver
679  */
680 static int vmbus_match(struct device *device, struct device_driver *driver)
681 {
682         int match = 0;
683         struct driver_context *driver_ctx = driver_to_driver_context(driver);
684         struct vm_device *device_ctx = device_to_vm_device(device);
685
686         /* We found our driver ? */
687         if (memcmp(&device_ctx->class_id, &driver_ctx->class_id,
688                    sizeof(struct hv_guid)) == 0) {
689                 /*
690                  * !! NOTE: The driver_ctx is not a vmbus_drv_ctx. We typecast
691                  * it here to access the struct hv_driver field
692                  */
693                 struct vmbus_driver_context *vmbus_drv_ctx =
694                         (struct vmbus_driver_context *)driver_ctx;
695
696                 device_ctx->device_obj.Driver = &vmbus_drv_ctx->drv_obj.Base;
697                 DPRINT_INFO(VMBUS_DRV,
698                             "device object (%p) set to driver object (%p)",
699                             &device_ctx->device_obj,
700                             device_ctx->device_obj.Driver);
701
702                 match = 1;
703         }
704         return match;
705 }
706
707 /*
708  * vmbus_probe_failed_cb - Callback when a driver probe failed in vmbus_probe()
709  *
710  * We need a callback because we cannot invoked device_unregister() inside
711  * vmbus_probe() since vmbus_probe() may be invoked inside device_register()
712  * i.e. we cannot call device_unregister() inside device_register()
713  */
714 static void vmbus_probe_failed_cb(struct work_struct *context)
715 {
716         struct vm_device *device_ctx = (struct vm_device *)context;
717
718         /*
719          * Kick off the process of unregistering the device.
720          * This will call vmbus_remove() and eventually vmbus_device_release()
721          */
722         device_unregister(&device_ctx->device);
723
724         /* put_device(&device_ctx->device); */
725 }
726
727 /*
728  * vmbus_probe - Add the new vmbus's child device
729  */
730 static int vmbus_probe(struct device *child_device)
731 {
732         int ret = 0;
733         struct driver_context *driver_ctx =
734                         driver_to_driver_context(child_device->driver);
735         struct vm_device *device_ctx =
736                         device_to_vm_device(child_device);
737
738         /* Let the specific open-source driver handles the probe if it can */
739         if (driver_ctx->probe) {
740                 ret = device_ctx->probe_error = driver_ctx->probe(child_device);
741                 if (ret != 0) {
742                         DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s "
743                                    "(%p) on driver %s (%d)...",
744                                    dev_name(child_device), child_device,
745                                    child_device->driver->name, ret);
746
747                         INIT_WORK(&device_ctx->probe_failed_work_item,
748                                   vmbus_probe_failed_cb);
749                         schedule_work(&device_ctx->probe_failed_work_item);
750                 }
751         } else {
752                 DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s",
753                            child_device->driver->name);
754                 ret = -1;
755         }
756         return ret;
757 }
758
759 /*
760  * vmbus_remove - Remove a vmbus device
761  */
762 static int vmbus_remove(struct device *child_device)
763 {
764         int ret;
765         struct driver_context *driver_ctx;
766
767         /* Special case root bus device */
768         if (child_device->parent == NULL) {
769                 /*
770                  * No-op since it is statically defined and handle in
771                  * vmbus_bus_exit()
772                  */
773                 return 0;
774         }
775
776         if (child_device->driver) {
777                 driver_ctx = driver_to_driver_context(child_device->driver);
778
779                 /*
780                  * Let the specific open-source driver handles the removal if
781                  * it can
782                  */
783                 if (driver_ctx->remove) {
784                         ret = driver_ctx->remove(child_device);
785                 } else {
786                         DPRINT_ERR(VMBUS_DRV,
787                                    "remove() method not set for driver - %s",
788                                    child_device->driver->name);
789                         ret = -1;
790                 }
791         }
792
793         return 0;
794 }
795
796 /*
797  * vmbus_shutdown - Shutdown a vmbus device
798  */
799 static void vmbus_shutdown(struct device *child_device)
800 {
801         struct driver_context *driver_ctx;
802
803         /* Special case root bus device */
804         if (child_device->parent == NULL) {
805                 /*
806                  * No-op since it is statically defined and handle in
807                  * vmbus_bus_exit()
808                  */
809                 return;
810         }
811
812         /* The device may not be attached yet */
813         if (!child_device->driver)
814                 return;
815
816         driver_ctx = driver_to_driver_context(child_device->driver);
817
818         /* Let the specific open-source driver handles the removal if it can */
819         if (driver_ctx->shutdown)
820                 driver_ctx->shutdown(child_device);
821
822         return;
823 }
824
825 /*
826  * vmbus_bus_release - Final callback release of the vmbus root device
827  */
828 static void vmbus_bus_release(struct device *device)
829 {
830         /* FIXME */
831         /* Empty release functions are a bug, or a major sign
832          * of a problem design, this MUST BE FIXED! */
833         dev_err(device, "%s needs to be fixed!\n", __func__);
834         WARN_ON(1);
835 }
836
837 /*
838  * vmbus_device_release - Final callback release of the vmbus child device
839  */
840 static void vmbus_device_release(struct device *device)
841 {
842         struct vm_device *device_ctx = device_to_vm_device(device);
843
844         /* vmbus_child_device_destroy(&device_ctx->device_obj); */
845         kfree(device_ctx);
846
847         /* !!DO NOT REFERENCE device_ctx anymore at this point!! */
848 }
849
850 /*
851  * vmbus_msg_dpc - Tasklet routine to handle hypervisor messages
852  */
853 static void vmbus_msg_dpc(unsigned long data)
854 {
855         struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data;
856
857         /* ASSERT(vmbus_drv_obj->OnMsgDpc != NULL); */
858
859         /* Call to bus driver to handle interrupt */
860         vmbus_drv_obj->OnMsgDpc(&vmbus_drv_obj->Base);
861 }
862
863 /*
864  * vmbus_msg_dpc - Tasklet routine to handle hypervisor events
865  */
866 static void vmbus_event_dpc(unsigned long data)
867 {
868         struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data;
869
870         /* ASSERT(vmbus_drv_obj->OnEventDpc != NULL); */
871
872         /* Call to bus driver to handle interrupt */
873         vmbus_drv_obj->OnEventDpc(&vmbus_drv_obj->Base);
874 }
875
876 static irqreturn_t vmbus_isr(int irq, void *dev_id)
877 {
878         struct vmbus_driver *vmbus_driver_obj = &g_vmbus_drv.drv_obj;
879         int ret;
880
881         /* ASSERT(vmbus_driver_obj->OnIsr != NULL); */
882
883         /* Call to bus driver to handle interrupt */
884         ret = vmbus_driver_obj->OnIsr(&vmbus_driver_obj->Base);
885
886         /* Schedules a dpc if necessary */
887         if (ret > 0) {
888                 if (test_bit(0, (unsigned long *)&ret))
889                         tasklet_schedule(&g_vmbus_drv.msg_dpc);
890
891                 if (test_bit(1, (unsigned long *)&ret))
892                         tasklet_schedule(&g_vmbus_drv.event_dpc);
893
894                 return IRQ_HANDLED;
895         } else {
896                 return IRQ_NONE;
897         }
898 }
899
900 static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = {
901         {
902                 .ident = "Hyper-V",
903                 .matches = {
904                         DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
905                         DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
906                         DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
907                 },
908         },
909         { },
910 };
911 MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table);
912
913 static int __init vmbus_init(void)
914 {
915         DPRINT_INFO(VMBUS_DRV,
916                 "Vmbus initializing.... current log level 0x%x (%x,%x)",
917                 vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
918         /* Todo: it is used for loglevel, to be ported to new kernel. */
919
920         if (!dmi_check_system(microsoft_hv_dmi_table))
921                 return -ENODEV;
922
923         return vmbus_bus_init(VmbusInitialize);
924 }
925
926 static void __exit vmbus_exit(void)
927 {
928         vmbus_bus_exit();
929         /* Todo: it is used for loglevel, to be ported to new kernel. */
930 }
931
932 /*
933  * We use a PCI table to determine if we should autoload this driver  This is
934  * needed by distro tools to determine if the hyperv drivers should be
935  * installed and/or configured.  We don't do anything else with the table, but
936  * it needs to be present.
937  */
938 static const struct pci_device_id microsoft_hv_pci_table[] = {
939         { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
940         { 0 }
941 };
942 MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
943
944 MODULE_LICENSE("GPL");
945 MODULE_VERSION(HV_DRV_VERSION);
946 module_param(vmbus_irq, int, S_IRUGO);
947 module_param(vmbus_loglevel, int, S_IRUGO);
948
949 module_init(vmbus_init);
950 module_exit(vmbus_exit);