Staging: hv: remove ReadMsr and WriteMsr functions from Hv.h
[safe/jmp/linux-2.6] / drivers / staging / hv / vmbus_drv.c
1 /*
2  *
3  * Copyright (c) 2009, Microsoft Corporation.
4  *
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.
8  *
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
12  * more details.
13  *
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.
17  *
18  * Authors:
19  *   Haiyang Zhang <haiyangz@microsoft.com>
20  *   Hank Janssen  <hjanssen@microsoft.com>
21  *
22  */
23
24
25 #include <linux/init.h>
26 #include <linux/module.h>
27 #include <linux/device.h>
28 #include <linux/irq.h>
29 #include <linux/interrupt.h>
30 #include <linux/sysctl.h>
31
32 #include "include/logging.h"
33 #include "include/vmbus.h"
34
35
36 /* Defines */
37
38
39 /* FIXME! We need to do this dynamically for PIC and APIC system */
40 #define VMBUS_IRQ                               0x5
41 #define VMBUS_IRQ_VECTOR     IRQ5_VECTOR
42
43 /* Data types */
44
45
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         VMBUS_DRIVER_OBJECT             drv_obj;
53
54         struct bus_type                 bus;
55         struct tasklet_struct   msg_dpc;
56         struct tasklet_struct   event_dpc;
57
58         /* The bus root device */
59         struct device_context   device_ctx;
60 };
61
62
63 /* Static decl */
64
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);
72
73 static irqreturn_t vmbus_isr(int irq, void* dev_id);
74
75 static void vmbus_device_release(struct device *device);
76 static void vmbus_bus_release(struct device *device);
77
78 static struct hv_device *vmbus_child_device_create(GUID type, 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, DEVICE_INFO *device_info);
83
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); */
86
87 static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf);
88
89
90 /* Global */
91
92
93 /* Global logging setting */
94
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);
99
100 static int vmbus_irq = VMBUS_IRQ;
101
102 /* Setup /proc/sys/bus/vmbus/vmbus_loglevel */
103 /* Allow usage of sysctl cmd to set the logging level */
104
105 /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
106
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),
113
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),
117
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),
121
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),
127
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),
133         __ATTR_NULL
134 };
135
136 /* The one and only one */
137 static struct vmbus_driver_context g_vmbus_drv={
138         .bus.name       = "vmbus",
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,
145 };
146
147
148 /* Routines */
149
150
151
152 /*++
153
154 Name:   vmbus_show_device_attr()
155
156 Desc:   Show the device attribute in sysfs. This is invoked when user does a "cat /sys/bus/vmbus/devices/<bus device>/<attr name>"
157
158 --*/
159 static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf)
160 {
161         struct device_context *device_ctx = device_to_device_context(dev);
162         DEVICE_INFO device_info;
163
164         memset(&device_info, 0, sizeof(DEVICE_INFO));
165
166         vmbus_child_device_get_info(&device_ctx->device_obj, &device_info);
167
168         if (!strcmp(dev_attr->attr.name, "class_id"))
169         {
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], device_info.ChannelType.Data[1], device_info.ChannelType.Data[0],
172                         device_info.ChannelType.Data[5], device_info.ChannelType.Data[4],
173                         device_info.ChannelType.Data[7], device_info.ChannelType.Data[6],
174                         device_info.ChannelType.Data[8], device_info.ChannelType.Data[9], device_info.ChannelType.Data[10], device_info.ChannelType.Data[11], device_info.ChannelType.Data[12], device_info.ChannelType.Data[13], device_info.ChannelType.Data[14], device_info.ChannelType.Data[15]);
175
176         }
177         else if (!strcmp(dev_attr->attr.name, "device_id"))
178         {
179                 return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n",
180                         device_info.ChannelInstance.Data[3], device_info.ChannelInstance.Data[2], device_info.ChannelInstance.Data[1], device_info.ChannelInstance.Data[0],
181                         device_info.ChannelInstance.Data[5], device_info.ChannelInstance.Data[4],
182                         device_info.ChannelInstance.Data[7], device_info.ChannelInstance.Data[6],
183                         device_info.ChannelInstance.Data[8], device_info.ChannelInstance.Data[9], device_info.ChannelInstance.Data[10], device_info.ChannelInstance.Data[11], device_info.ChannelInstance.Data[12], device_info.ChannelInstance.Data[13], device_info.ChannelInstance.Data[14], device_info.ChannelInstance.Data[15]);
184         }
185         else if (!strcmp(dev_attr->attr.name, "state"))
186         {
187                 return sprintf(buf, "%d\n", device_info.ChannelState);
188         }
189         else if (!strcmp(dev_attr->attr.name, "id"))
190         {
191                 return sprintf(buf, "%d\n", device_info.ChannelId);
192         }
193         else if (!strcmp(dev_attr->attr.name, "out_intr_mask"))
194         {
195                 return sprintf(buf, "%d\n", device_info.Outbound.InterruptMask);
196         }
197         else if (!strcmp(dev_attr->attr.name, "out_read_index"))
198         {
199                 return sprintf(buf, "%d\n", device_info.Outbound.ReadIndex);
200         }
201         else if (!strcmp(dev_attr->attr.name, "out_write_index"))
202         {
203                 return sprintf(buf, "%d\n", device_info.Outbound.WriteIndex);
204         }
205         else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail"))
206         {
207                 return sprintf(buf, "%d\n", device_info.Outbound.BytesAvailToRead);
208         }
209         else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail"))
210         {
211                 return sprintf(buf, "%d\n", device_info.Outbound.BytesAvailToWrite);
212         }
213         else if (!strcmp(dev_attr->attr.name, "in_intr_mask"))
214         {
215                 return sprintf(buf, "%d\n", device_info.Inbound.InterruptMask);
216         }
217         else if (!strcmp(dev_attr->attr.name, "in_read_index"))
218         {
219                 return sprintf(buf, "%d\n", device_info.Inbound.ReadIndex);
220         }
221         else if (!strcmp(dev_attr->attr.name, "in_write_index"))
222         {
223                 return sprintf(buf, "%d\n", device_info.Inbound.WriteIndex);
224         }
225         else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail"))
226         {
227                 return sprintf(buf, "%d\n", device_info.Inbound.BytesAvailToRead);
228         }
229         else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail"))
230         {
231                 return sprintf(buf, "%d\n", device_info.Inbound.BytesAvailToWrite);
232         }
233         else if (!strcmp(dev_attr->attr.name, "monitor_id"))
234         {
235                 return sprintf(buf, "%d\n", device_info.MonitorId);
236         }
237         else if (!strcmp(dev_attr->attr.name, "server_monitor_pending"))
238         {
239                 return sprintf(buf, "%d\n", device_info.ServerMonitorPending);
240         }
241         else if (!strcmp(dev_attr->attr.name, "server_monitor_latency"))
242         {
243                 return sprintf(buf, "%d\n", device_info.ServerMonitorLatency);
244         }
245         else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id"))
246         {
247                 return sprintf(buf, "%d\n", device_info.ServerMonitorConnectionId);
248         }
249         else if (!strcmp(dev_attr->attr.name, "client_monitor_pending"))
250         {
251                 return sprintf(buf, "%d\n", device_info.ClientMonitorPending);
252         }
253         else if (!strcmp(dev_attr->attr.name, "client_monitor_latency"))
254         {
255                 return sprintf(buf, "%d\n", device_info.ClientMonitorLatency);
256         }
257         else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id"))
258         {
259                 return sprintf(buf, "%d\n", device_info.ClientMonitorConnectionId);
260         }
261         else
262         {
263                 return 0;
264         }
265 }
266
267 /*++
268
269 Name:   vmbus_show_class_id()
270
271 Desc:   Show the device class id in sysfs
272
273 --*/
274 /* static ssize_t vmbus_show_class_id(struct device *dev, struct device_attribute *attr, char *buf) */
275 /* { */
276 /* struct device_context *device_ctx = device_to_device_context(dev); */
277 /* return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n", */
278 /*      device_ctx->class_id[3], device_ctx->class_id[2], device_ctx->class_id[1], device_ctx->class_id[0], */
279 /*      device_ctx->class_id[5], device_ctx->class_id[4], */
280 /*      device_ctx->class_id[7], device_ctx->class_id[6], */
281 /*      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]); */
282 /* } */
283
284 /*++
285
286 Name:   vmbus_show_device_id()
287
288 Desc:   Show the device instance id in sysfs
289
290 --*/
291 /* static ssize_t vmbus_show_device_id(struct device *dev, struct device_attribute *attr, char *buf) */
292 /* { */
293 /* struct device_context *device_ctx = device_to_device_context(dev); */
294 /* return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n", */
295 /*      device_ctx->device_id[3], device_ctx->device_id[2], device_ctx->device_id[1], device_ctx->device_id[0], */
296 /*      device_ctx->device_id[5], device_ctx->device_id[4], */
297 /*      device_ctx->device_id[7], device_ctx->device_id[6], */
298 /*      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]); */
299 /* } */
300
301 /*++
302
303 Name:   vmbus_bus_init()
304
305 Desc:   Main vmbus driver initialization routine. Here, we
306                 - initialize the vmbus driver context
307                 - setup various driver entry points
308                 - invoke the vmbus hv main init routine
309                 - get the irq resource
310                 - invoke the vmbus to add the vmbus root device
311                 - setup the vmbus root device
312                 - retrieve the channel offers
313 --*/
314 static int vmbus_bus_init(PFN_DRIVERINITIALIZE pfn_drv_init)
315 {
316         int ret=0;
317         unsigned int vector=0;
318
319         struct vmbus_driver_context *vmbus_drv_ctx=&g_vmbus_drv;
320         VMBUS_DRIVER_OBJECT *vmbus_drv_obj=&g_vmbus_drv.drv_obj;
321
322         struct device_context *dev_ctx=&g_vmbus_drv.device_ctx;
323
324         DPRINT_ENTER(VMBUS_DRV);
325
326         /* Set this up to allow lower layer to callback to add/remove child devices on the bus */
327         vmbus_drv_obj->OnChildDeviceCreate = vmbus_child_device_create;
328         vmbus_drv_obj->OnChildDeviceDestroy = vmbus_child_device_destroy;
329         vmbus_drv_obj->OnChildDeviceAdd = vmbus_child_device_register;
330         vmbus_drv_obj->OnChildDeviceRemove = vmbus_child_device_unregister;
331
332         /* Call to bus driver to initialize */
333         ret = pfn_drv_init(&vmbus_drv_obj->Base);
334         if (ret != 0)
335         {
336                 DPRINT_ERR(VMBUS_DRV, "Unable to initialize vmbus (%d)", ret);
337                 goto cleanup;
338         }
339
340         /* Sanity checks */
341         if (!vmbus_drv_obj->Base.OnDeviceAdd)
342         {
343                 DPRINT_ERR(VMBUS_DRV, "OnDeviceAdd() routine not set");
344                 ret = -1;
345                 goto cleanup;
346         }
347
348         vmbus_drv_ctx->bus.name = vmbus_drv_obj->Base.name;
349
350         /* Initialize the bus context */
351         tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_msg_dpc, (unsigned long)vmbus_drv_obj);
352         tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc, (unsigned long)vmbus_drv_obj);
353
354         /* Now, register the bus driver with LDM */
355         ret = bus_register(&vmbus_drv_ctx->bus);
356         if (ret)
357         {
358                 ret = -1;
359                 goto cleanup;
360         }
361
362         /* Get the interrupt resource */
363         ret = request_irq(vmbus_irq,
364                           vmbus_isr,
365                           IRQF_SAMPLE_RANDOM,
366                           vmbus_drv_obj->Base.name,
367                           NULL);
368
369         if (ret != 0)
370         {
371                 DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d", vmbus_irq);
372
373                 bus_unregister(&vmbus_drv_ctx->bus);
374
375                 ret = -1;
376                 goto cleanup;
377         }
378         vector = VMBUS_IRQ_VECTOR;
379
380         DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector);
381
382         /* Call to bus driver to add the root device */
383         memset(dev_ctx, 0, sizeof(struct device_context));
384
385         ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector);
386         if (ret != 0)
387         {
388                 DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to add vmbus root device");
389
390                 free_irq(vmbus_irq, NULL);
391
392                 bus_unregister(&vmbus_drv_ctx->bus);
393
394                 ret = -1;
395                 goto cleanup;
396         }
397         /* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */
398         dev_set_name(&dev_ctx->device, "vmbus_0_0");
399         memcpy(&dev_ctx->class_id, &dev_ctx->device_obj.deviceType, sizeof(GUID));
400         memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.deviceInstance, sizeof(GUID));
401
402         /* No need to bind a driver to the root device. */
403         dev_ctx->device.parent = NULL;
404         dev_ctx->device.bus = &vmbus_drv_ctx->bus; /* NULL; vmbus_remove() does not get invoked */
405
406         /* Setup the device dispatch table */
407         dev_ctx->device.release = vmbus_bus_release;
408
409         /* Setup the bus as root device */
410         ret = device_register(&dev_ctx->device);
411         if (ret)
412         {
413                 DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to register vmbus root device");
414
415                 free_irq(vmbus_irq, NULL);
416                 bus_unregister(&vmbus_drv_ctx->bus);
417
418                 ret = -1;
419                 goto cleanup;
420         }
421
422
423         vmbus_drv_obj->GetChannelOffers();
424
425 cleanup:
426         DPRINT_EXIT(VMBUS_DRV);
427
428         return ret;
429 }
430
431
432 /*++
433
434 Name:   vmbus_bus_exit()
435
436 Desc:   Terminate the vmbus driver. This routine is opposite of vmbus_bus_init()
437
438 --*/
439 static void vmbus_bus_exit(void)
440 {
441         VMBUS_DRIVER_OBJECT *vmbus_drv_obj=&g_vmbus_drv.drv_obj;
442         struct vmbus_driver_context *vmbus_drv_ctx=&g_vmbus_drv;
443
444         struct device_context *dev_ctx=&g_vmbus_drv.device_ctx;
445
446         DPRINT_ENTER(VMBUS_DRV);
447
448         /* Remove the root device */
449         if (vmbus_drv_obj->Base.OnDeviceRemove)
450                 vmbus_drv_obj->Base.OnDeviceRemove(&dev_ctx->device_obj);
451
452         if (vmbus_drv_obj->Base.OnCleanup)
453                 vmbus_drv_obj->Base.OnCleanup(&vmbus_drv_obj->Base);
454
455         /* Unregister the root bus device */
456         device_unregister(&dev_ctx->device);
457
458         bus_unregister(&vmbus_drv_ctx->bus);
459
460         free_irq(vmbus_irq, NULL);
461
462         tasklet_kill(&vmbus_drv_ctx->msg_dpc);
463         tasklet_kill(&vmbus_drv_ctx->event_dpc);
464
465         DPRINT_EXIT(VMBUS_DRV);
466
467         return;
468 }
469
470 /*++
471
472 Name:   vmbus_child_driver_register()
473
474 Desc:   Register a vmbus's child driver
475
476 --*/
477 int vmbus_child_driver_register(struct driver_context* driver_ctx)
478 {
479         VMBUS_DRIVER_OBJECT *vmbus_drv_obj=&g_vmbus_drv.drv_obj;
480         int ret;
481
482         DPRINT_ENTER(VMBUS_DRV);
483
484         DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s", driver_ctx, driver_ctx->driver.name);
485
486         /* The child driver on this vmbus */
487         driver_ctx->driver.bus = &g_vmbus_drv.bus;
488
489         ret = driver_register(&driver_ctx->driver);
490
491         vmbus_drv_obj->GetChannelOffers();
492
493         DPRINT_EXIT(VMBUS_DRV);
494
495         return ret;
496 }
497
498 EXPORT_SYMBOL(vmbus_child_driver_register);
499
500 /*++
501
502 Name:   vmbus_child_driver_unregister()
503
504 Desc:   Unregister a vmbus's child driver
505
506 --*/
507 void vmbus_child_driver_unregister(struct driver_context* driver_ctx)
508 {
509         DPRINT_ENTER(VMBUS_DRV);
510
511         DPRINT_INFO(VMBUS_DRV, "child driver (%p) unregistering - name %s", driver_ctx, driver_ctx->driver.name);
512
513         driver_unregister(&driver_ctx->driver);
514
515         driver_ctx->driver.bus = NULL;
516
517         DPRINT_EXIT(VMBUS_DRV);
518 }
519
520 EXPORT_SYMBOL(vmbus_child_driver_unregister);
521
522 /*++
523
524 Name:   vmbus_get_interface()
525
526 Desc:   Get the vmbus channel interface. This is invoked by child/client driver that sits
527                 above vmbus
528 --*/
529 void vmbus_get_interface(VMBUS_CHANNEL_INTERFACE *interface)
530 {
531         VMBUS_DRIVER_OBJECT *vmbus_drv_obj=&g_vmbus_drv.drv_obj;
532
533         vmbus_drv_obj->GetChannelInterface(interface);
534 }
535
536 EXPORT_SYMBOL(vmbus_get_interface);
537
538
539 /*++
540
541 Name:   vmbus_child_device_get_info()
542
543 Desc:   Get the vmbus child device info. This is invoked to display various device attributes in sysfs.
544 --*/
545 static void vmbus_child_device_get_info(struct hv_device *device_obj, DEVICE_INFO *device_info)
546 {
547         VMBUS_DRIVER_OBJECT *vmbus_drv_obj=&g_vmbus_drv.drv_obj;
548
549         vmbus_drv_obj->GetChannelInfo(device_obj, device_info);
550 }
551
552
553 /*++
554
555 Name:   vmbus_child_device_create()
556
557 Desc:   Creates and registers a new child device on the vmbus.
558
559 --*/
560 static struct hv_device *vmbus_child_device_create(GUID type, GUID instance, void* context)
561 {
562         struct device_context *child_device_ctx;
563         struct hv_device *child_device_obj;
564
565         DPRINT_ENTER(VMBUS_DRV);
566
567         /* Allocate the new child device */
568         child_device_ctx = kzalloc(sizeof(struct device_context), GFP_KERNEL);
569         if (!child_device_ctx)
570         {
571                 DPRINT_ERR(VMBUS_DRV, "unable to allocate device_context for child device");
572                 DPRINT_EXIT(VMBUS_DRV);
573
574                 return NULL;
575         }
576
577         DPRINT_DBG(VMBUS_DRV, "child device (%p) allocated - "
578                 "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x},"
579                 "id {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}",
580                 &child_device_ctx->device,
581                 type.Data[3], type.Data[2], type.Data[1], type.Data[0], type.Data[5], type.Data[4], type.Data[7], type.Data[6], type.Data[8], type.Data[9], type.Data[10], type.Data[11], type.Data[12], type.Data[13], type.Data[14], type.Data[15],
582                 instance.Data[3], instance.Data[2], instance.Data[1], instance.Data[0], instance.Data[5], instance.Data[4], instance.Data[7], instance.Data[6], instance.Data[8], instance.Data[9], instance.Data[10], instance.Data[11], instance.Data[12], instance.Data[13], instance.Data[14], instance.Data[15]);
583
584         child_device_obj = &child_device_ctx->device_obj;
585         child_device_obj->context = context;
586         memcpy(&child_device_obj->deviceType, &type, sizeof(GUID));
587         memcpy(&child_device_obj->deviceInstance, &instance, sizeof(GUID));
588
589         memcpy(&child_device_ctx->class_id, &type, sizeof(GUID));
590         memcpy(&child_device_ctx->device_id, &instance, sizeof(GUID));
591
592         DPRINT_EXIT(VMBUS_DRV);
593
594         return child_device_obj;
595 }
596
597 /*++
598
599 Name:   vmbus_child_device_register()
600
601 Desc:   Register the child device on the specified bus
602
603 --*/
604 static int vmbus_child_device_register(struct hv_device *root_device_obj, struct hv_device *child_device_obj)
605 {
606         int ret=0;
607         struct device_context *root_device_ctx = to_device_context(root_device_obj);
608         struct device_context *child_device_ctx = to_device_context(child_device_obj);
609         static atomic_t device_num = ATOMIC_INIT(0);
610
611         DPRINT_ENTER(VMBUS_DRV);
612
613         DPRINT_DBG(VMBUS_DRV, "child device (%p) registering", child_device_ctx);
614
615         /* Make sure we are not registered already */
616
617         if (strlen(dev_name(&child_device_ctx->device)) != 0)
618         {
619                 DPRINT_ERR(VMBUS_DRV, "child device (%p) already registered - busid %s", child_device_ctx, dev_name(&child_device_ctx->device));
620
621                 ret = -1;
622                 goto Cleanup;
623         }
624
625         /* Set the device bus id. Otherwise, device_register()will fail. */
626         dev_set_name(&child_device_ctx->device, "vmbus_0_%d", atomic_inc_return(&device_num));
627
628         /* The new device belongs to this bus */
629         child_device_ctx->device.bus = &g_vmbus_drv.bus; /* device->dev.bus; */
630         child_device_ctx->device.parent = &root_device_ctx->device;
631         child_device_ctx->device.release = vmbus_device_release;
632
633         /* Register with the LDM. This will kick off the driver/device binding...which will */
634         /* eventually call vmbus_match() and vmbus_probe() */
635         ret = device_register(&child_device_ctx->device);
636
637         /* vmbus_probe() error does not get propergate to device_register(). */
638         ret = child_device_ctx->probe_error;
639
640         if (ret)
641                 DPRINT_ERR(VMBUS_DRV, "unable to register child device (%p)", &child_device_ctx->device);
642         else
643                 DPRINT_INFO(VMBUS_DRV, "child device (%p) registered", &child_device_ctx->device);
644
645 Cleanup:
646         DPRINT_EXIT(VMBUS_DRV);
647
648         return ret;
649 }
650
651 /*++
652
653 Name:   vmbus_child_device_unregister()
654
655 Desc:   Remove the specified child device from the vmbus.
656
657 --*/
658 static void vmbus_child_device_unregister(struct hv_device *device_obj)
659 {
660         struct device_context *device_ctx = to_device_context(device_obj);
661
662         DPRINT_ENTER(VMBUS_DRV);
663
664         DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)", &device_ctx->device);
665
666         /* Kick off the process of unregistering the device. */
667         /* This will call vmbus_remove() and eventually vmbus_device_release() */
668         device_unregister(&device_ctx->device);
669
670         DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered", &device_ctx->device);
671
672         DPRINT_EXIT(VMBUS_DRV);
673 }
674
675
676 /*++
677
678 Name:   vmbus_child_device_destroy()
679
680 Desc:   Destroy the specified child device on the vmbus.
681
682 --*/
683 static void vmbus_child_device_destroy(struct hv_device *device_obj)
684 {
685         DPRINT_ENTER(VMBUS_DRV);
686
687         DPRINT_EXIT(VMBUS_DRV);
688 }
689
690 /*++
691
692 Name:   vmbus_uevent()
693
694 Desc:   This routine is invoked when a device is added or removed on the vmbus to generate a uevent to udev in the
695                 userspace. The udev will then look at its rule and the uevent generated here to load the appropriate driver
696
697 --*/
698 static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
699 {
700         struct device_context *device_ctx = device_to_device_context(device);
701         int i=0;
702         int len=0;
703         int ret;
704
705         DPRINT_ENTER(VMBUS_DRV);
706
707         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}",
708                 device_ctx->class_id.Data[3], device_ctx->class_id.Data[2], device_ctx->class_id.Data[1], device_ctx->class_id.Data[0],
709                 device_ctx->class_id.Data[5], device_ctx->class_id.Data[4],
710                 device_ctx->class_id.Data[7], device_ctx->class_id.Data[6],
711                 device_ctx->class_id.Data[8], device_ctx->class_id.Data[9], device_ctx->class_id.Data[10], device_ctx->class_id.Data[11],
712                 device_ctx->class_id.Data[12], device_ctx->class_id.Data[13], device_ctx->class_id.Data[14], device_ctx->class_id.Data[15]);
713
714         env->envp_idx = i;
715         env->buflen = len;
716         ret = add_uevent_var(env,
717                 "VMBUS_DEVICE_CLASS_GUID={%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}",
718                 device_ctx->class_id.Data[3], device_ctx->class_id.Data[2], device_ctx->class_id.Data[1], device_ctx->class_id.Data[0],
719                 device_ctx->class_id.Data[5], device_ctx->class_id.Data[4],
720                 device_ctx->class_id.Data[7], device_ctx->class_id.Data[6],
721                 device_ctx->class_id.Data[8], device_ctx->class_id.Data[9], device_ctx->class_id.Data[10], device_ctx->class_id.Data[11],
722                 device_ctx->class_id.Data[12], device_ctx->class_id.Data[13], device_ctx->class_id.Data[14], device_ctx->class_id.Data[15]);
723
724         if (ret)
725         {
726                 return ret;
727         }
728
729         ret = add_uevent_var(env,
730                 "VMBUS_DEVICE_DEVICE_GUID={%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}",
731                 device_ctx->device_id.Data[3], device_ctx->device_id.Data[2], device_ctx->device_id.Data[1], device_ctx->device_id.Data[0],
732                 device_ctx->device_id.Data[5], device_ctx->device_id.Data[4],
733                 device_ctx->device_id.Data[7], device_ctx->device_id.Data[6],
734                 device_ctx->device_id.Data[8], device_ctx->device_id.Data[9], device_ctx->device_id.Data[10], device_ctx->device_id.Data[11],
735                 device_ctx->device_id.Data[12], device_ctx->device_id.Data[13], device_ctx->device_id.Data[14], device_ctx->device_id.Data[15]);
736
737         if (ret)
738         {
739                 return ret;
740         }
741
742         env->envp[env->envp_idx] = NULL;
743
744         DPRINT_EXIT(VMBUS_DRV);
745
746         return 0;
747 }
748
749 /*++
750
751 Name:   vmbus_match()
752
753 Desc:   Attempt to match the specified device to the specified driver
754
755 --*/
756 static int vmbus_match(struct device *device, struct device_driver *driver)
757 {
758         int match=0;
759         struct driver_context *driver_ctx = driver_to_driver_context(driver);
760         struct device_context *device_ctx = device_to_device_context(device);
761
762         DPRINT_ENTER(VMBUS_DRV);
763
764         /* We found our driver ? */
765         if (memcmp(&device_ctx->class_id, &driver_ctx->class_id, sizeof(GUID)) == 0)
766         {
767                 /* !! NOTE: The driver_ctx is not a vmbus_drv_ctx. We typecast it here to access the */
768                 /* struct hv_driver field */
769                 struct vmbus_driver_context *vmbus_drv_ctx = (struct vmbus_driver_context*)driver_ctx;
770                 device_ctx->device_obj.Driver = &vmbus_drv_ctx->drv_obj.Base;
771                 DPRINT_INFO(VMBUS_DRV, "device object (%p) set to driver object (%p)", &device_ctx->device_obj, device_ctx->device_obj.Driver);
772
773                 match = 1;
774         }
775
776         DPRINT_EXIT(VMBUS_DRV);
777
778         return match;
779 }
780
781
782 /*++
783
784 Name:   vmbus_probe_failed_cb()
785
786 Desc:   Callback when a driver probe failed in vmbus_probe(). We need a callback because
787                 we cannot invoked device_unregister() inside vmbus_probe() since vmbus_probe() may be
788                 invoked inside device_register() i.e. we cannot call device_unregister() inside
789                 device_register()
790 --*/
791 static void vmbus_probe_failed_cb(struct work_struct *context)
792 {
793         struct device_context *device_ctx = (struct device_context*)context;
794
795
796         DPRINT_ENTER(VMBUS_DRV);
797
798         /* Kick off the process of unregistering the device. */
799         /* This will call vmbus_remove() and eventually vmbus_device_release() */
800         device_unregister(&device_ctx->device);
801
802         /* put_device(&device_ctx->device); */
803         DPRINT_EXIT(VMBUS_DRV);
804 }
805
806
807 /*++
808
809 Name:   vmbus_probe()
810
811 Desc:   Add the new vmbus's child device
812
813 --*/
814 static int vmbus_probe(struct device *child_device)
815 {
816         int ret=0;
817         struct driver_context *driver_ctx = driver_to_driver_context(child_device->driver);
818         struct device_context *device_ctx = device_to_device_context(child_device);
819
820         DPRINT_ENTER(VMBUS_DRV);
821
822         /* Let the specific open-source driver handles the probe if it can */
823         if (driver_ctx->probe)
824         {
825                 ret = device_ctx->probe_error = driver_ctx->probe(child_device);
826                 if (ret != 0)
827                 {
828                         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);
829
830                         INIT_WORK(&device_ctx->probe_failed_work_item, vmbus_probe_failed_cb);
831                         schedule_work(&device_ctx->probe_failed_work_item);
832                 }
833         }
834         else
835         {
836                 DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s", child_device->driver->name);
837                 ret = -1;
838         }
839
840         DPRINT_EXIT(VMBUS_DRV);
841         return ret;
842 }
843
844
845 /*++
846
847 Name:   vmbus_remove()
848
849 Desc:   Remove a vmbus device
850
851 --*/
852 static int vmbus_remove(struct device *child_device)
853 {
854         int ret=0;
855         struct driver_context *driver_ctx;
856
857         DPRINT_ENTER(VMBUS_DRV);
858
859         /* Special case root bus device */
860         if (child_device->parent == NULL)
861         {
862                 /* No-op since it is statically defined and handle in vmbus_bus_exit() */
863                 DPRINT_EXIT(VMBUS_DRV);
864                 return 0;
865         }
866
867         if (child_device->driver)
868         {
869                 driver_ctx = driver_to_driver_context(child_device->driver);
870
871                 /* Let the specific open-source driver handles the removal if it can */
872                 if (driver_ctx->remove)
873                 {
874                         ret = driver_ctx->remove(child_device);
875                 }
876                 else
877                 {
878                         DPRINT_ERR(VMBUS_DRV, "remove() method not set for driver - %s", child_device->driver->name);
879                         ret = -1;
880                 }
881         }
882         else
883         {
884
885         }
886
887         DPRINT_EXIT(VMBUS_DRV);
888
889         return 0;
890 }
891
892 /*++
893
894 Name:   vmbus_shutdown()
895
896 Desc:   Shutdown a vmbus device
897
898 --*/
899 static void vmbus_shutdown(struct device *child_device)
900 {
901         struct driver_context *driver_ctx;
902
903         DPRINT_ENTER(VMBUS_DRV);
904
905         /* Special case root bus device */
906         if (child_device->parent == NULL)
907         {
908                 /* No-op since it is statically defined and handle in vmbus_bus_exit() */
909                 DPRINT_EXIT(VMBUS_DRV);
910                 return;
911         }
912
913         /* The device may not be attached yet */
914         if (!child_device->driver)
915         {
916                 DPRINT_EXIT(VMBUS_DRV);
917                 return;
918         }
919
920         driver_ctx = driver_to_driver_context(child_device->driver);
921
922         /* Let the specific open-source driver handles the removal if it can */
923         if (driver_ctx->shutdown)
924         {
925                 driver_ctx->shutdown(child_device);
926         }
927
928         DPRINT_EXIT(VMBUS_DRV);
929
930         return;
931 }
932
933 /*++
934
935 Name:   vmbus_bus_release()
936
937 Desc:   Final callback release of the vmbus root device
938
939 --*/
940 static void vmbus_bus_release(struct device *device)
941 {
942         DPRINT_ENTER(VMBUS_DRV);
943         DPRINT_EXIT(VMBUS_DRV);
944 }
945
946 /*++
947
948 Name:   vmbus_device_release()
949
950 Desc:   Final callback release of the vmbus child device
951
952 --*/
953 static void vmbus_device_release(struct device *device)
954 {
955         struct device_context *device_ctx = device_to_device_context(device);
956
957         DPRINT_ENTER(VMBUS_DRV);
958
959         /* vmbus_child_device_destroy(&device_ctx->device_obj); */
960         kfree(device_ctx);
961
962         /* !!DO NOT REFERENCE device_ctx anymore at this point!! */
963
964         DPRINT_EXIT(VMBUS_DRV);
965
966         return;
967 }
968
969 /*++
970
971 Name:   vmbus_msg_dpc()
972
973 Desc:   Tasklet routine to handle hypervisor messages
974
975 --*/
976 static void vmbus_msg_dpc(unsigned long data)
977 {
978         VMBUS_DRIVER_OBJECT* vmbus_drv_obj = (VMBUS_DRIVER_OBJECT*)data;
979
980         DPRINT_ENTER(VMBUS_DRV);
981
982         ASSERT(vmbus_drv_obj->OnMsgDpc != NULL);
983
984         /* Call to bus driver to handle interrupt */
985         vmbus_drv_obj->OnMsgDpc(&vmbus_drv_obj->Base);
986
987         DPRINT_EXIT(VMBUS_DRV);
988 }
989
990 /*++
991
992 Name:   vmbus_msg_dpc()
993
994 Desc:   Tasklet routine to handle hypervisor events
995
996 --*/
997 static void vmbus_event_dpc(unsigned long data)
998 {
999         VMBUS_DRIVER_OBJECT* vmbus_drv_obj = (VMBUS_DRIVER_OBJECT*)data;
1000
1001         DPRINT_ENTER(VMBUS_DRV);
1002
1003         ASSERT(vmbus_drv_obj->OnEventDpc != NULL);
1004
1005         /* Call to bus driver to handle interrupt */
1006         vmbus_drv_obj->OnEventDpc(&vmbus_drv_obj->Base);
1007
1008         DPRINT_EXIT(VMBUS_DRV);
1009 }
1010
1011 /*++
1012
1013 Name:   vmbus_msg_dpc()
1014
1015 Desc:   ISR routine
1016
1017 --*/
1018 static irqreturn_t vmbus_isr(int irq, void* dev_id)
1019 {
1020         int ret=0;
1021         VMBUS_DRIVER_OBJECT* vmbus_driver_obj = &g_vmbus_drv.drv_obj;
1022
1023         DPRINT_ENTER(VMBUS_DRV);
1024
1025         ASSERT(vmbus_driver_obj->OnIsr != NULL);
1026
1027         /* Call to bus driver to handle interrupt */
1028         ret = vmbus_driver_obj->OnIsr(&vmbus_driver_obj->Base);
1029
1030         /* Schedules a dpc if necessary */
1031         if (ret > 0)
1032         {
1033                 if (test_bit(0, (unsigned long*)&ret))
1034                 {
1035                         tasklet_schedule(&g_vmbus_drv.msg_dpc);
1036                 }
1037
1038                 if (test_bit(1, (unsigned long*)&ret))
1039                 {
1040                         tasklet_schedule(&g_vmbus_drv.event_dpc);
1041                 }
1042
1043                 DPRINT_EXIT(VMBUS_DRV);
1044                 return IRQ_HANDLED;
1045         }
1046         else
1047         {
1048                 DPRINT_EXIT(VMBUS_DRV);
1049                 return IRQ_NONE;
1050         }
1051 }
1052
1053 MODULE_LICENSE("GPL");
1054
1055
1056 /*++
1057
1058 Name:   vmbus_init()
1059
1060 Desc:   Main vmbus driver entry routine
1061
1062 --*/
1063 static int __init vmbus_init(void)
1064 {
1065         int ret=0;
1066
1067         DPRINT_ENTER(VMBUS_DRV);
1068
1069         DPRINT_INFO(VMBUS_DRV,
1070                 "Vmbus initializing.... current log level 0x%x (%x,%x)",
1071                 vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
1072 /* Todo: it is used for loglevel, to be ported to new kernel. */
1073
1074         ret = vmbus_bus_init(VmbusInitialize);
1075
1076         DPRINT_EXIT(VMBUS_DRV);
1077         return ret;
1078 }
1079
1080
1081
1082 /*++
1083
1084 Name:   vmbus_init()
1085
1086 Desc:   Main vmbus driver exit routine
1087
1088 --*/
1089 static void __exit vmbus_exit(void)
1090 {
1091         DPRINT_ENTER(VMBUS_DRV);
1092
1093         vmbus_bus_exit();
1094 /* Todo: it is used for loglevel, to be ported to new kernel. */
1095         DPRINT_EXIT(VMBUS_DRV);
1096
1097         return;
1098 }
1099
1100 module_param(vmbus_irq, int, S_IRUGO);
1101 module_param(vmbus_loglevel, int, S_IRUGO);
1102
1103 module_init(vmbus_init);
1104 module_exit(vmbus_exit);
1105 /* eof */