Merge branches 'slab/fixes', 'slob/fixes', 'slub/cleanups' and 'slub/fixes' into...
[sfrench/cifs-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         DPRINT_ENTER(VMBUS_DRV);
258
259         /*
260          * Set this up to allow lower layer to callback to add/remove child
261          * devices on the bus
262          */
263         vmbus_drv_obj->OnChildDeviceCreate = vmbus_child_device_create;
264         vmbus_drv_obj->OnChildDeviceDestroy = vmbus_child_device_destroy;
265         vmbus_drv_obj->OnChildDeviceAdd = vmbus_child_device_register;
266         vmbus_drv_obj->OnChildDeviceRemove = vmbus_child_device_unregister;
267
268         /* Call to bus driver to initialize */
269         ret = drv_init(&vmbus_drv_obj->Base);
270         if (ret != 0) {
271                 DPRINT_ERR(VMBUS_DRV, "Unable to initialize vmbus (%d)", ret);
272                 goto cleanup;
273         }
274
275         /* Sanity checks */
276         if (!vmbus_drv_obj->Base.OnDeviceAdd) {
277                 DPRINT_ERR(VMBUS_DRV, "OnDeviceAdd() routine not set");
278                 ret = -1;
279                 goto cleanup;
280         }
281
282         vmbus_drv_ctx->bus.name = vmbus_drv_obj->Base.name;
283
284         /* Initialize the bus context */
285         tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_msg_dpc,
286                      (unsigned long)vmbus_drv_obj);
287         tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc,
288                      (unsigned long)vmbus_drv_obj);
289
290         /* Now, register the bus driver with LDM */
291         ret = bus_register(&vmbus_drv_ctx->bus);
292         if (ret) {
293                 ret = -1;
294                 goto cleanup;
295         }
296
297         /* Get the interrupt resource */
298         ret = request_irq(vmbus_irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
299                           vmbus_drv_obj->Base.name, NULL);
300
301         if (ret != 0) {
302                 DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d",
303                            vmbus_irq);
304
305                 bus_unregister(&vmbus_drv_ctx->bus);
306
307                 ret = -1;
308                 goto cleanup;
309         }
310         vector = VMBUS_IRQ_VECTOR;
311
312         DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector);
313
314         /* Call to bus driver to add the root device */
315         memset(dev_ctx, 0, sizeof(struct vm_device));
316
317         ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector);
318         if (ret != 0) {
319                 DPRINT_ERR(VMBUS_DRV,
320                            "ERROR - Unable to add vmbus root device");
321
322                 free_irq(vmbus_irq, NULL);
323
324                 bus_unregister(&vmbus_drv_ctx->bus);
325
326                 ret = -1;
327                 goto cleanup;
328         }
329         /* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */
330         dev_set_name(&dev_ctx->device, "vmbus_0_0");
331         memcpy(&dev_ctx->class_id, &dev_ctx->device_obj.deviceType,
332                 sizeof(struct hv_guid));
333         memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.deviceInstance,
334                 sizeof(struct hv_guid));
335
336         /* No need to bind a driver to the root device. */
337         dev_ctx->device.parent = NULL;
338         /* NULL; vmbus_remove() does not get invoked */
339         dev_ctx->device.bus = &vmbus_drv_ctx->bus;
340
341         /* Setup the device dispatch table */
342         dev_ctx->device.release = vmbus_bus_release;
343
344         /* Setup the bus as root device */
345         ret = device_register(&dev_ctx->device);
346         if (ret) {
347                 DPRINT_ERR(VMBUS_DRV,
348                            "ERROR - Unable to register vmbus root device");
349
350                 free_irq(vmbus_irq, NULL);
351                 bus_unregister(&vmbus_drv_ctx->bus);
352
353                 ret = -1;
354                 goto cleanup;
355         }
356
357
358         vmbus_drv_obj->GetChannelOffers();
359
360         wait_for_completion(&hv_channel_ready);
361
362 cleanup:
363         DPRINT_EXIT(VMBUS_DRV);
364
365         return ret;
366 }
367
368 /*
369  * vmbus_bus_exit - Terminate the vmbus driver.
370  *
371  * This routine is opposite of vmbus_bus_init()
372  */
373 static void vmbus_bus_exit(void)
374 {
375         struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
376         struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
377
378         struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx;
379
380         DPRINT_ENTER(VMBUS_DRV);
381
382         /* Remove the root device */
383         if (vmbus_drv_obj->Base.OnDeviceRemove)
384                 vmbus_drv_obj->Base.OnDeviceRemove(&dev_ctx->device_obj);
385
386         if (vmbus_drv_obj->Base.OnCleanup)
387                 vmbus_drv_obj->Base.OnCleanup(&vmbus_drv_obj->Base);
388
389         /* Unregister the root bus device */
390         device_unregister(&dev_ctx->device);
391
392         bus_unregister(&vmbus_drv_ctx->bus);
393
394         free_irq(vmbus_irq, NULL);
395
396         tasklet_kill(&vmbus_drv_ctx->msg_dpc);
397         tasklet_kill(&vmbus_drv_ctx->event_dpc);
398
399         DPRINT_EXIT(VMBUS_DRV);
400
401         return;
402 }
403
404
405 /**
406  * vmbus_child_driver_register() - Register a vmbus's child driver
407  * @driver_ctx:        Pointer to driver structure you want to register
408  *
409  * @driver_ctx is of type &struct driver_context
410  *
411  * Registers the given driver with Linux through the 'driver_register()' call
412  * And sets up the hyper-v vmbus handling for this driver.
413  * It will return the state of the 'driver_register()' call.
414  *
415  * Mainly used by Hyper-V drivers.
416  */
417 int vmbus_child_driver_register(struct driver_context *driver_ctx)
418 {
419         struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
420         int ret;
421
422         DPRINT_ENTER(VMBUS_DRV);
423
424         DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s",
425                     driver_ctx, driver_ctx->driver.name);
426
427         /* The child driver on this vmbus */
428         driver_ctx->driver.bus = &g_vmbus_drv.bus;
429
430         ret = driver_register(&driver_ctx->driver);
431
432         vmbus_drv_obj->GetChannelOffers();
433
434         DPRINT_EXIT(VMBUS_DRV);
435
436         return ret;
437 }
438 EXPORT_SYMBOL(vmbus_child_driver_register);
439
440 /**
441  * vmbus_child_driver_unregister() - Unregister a vmbus's child driver
442  * @driver_ctx:        Pointer to driver structure you want to un-register
443  *
444  * @driver_ctx is of type &struct driver_context
445  *
446  * Un-register the given driver with Linux through the 'driver_unregister()'
447  * call. And ungegisters the driver from the Hyper-V vmbus handler.
448  *
449  * Mainly used by Hyper-V drivers.
450  */
451 void vmbus_child_driver_unregister(struct driver_context *driver_ctx)
452 {
453         DPRINT_ENTER(VMBUS_DRV);
454
455         DPRINT_INFO(VMBUS_DRV, "child driver (%p) unregistering - name %s",
456                     driver_ctx, driver_ctx->driver.name);
457
458         driver_unregister(&driver_ctx->driver);
459
460         driver_ctx->driver.bus = NULL;
461
462         DPRINT_EXIT(VMBUS_DRV);
463 }
464 EXPORT_SYMBOL(vmbus_child_driver_unregister);
465
466 /**
467  * vmbus_get_interface() - Get the vmbus channel interface.
468  * @interface: Pointer to channel interface structure
469  *
470  * Get the Hyper-V channel used for the driver.
471  *
472  * @interface is of type &struct vmbus_channel_interface
473  * This is invoked by child/client driver that sits above vmbus.
474  *
475  * Mainly used by Hyper-V drivers.
476  */
477 void vmbus_get_interface(struct vmbus_channel_interface *interface)
478 {
479         struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
480
481         vmbus_drv_obj->GetChannelInterface(interface);
482 }
483 EXPORT_SYMBOL(vmbus_get_interface);
484
485 /*
486  * vmbus_child_device_get_info - Get the vmbus child device info.
487  *
488  * This is invoked to display various device attributes in sysfs.
489  */
490 static void vmbus_child_device_get_info(struct hv_device *device_obj,
491                                         struct hv_device_info *device_info)
492 {
493         struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
494
495         vmbus_drv_obj->GetChannelInfo(device_obj, device_info);
496 }
497
498 /*
499  * vmbus_child_device_create - Creates and registers a new child device
500  * on the vmbus.
501  */
502 static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
503                                                    struct hv_guid *instance,
504                                                    void *context)
505 {
506         struct vm_device *child_device_ctx;
507         struct hv_device *child_device_obj;
508
509         DPRINT_ENTER(VMBUS_DRV);
510
511         /* Allocate the new child device */
512         child_device_ctx = kzalloc(sizeof(struct vm_device), GFP_KERNEL);
513         if (!child_device_ctx) {
514                 DPRINT_ERR(VMBUS_DRV,
515                         "unable to allocate device_context for child device");
516                 DPRINT_EXIT(VMBUS_DRV);
517
518                 return NULL;
519         }
520
521         DPRINT_DBG(VMBUS_DRV, "child device (%p) allocated - "
522                 "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
523                 "%02x%02x%02x%02x%02x%02x%02x%02x},"
524                 "id {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
525                 "%02x%02x%02x%02x%02x%02x%02x%02x}",
526                 &child_device_ctx->device,
527                 type->data[3], type->data[2], type->data[1], type->data[0],
528                 type->data[5], type->data[4], type->data[7], type->data[6],
529                 type->data[8], type->data[9], type->data[10], type->data[11],
530                 type->data[12], type->data[13], type->data[14], type->data[15],
531                 instance->data[3], instance->data[2],
532                 instance->data[1], instance->data[0],
533                 instance->data[5], instance->data[4],
534                 instance->data[7], instance->data[6],
535                 instance->data[8], instance->data[9],
536                 instance->data[10], instance->data[11],
537                 instance->data[12], instance->data[13],
538                 instance->data[14], instance->data[15]);
539
540         child_device_obj = &child_device_ctx->device_obj;
541         child_device_obj->context = context;
542         memcpy(&child_device_obj->deviceType, type, sizeof(struct hv_guid));
543         memcpy(&child_device_obj->deviceInstance, instance,
544                sizeof(struct hv_guid));
545
546         memcpy(&child_device_ctx->class_id, type, sizeof(struct hv_guid));
547         memcpy(&child_device_ctx->device_id, instance, sizeof(struct hv_guid));
548
549         DPRINT_EXIT(VMBUS_DRV);
550
551         return child_device_obj;
552 }
553
554 /*
555  * vmbus_child_device_register - Register the child device on the specified bus
556  */
557 static int vmbus_child_device_register(struct hv_device *root_device_obj,
558                                        struct hv_device *child_device_obj)
559 {
560         int ret = 0;
561         struct vm_device *root_device_ctx =
562                                 to_vm_device(root_device_obj);
563         struct vm_device *child_device_ctx =
564                                 to_vm_device(child_device_obj);
565         static atomic_t device_num = ATOMIC_INIT(0);
566
567         DPRINT_ENTER(VMBUS_DRV);
568
569         DPRINT_DBG(VMBUS_DRV, "child device (%p) registering",
570                    child_device_ctx);
571
572         /* Set the device name. Otherwise, device_register() will fail. */
573         dev_set_name(&child_device_ctx->device, "vmbus_0_%d",
574                      atomic_inc_return(&device_num));
575
576         /* The new device belongs to this bus */
577         child_device_ctx->device.bus = &g_vmbus_drv.bus; /* device->dev.bus; */
578         child_device_ctx->device.parent = &root_device_ctx->device;
579         child_device_ctx->device.release = vmbus_device_release;
580
581         /*
582          * Register with the LDM. This will kick off the driver/device
583          * binding...which will eventually call vmbus_match() and vmbus_probe()
584          */
585         ret = device_register(&child_device_ctx->device);
586
587         /* vmbus_probe() error does not get propergate to device_register(). */
588         ret = child_device_ctx->probe_error;
589
590         if (ret)
591                 DPRINT_ERR(VMBUS_DRV, "unable to register child device (%p)",
592                            &child_device_ctx->device);
593         else
594                 DPRINT_INFO(VMBUS_DRV, "child device (%p) registered",
595                             &child_device_ctx->device);
596
597         DPRINT_EXIT(VMBUS_DRV);
598
599         return ret;
600 }
601
602 /*
603  * vmbus_child_device_unregister - Remove the specified child device
604  * from the vmbus.
605  */
606 static void vmbus_child_device_unregister(struct hv_device *device_obj)
607 {
608         struct vm_device *device_ctx = to_vm_device(device_obj);
609
610         DPRINT_ENTER(VMBUS_DRV);
611
612         DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)",
613                     &device_ctx->device);
614
615         /*
616          * Kick off the process of unregistering the device.
617          * This will call vmbus_remove() and eventually vmbus_device_release()
618          */
619         device_unregister(&device_ctx->device);
620
621         DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered",
622                     &device_ctx->device);
623
624         DPRINT_EXIT(VMBUS_DRV);
625 }
626
627 /*
628  * vmbus_child_device_destroy - Destroy the specified child device on the vmbus.
629  */
630 static void vmbus_child_device_destroy(struct hv_device *device_obj)
631 {
632         DPRINT_ENTER(VMBUS_DRV);
633
634         DPRINT_EXIT(VMBUS_DRV);
635 }
636
637 /*
638  * vmbus_uevent - add uevent for our device
639  *
640  * This routine is invoked when a device is added or removed on the vmbus to
641  * generate a uevent to udev in the userspace. The udev will then look at its
642  * rule and the uevent generated here to load the appropriate driver
643  */
644 static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
645 {
646         struct vm_device *device_ctx = device_to_vm_device(device);
647         int ret;
648
649         DPRINT_ENTER(VMBUS_DRV);
650
651         DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={"
652                     "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
653                     "%02x%02x%02x%02x%02x%02x%02x%02x}",
654                     device_ctx->class_id.data[3], device_ctx->class_id.data[2],
655                     device_ctx->class_id.data[1], device_ctx->class_id.data[0],
656                     device_ctx->class_id.data[5], device_ctx->class_id.data[4],
657                     device_ctx->class_id.data[7], device_ctx->class_id.data[6],
658                     device_ctx->class_id.data[8], device_ctx->class_id.data[9],
659                     device_ctx->class_id.data[10],
660                     device_ctx->class_id.data[11],
661                     device_ctx->class_id.data[12],
662                     device_ctx->class_id.data[13],
663                     device_ctx->class_id.data[14],
664                     device_ctx->class_id.data[15]);
665
666         ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={"
667                              "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
668                              "%02x%02x%02x%02x%02x%02x%02x%02x}",
669                              device_ctx->class_id.data[3],
670                              device_ctx->class_id.data[2],
671                              device_ctx->class_id.data[1],
672                              device_ctx->class_id.data[0],
673                              device_ctx->class_id.data[5],
674                              device_ctx->class_id.data[4],
675                              device_ctx->class_id.data[7],
676                              device_ctx->class_id.data[6],
677                              device_ctx->class_id.data[8],
678                              device_ctx->class_id.data[9],
679                              device_ctx->class_id.data[10],
680                              device_ctx->class_id.data[11],
681                              device_ctx->class_id.data[12],
682                              device_ctx->class_id.data[13],
683                              device_ctx->class_id.data[14],
684                              device_ctx->class_id.data[15]);
685
686         if (ret)
687                 return ret;
688
689         ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={"
690                              "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
691                              "%02x%02x%02x%02x%02x%02x%02x%02x}",
692                              device_ctx->device_id.data[3],
693                              device_ctx->device_id.data[2],
694                              device_ctx->device_id.data[1],
695                              device_ctx->device_id.data[0],
696                              device_ctx->device_id.data[5],
697                              device_ctx->device_id.data[4],
698                              device_ctx->device_id.data[7],
699                              device_ctx->device_id.data[6],
700                              device_ctx->device_id.data[8],
701                              device_ctx->device_id.data[9],
702                              device_ctx->device_id.data[10],
703                              device_ctx->device_id.data[11],
704                              device_ctx->device_id.data[12],
705                              device_ctx->device_id.data[13],
706                              device_ctx->device_id.data[14],
707                              device_ctx->device_id.data[15]);
708         if (ret)
709                 return ret;
710
711         DPRINT_EXIT(VMBUS_DRV);
712
713         return 0;
714 }
715
716 /*
717  * vmbus_match - Attempt to match the specified device to the specified driver
718  */
719 static int vmbus_match(struct device *device, struct device_driver *driver)
720 {
721         int match = 0;
722         struct driver_context *driver_ctx = driver_to_driver_context(driver);
723         struct vm_device *device_ctx = device_to_vm_device(device);
724
725         DPRINT_ENTER(VMBUS_DRV);
726
727         /* We found our driver ? */
728         if (memcmp(&device_ctx->class_id, &driver_ctx->class_id,
729                    sizeof(struct hv_guid)) == 0) {
730                 /*
731                  * !! NOTE: The driver_ctx is not a vmbus_drv_ctx. We typecast
732                  * it here to access the struct hv_driver field
733                  */
734                 struct vmbus_driver_context *vmbus_drv_ctx =
735                         (struct vmbus_driver_context *)driver_ctx;
736
737                 device_ctx->device_obj.Driver = &vmbus_drv_ctx->drv_obj.Base;
738                 DPRINT_INFO(VMBUS_DRV,
739                             "device object (%p) set to driver object (%p)",
740                             &device_ctx->device_obj,
741                             device_ctx->device_obj.Driver);
742
743                 match = 1;
744         }
745
746         DPRINT_EXIT(VMBUS_DRV);
747
748         return match;
749 }
750
751 /*
752  * vmbus_probe_failed_cb - Callback when a driver probe failed in vmbus_probe()
753  *
754  * We need a callback because we cannot invoked device_unregister() inside
755  * vmbus_probe() since vmbus_probe() may be invoked inside device_register()
756  * i.e. we cannot call device_unregister() inside device_register()
757  */
758 static void vmbus_probe_failed_cb(struct work_struct *context)
759 {
760         struct vm_device *device_ctx = (struct vm_device *)context;
761
762         DPRINT_ENTER(VMBUS_DRV);
763
764         /*
765          * Kick off the process of unregistering the device.
766          * This will call vmbus_remove() and eventually vmbus_device_release()
767          */
768         device_unregister(&device_ctx->device);
769
770         /* put_device(&device_ctx->device); */
771         DPRINT_EXIT(VMBUS_DRV);
772 }
773
774 /*
775  * vmbus_probe - Add the new vmbus's child device
776  */
777 static int vmbus_probe(struct device *child_device)
778 {
779         int ret = 0;
780         struct driver_context *driver_ctx =
781                         driver_to_driver_context(child_device->driver);
782         struct vm_device *device_ctx =
783                         device_to_vm_device(child_device);
784
785         DPRINT_ENTER(VMBUS_DRV);
786
787         /* Let the specific open-source driver handles the probe if it can */
788         if (driver_ctx->probe) {
789                 ret = device_ctx->probe_error = driver_ctx->probe(child_device);
790                 if (ret != 0) {
791                         DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s "
792                                    "(%p) on driver %s (%d)...",
793                                    dev_name(child_device), child_device,
794                                    child_device->driver->name, ret);
795
796                         INIT_WORK(&device_ctx->probe_failed_work_item,
797                                   vmbus_probe_failed_cb);
798                         schedule_work(&device_ctx->probe_failed_work_item);
799                 }
800         } else {
801                 DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s",
802                            child_device->driver->name);
803                 ret = -1;
804         }
805
806         DPRINT_EXIT(VMBUS_DRV);
807         return ret;
808 }
809
810 /*
811  * vmbus_remove - Remove a vmbus device
812  */
813 static int vmbus_remove(struct device *child_device)
814 {
815         int ret;
816         struct driver_context *driver_ctx;
817
818         DPRINT_ENTER(VMBUS_DRV);
819
820         /* Special case root bus device */
821         if (child_device->parent == NULL) {
822                 /*
823                  * No-op since it is statically defined and handle in
824                  * vmbus_bus_exit()
825                  */
826                 DPRINT_EXIT(VMBUS_DRV);
827                 return 0;
828         }
829
830         if (child_device->driver) {
831                 driver_ctx = driver_to_driver_context(child_device->driver);
832
833                 /*
834                  * Let the specific open-source driver handles the removal if
835                  * it can
836                  */
837                 if (driver_ctx->remove) {
838                         ret = driver_ctx->remove(child_device);
839                 } else {
840                         DPRINT_ERR(VMBUS_DRV,
841                                    "remove() method not set for driver - %s",
842                                    child_device->driver->name);
843                         ret = -1;
844                 }
845         }
846
847         DPRINT_EXIT(VMBUS_DRV);
848
849         return 0;
850 }
851
852 /*
853  * vmbus_shutdown - Shutdown a vmbus device
854  */
855 static void vmbus_shutdown(struct device *child_device)
856 {
857         struct driver_context *driver_ctx;
858
859         DPRINT_ENTER(VMBUS_DRV);
860
861         /* Special case root bus device */
862         if (child_device->parent == NULL) {
863                 /*
864                  * No-op since it is statically defined and handle in
865                  * vmbus_bus_exit()
866                  */
867                 DPRINT_EXIT(VMBUS_DRV);
868                 return;
869         }
870
871         /* The device may not be attached yet */
872         if (!child_device->driver) {
873                 DPRINT_EXIT(VMBUS_DRV);
874                 return;
875         }
876
877         driver_ctx = driver_to_driver_context(child_device->driver);
878
879         /* Let the specific open-source driver handles the removal if it can */
880         if (driver_ctx->shutdown)
881                 driver_ctx->shutdown(child_device);
882
883         DPRINT_EXIT(VMBUS_DRV);
884
885         return;
886 }
887
888 /*
889  * vmbus_bus_release - Final callback release of the vmbus root device
890  */
891 static void vmbus_bus_release(struct device *device)
892 {
893         DPRINT_ENTER(VMBUS_DRV);
894         /* FIXME */
895         /* Empty release functions are a bug, or a major sign
896          * of a problem design, this MUST BE FIXED! */
897         dev_err(device, "%s needs to be fixed!\n", __func__);
898         WARN_ON(1);
899         DPRINT_EXIT(VMBUS_DRV);
900 }
901
902 /*
903  * vmbus_device_release - Final callback release of the vmbus child device
904  */
905 static void vmbus_device_release(struct device *device)
906 {
907         struct vm_device *device_ctx = device_to_vm_device(device);
908
909         DPRINT_ENTER(VMBUS_DRV);
910
911         /* vmbus_child_device_destroy(&device_ctx->device_obj); */
912         kfree(device_ctx);
913
914         /* !!DO NOT REFERENCE device_ctx anymore at this point!! */
915         DPRINT_EXIT(VMBUS_DRV);
916
917         return;
918 }
919
920 /*
921  * vmbus_msg_dpc - Tasklet routine to handle hypervisor messages
922  */
923 static void vmbus_msg_dpc(unsigned long data)
924 {
925         struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data;
926
927         DPRINT_ENTER(VMBUS_DRV);
928
929         /* ASSERT(vmbus_drv_obj->OnMsgDpc != NULL); */
930
931         /* Call to bus driver to handle interrupt */
932         vmbus_drv_obj->OnMsgDpc(&vmbus_drv_obj->Base);
933
934         DPRINT_EXIT(VMBUS_DRV);
935 }
936
937 /*
938  * vmbus_msg_dpc - Tasklet routine to handle hypervisor events
939  */
940 static void vmbus_event_dpc(unsigned long data)
941 {
942         struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data;
943
944         DPRINT_ENTER(VMBUS_DRV);
945
946         /* ASSERT(vmbus_drv_obj->OnEventDpc != NULL); */
947
948         /* Call to bus driver to handle interrupt */
949         vmbus_drv_obj->OnEventDpc(&vmbus_drv_obj->Base);
950
951         DPRINT_EXIT(VMBUS_DRV);
952 }
953
954 static irqreturn_t vmbus_isr(int irq, void *dev_id)
955 {
956         struct vmbus_driver *vmbus_driver_obj = &g_vmbus_drv.drv_obj;
957         int ret;
958
959         DPRINT_ENTER(VMBUS_DRV);
960
961         /* ASSERT(vmbus_driver_obj->OnIsr != NULL); */
962
963         /* Call to bus driver to handle interrupt */
964         ret = vmbus_driver_obj->OnIsr(&vmbus_driver_obj->Base);
965
966         /* Schedules a dpc if necessary */
967         if (ret > 0) {
968                 if (test_bit(0, (unsigned long *)&ret))
969                         tasklet_schedule(&g_vmbus_drv.msg_dpc);
970
971                 if (test_bit(1, (unsigned long *)&ret))
972                         tasklet_schedule(&g_vmbus_drv.event_dpc);
973
974                 DPRINT_EXIT(VMBUS_DRV);
975                 return IRQ_HANDLED;
976         } else {
977                 DPRINT_EXIT(VMBUS_DRV);
978                 return IRQ_NONE;
979         }
980 }
981
982 static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = {
983         {
984                 .ident = "Hyper-V",
985                 .matches = {
986                         DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
987                         DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
988                         DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
989                 },
990         },
991         { },
992 };
993 MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table);
994
995 static int __init vmbus_init(void)
996 {
997         int ret = 0;
998
999         DPRINT_ENTER(VMBUS_DRV);
1000
1001         DPRINT_INFO(VMBUS_DRV,
1002                 "Vmbus initializing.... current log level 0x%x (%x,%x)",
1003                 vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
1004         /* Todo: it is used for loglevel, to be ported to new kernel. */
1005
1006         if (!dmi_check_system(microsoft_hv_dmi_table))
1007                 return -ENODEV;
1008
1009         ret = vmbus_bus_init(VmbusInitialize);
1010
1011         DPRINT_EXIT(VMBUS_DRV);
1012         return ret;
1013 }
1014
1015 static void __exit vmbus_exit(void)
1016 {
1017         DPRINT_ENTER(VMBUS_DRV);
1018
1019         vmbus_bus_exit();
1020         /* Todo: it is used for loglevel, to be ported to new kernel. */
1021         DPRINT_EXIT(VMBUS_DRV);
1022         return;
1023 }
1024
1025 /*
1026  * We use a PCI table to determine if we should autoload this driver  This is
1027  * needed by distro tools to determine if the hyperv drivers should be
1028  * installed and/or configured.  We don't do anything else with the table, but
1029  * it needs to be present.
1030  */
1031 const static struct pci_device_id microsoft_hv_pci_table[] = {
1032         { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
1033         { 0 }
1034 };
1035 MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
1036
1037 MODULE_LICENSE("GPL");
1038 MODULE_VERSION(HV_DRV_VERSION);
1039 module_param(vmbus_irq, int, S_IRUGO);
1040 module_param(vmbus_loglevel, int, S_IRUGO);
1041
1042 module_init(vmbus_init);
1043 module_exit(vmbus_exit);