remove print cmd
[kernel/swap-modules.git] / driver / device_driver.c
1 ////////////////////////////////////////////////////////////////////////////////////
2 //
3 //      FILE:           device_driver.c
4 //
5 //      DESCRIPTION:
6 //      This file is C source for SWAP driver.
7 //
8 //      SEE ALSO:       device_driver.h
9 //      AUTHOR:         L.Komkov, S.Dianov, S.Grekhov, A.Gerenkov
10 //      COMPANY NAME:   Samsung Research Center in Moscow
11 //      DEPT NAME:      Advanced Software Group
12 //      CREATED:        2008.02.15
13 //      VERSION:        1.0
14 //      REVISION DATE:  2008.12.03
15 //
16 ////////////////////////////////////////////////////////////////////////////////////
17
18 #include "module.h"
19 #include "device_driver.h"      // device driver
20 #include "handlers_core.h"
21 #include <linux/notifier.h>
22 #include "sspt/sspt_procs.h"
23
24 #ifdef OVERHEAD_DEBUG
25 extern unsigned long swap_sum_time;
26 extern unsigned long swap_sum_hit;
27 #endif
28
29
30 extern unsigned long imi_sum_time;
31 extern unsigned long imi_sum_hit;
32
33
34 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
35 static BLOCKING_NOTIFIER_HEAD(swap_notifier_list);
36 #endif
37 pid_t gl_nNotifyTgid;
38 EXPORT_SYMBOL_GPL(gl_nNotifyTgid);
39
40 DECLARE_WAIT_QUEUE_HEAD (notification_waiters_queue);
41 volatile unsigned notification_count;
42
43 static int device_mmap (struct file *filp, struct vm_area_struct *vma);
44 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
45 static int device_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
46 #else
47 static long device_ioctl (struct file *file, unsigned int cmd, unsigned long arg);
48 #endif
49 static int device_open(struct inode *, struct file *);
50 static int device_release(struct inode *, struct file *);
51 static ssize_t device_read(struct file *, char *, size_t, loff_t *);
52 static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
53
54 static int gl_nDeviceOpened = 0;
55 static struct file_operations device_fops = {
56         .owner = THIS_MODULE,
57         .mmap = device_mmap,
58 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
59         .ioctl = device_ioctl,
60 #else
61         .unlocked_ioctl = device_ioctl,
62 #endif
63         .read = device_read,
64         .write = device_write,
65         .open = device_open,
66         .release = device_release
67 };
68
69 typedef void (* dbi_module_callback)();
70
71 int device_init (void)
72 {
73         int nReserved = 0;
74         nReserved = register_chrdev(0, device_name, &device_fops);
75         if(nReserved < 0)
76         {
77                 unregister_chrdev(nReserved, device_name);
78                 EPRINTF("Cannot register character device!");
79                 return -1;
80         }
81         EPRINTF("New device node with major number [%d], was created\n", nReserved);
82         device_major = nReserved;
83         return 0;
84 }
85
86 void device_down (void)
87 {
88         unregister_chrdev(device_major, device_name);
89 }
90
91 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
92 void swap_register_notify (struct notifier_block *nb)
93 {
94         blocking_notifier_chain_register(&swap_notifier_list, nb);
95 }
96 EXPORT_SYMBOL_GPL(swap_register_notify);
97
98 void swap_unregister_notify (struct notifier_block *nb)
99 {
100         blocking_notifier_chain_unregister(&swap_notifier_list, nb);
101 }
102 EXPORT_SYMBOL_GPL(swap_unregister_notify);
103 #endif
104
105 void notify_user (event_id_t event_id)
106 {
107         ec_info.events_counters[event_id] += 1;
108
109         if (EVENT_EC_PROBE_RECORD == event_id)
110         {
111                 // EC_PROBE_RECORD events happen to often. To reduce overhead user
112                 // space will be notified only once per each EVENTS_AGGREGATION_USEC
113                 static uint64_t timestamp_usec = 0;
114
115                 uint64_t current_usec;
116                 uint64_t delta_usec;
117
118                 struct timeval tv;
119
120                 do_gettimeofday (&tv);
121                 current_usec = 1000000ULL * (unsigned) tv.tv_sec + (unsigned) tv.tv_usec;
122
123                 if (current_usec < timestamp_usec)
124                 {
125                         // Note: time from do_gettimeofday() may go backward
126                         EPRINTF ("current_usec=%llu timestamp_usec=%llu", current_usec, timestamp_usec);
127                 }
128                 else
129                 {
130                         delta_usec = current_usec - timestamp_usec;
131                         if (EVENTS_AGGREGATION_USEC > delta_usec)
132                         {
133                                 // wait the time left
134 #if defined(__DEBUG)
135                                 unsigned UNUSED left_usec = EVENTS_AGGREGATION_USEC - delta_usec;
136 #endif /* defined(__DEBUG) */
137                                 return; // supress notification
138                         }
139                 }
140                 timestamp_usec = current_usec;  // remember new time for the future use
141         } else if (EVENT_EC_START_CONDITION_SEEN == event_id) {
142                 return;         // supress notification
143         } else if (EVENT_EC_STOP_CONDITION_SEEN == event_id) {
144                 return;         // supress notification
145         }
146
147         ++notification_count;
148         wake_up_interruptible (&notification_waiters_queue);
149 }
150
151 static int device_mmap (struct file *filp UNUSED, struct vm_area_struct *vma)
152 {
153         if(!p_buffer) {
154                 EPRINTF("Null pointer to buffer!");
155                 return -1;
156         }
157         return remap_vmalloc_range (vma, p_buffer, 0);
158 }
159
160 static int device_open(struct inode *inode, struct file *file)
161 {
162         /*if (gl_nDeviceOpened)
163                 return -EBUSY;*/
164         gl_nDeviceOpened++;
165         // TODO
166         try_module_get(THIS_MODULE);
167         return 0;
168 }
169
170 static int device_release(struct inode *inode, struct file *file)
171 {
172         gl_nDeviceOpened--;
173         module_put(THIS_MODULE);
174         return 0;
175 }
176
177 static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
178 {
179         EPRINTF("Operation <<read>> not supported!");
180         return -1;
181 }
182
183 static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
184 {
185         EPRINTF("Operation <<write>> not supported!");
186         return -1;
187 }
188
189 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
190 static int device_ioctl (struct inode *inode UNUSED, struct file *file UNUSED, unsigned int cmd, unsigned long arg)
191 #else
192 static long device_ioctl (struct file *file UNUSED, unsigned int cmd, unsigned long arg)
193 #endif
194 {
195         unsigned long spinlock_flags = 0L;
196         int result = -1;
197 //      DPRINTF("Command=%d", cmd);
198         switch (cmd)
199         {
200         case EC_IOCTL_SET_EC_MODE:
201                 {
202                         ioctl_general_t param;
203                         unsigned long nIgnoredBytes = 0;
204                         memset(&param, '0', sizeof(ioctl_general_t));
205                         nIgnoredBytes = copy_from_user (&param, (void*)arg, sizeof(ioctl_general_t));
206                         if (nIgnoredBytes > 0) {
207                                 result = -1;
208                                 break;
209                         }
210                         if(SetECMode(param.m_unsignedLong) == -1) {
211                                 result = -1;
212                                 break;
213                         }
214                         result = 0;
215                         DPRINTF("Set EC Mode = %lu", param.m_unsignedLong);
216                         break;
217                 }
218         case EC_IOCTL_GET_EC_MODE:
219                 {
220                         ioctl_general_t param;
221                         unsigned long nIgnoredBytes = 0;
222                         memset(&param, '0', sizeof(ioctl_general_t));
223                         param.m_unsignedLong = GetECMode();
224                         nIgnoredBytes = copy_to_user ((void*)arg, &param, sizeof (ioctl_general_t));
225                         if (nIgnoredBytes > 0) {
226                                 result = -1;
227                                 break;
228                         }
229                         result = 0;
230 //                      DPRINTF("Get EC Mode = %lu", param.m_unsignedLong);  // Frequent call
231                         break;
232                 }
233         case EC_IOCTL_SET_BUFFER_SIZE:
234                 {
235                         ioctl_general_t param;
236                         unsigned long nIgnoredBytes = 0;
237                         memset(&param, '0', sizeof(ioctl_general_t));
238                         nIgnoredBytes = copy_from_user (&param, (void*)arg, sizeof(ioctl_general_t));
239                         if (nIgnoredBytes > 0) {
240                                 result = -1;
241                                 break;
242                         }
243                         if (SetBufferSize(param.m_unsignedLong) == -1) {
244                                 result = -1;
245                                 break;
246                         }
247                         result = 0;
248                         DPRINTF("Set Buffer Size = %lu", param.m_unsignedLong);
249                         break;
250                 }
251         case EC_IOCTL_GET_BUFFER_SIZE:
252                 {
253                         ioctl_general_t param;
254                         unsigned long nIgnoredBytes = 0;
255                         memset(&param, '0', sizeof(ioctl_general_t));
256                         param.m_unsignedLong = GetBufferSize();
257                         nIgnoredBytes = copy_to_user ((void*)arg, &param, sizeof (ioctl_general_t));
258                         if (nIgnoredBytes > 0) {
259                                 result = -1;
260                                 break;
261                         }
262                         result = 0;
263                         DPRINTF("Get Buffer Size = %lu", param.m_unsignedLong);
264                         break;
265                 }
266         case EC_IOCTL_RESET_BUFFER:
267                 {
268                         if (ResetBuffer() == -1) {
269                                 result = -1;
270                                 break;
271                         }
272                         result = 0;
273                         DPRINTF("Reset Buffer");
274                         break;
275                 }
276         case EC_IOCTL_GET_EC_INFO:
277                 {
278                         if (copy_ec_info_to_user_space ((ec_info_t *) arg) != 0) {
279                                 result = -1;
280                                 break;
281                         }
282                         result = 0;
283 //                      DPRINTF("Get Buffer Status"); // Frequent call
284                         break;
285                 }
286         case EC_IOCTL_CONSUME_BUFFER:
287                 {
288                         static ec_info_t ec_info_copy;
289                         int nIgnoredBytes = 0;
290
291                         nIgnoredBytes = copy_from_user (&ec_info_copy, (ec_info_t *) arg, sizeof (ec_info_t));
292                         if(nIgnoredBytes > 0)
293                         {
294                                 EPRINTF ("copy_from_user(%08X,%08X)=%d", (unsigned) arg, (unsigned) &ec_info_copy, nIgnoredBytes);
295                                 result = -1;
296                                 break;
297                         }
298
299                         spin_lock_irqsave (&ec_spinlock, spinlock_flags);
300
301                         // Original buffer
302                         if(ec_info.after_last > ec_info.first) {
303                                 ec_info.buffer_effect = ec_info.buffer_size;
304                         }
305                         if (ec_info.after_last == ec_info.buffer_effect) {
306                                  ec_info.first = 0;
307                         } else {
308                                  ec_info.first = ec_info_copy.after_last;
309                         }
310                         ec_info.trace_size = ec_info.trace_size - ec_info_copy.trace_size;
311
312                         spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
313                         result = 0;
314 //                      DPRINTF("Consume Buffer"); // Frequent call
315                         break;
316                 }
317         case EC_IOCTL_ADD_PROBE:
318                 {
319                         unsigned long addr = arg;
320                         result = add_probe(addr);
321
322                         break;
323                 }
324         //@AGv: remove_probe expects probe address instead of name
325         /*case EC_IOCTL_REMOVE_PROBE:
326                 {
327                         char *probe_name = (char *) arg;
328                         result = remove_probe (probe_name);
329
330                         break;
331                 }*/
332         case EC_IOCTL_SET_APPDEPS:
333         {
334                 size_t size;
335                 result = copy_from_user(&size, (void *)arg, sizeof(size_t));
336                 if (result) {
337                         EPRINTF("Cannot copy deps size!");
338                         result = -1;
339                         break;
340                 }
341                 DPRINTF("Deps size has been copied (%d)", size);
342
343                 if (size == 0) {
344                         DPRINTF("Deps are size of 0");
345                         break;
346                 }
347
348                 deps = vmalloc(size);
349                 if (deps == NULL) {
350                         EPRINTF("Cannot alloc mem for deps!");
351                         result = -1;
352                         break;
353                 }
354                 DPRINTF("Mem for deps has been allocated");
355
356                 result = copy_from_user(deps, (void *)arg, size);
357                 if (result) {
358                         EPRINTF("Cannot copy deps!");
359                         result = -1;
360                         break;
361                 }
362                 DPRINTF("Deps has been copied successfully");
363
364                 break;
365         }
366         case EC_IOCTL_SET_PID:
367         {
368                 unsigned int _pid;
369
370                 result = copy_from_user(&_pid, (void *)arg, sizeof(unsigned int));
371                 if (result) {
372                         EPRINTF("Cannot copy pid!");
373                         result = -1;
374                         break;
375                 }
376
377                 inst_pid = _pid;
378
379                 DPRINTF("EC_IOCTL_SET_PID pid:%d", inst_pid);
380
381                 break;
382         }
383         case EC_IOCTL_SET_PROFILEBUNDLE:
384         {
385                 size_t size;
386
387                 result = copy_from_user(&size, (void *)arg, sizeof(size_t));
388                 if (result) {
389                         EPRINTF("Cannot copy bundle size!");
390                         result = -1;
391                         break;
392                 }
393                 DPRINTF("Bundle size has been copied");
394
395                 bundle = vmalloc(size);
396                 if (bundle == NULL) {
397                         EPRINTF("Cannot alloc mem for bundle!");
398                         result = -1;
399                         break;
400                 }
401                 DPRINTF("Mem for bundle has been alloced");
402
403                 result = copy_from_user(bundle, (void *)arg, size);
404                 if (result) {
405                         EPRINTF("Cannot copy bundle!");
406                         result = -1;
407                         break;
408                 }
409                 DPRINTF("Bundle has been copied successfully");
410
411                 if (link_bundle() == -1) {
412                         EPRINTF("Cannot link profile bundle!");
413                         result = -1;
414                         break;
415                 }
416
417                 break;
418         }
419         case EC_IOCTL_RESET_PROBES:
420                 {
421                         result = reset_probes();
422
423                         break;
424                 }
425         case EC_IOCTL_UPDATE_CONDS:
426                 {
427                         int args_cnt, i;
428                         struct cond *c, *c_tmp, *p_cond;
429                         unsigned char *p_data;
430                         int err;
431                         result = 0;
432                         err = copy_from_user(&args_cnt, (void *)arg, sizeof(int));
433                         if (err) {
434                                 result = -1;
435                                 break;
436                         }
437                         /* first, delete all the conds */
438                         list_for_each_entry_safe(c, c_tmp, &cond_list.list, list) {
439                                 list_del(&c->list);
440                                 kfree(c);
441                         }
442                         /* second, add new conds */
443                         p_data = (unsigned char *)(arg + sizeof(int));
444                         for (i = 0; i < args_cnt; i++) {
445                                 p_cond = kmalloc(sizeof(struct cond), GFP_KERNEL);
446                                 if (!p_cond) {
447                                         DPRINTF("Cannot alloc cond!");
448                                         result = -1;
449                                         break;
450                                 }
451                                 err = copy_from_user(&p_cond->tmpl, p_data, sizeof(struct event_tmpl));
452                                 if (err) {
453                                         DPRINTF("Cannot copy cond from user!");
454                                         result = -1;
455                                         break;
456                                 }
457                                 p_cond->applied = 0;
458                                 list_add(&(p_cond->list), &(cond_list.list));
459                                 p_data += sizeof(struct event_tmpl);
460                         }
461                         break;
462                 }
463         case EC_IOCTL_ATTACH:
464                 {
465                         unsigned long dbi_flags;
466                         struct dbi_modules_handlers *local_mh;
467                         struct dbi_modules_handlers_info *local_mhi;
468                         int j;
469                         dbi_module_callback dmc_start;
470
471                         // call "start"-callback for all modules according module priority
472                         local_mh = get_dbi_modules_handlers();
473                         spin_lock_irqsave(&local_mh->lock, dbi_flags);
474                         for (j = 0; j <= MAX_PRIORITY; j++) {
475                                 list_for_each_entry_rcu(local_mhi, &local_mh->modules_handlers, dbi_list_head) {
476                                         if (local_mhi->dbi_module_priority_start == j) {
477                                                 if (local_mhi->dbi_module_callback_start != NULL) {
478                                                         printk("Started module callback (start) %s\n", local_mhi->dbi_module->name);
479                                                         dmc_start = (dbi_module_callback )local_mhi->dbi_module_callback_start;
480                                                         dmc_start();
481                                                 }
482                                         }
483                                 }
484                         }
485                         spin_unlock_irqrestore(&local_mh->lock, dbi_flags);
486
487                         result = ec_user_attach ();
488 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
489                         DPRINTF("EC_IOCTL_ATTACH calling notification chain");
490                         blocking_notifier_call_chain(&swap_notifier_list, EC_IOCTL_ATTACH, (void*)NULL);
491 #endif
492                         DPRINTF("Attach Probes");
493                         break;
494                 }
495         case EC_IOCTL_ACTIVATE:
496                 result = ec_user_activate ();
497                 DPRINTF("Activate Probes");
498                 break;
499         case EC_IOCTL_STOP_AND_DETACH:
500         {
501                 unsigned long nIgnoredBytes = 0;
502                 unsigned long dbi_flags;
503                 struct dbi_modules_handlers *local_mh;
504                 struct dbi_modules_handlers_info *local_mhi;
505                 unsigned int local_module_refcount = 0;
506                 int j;
507                 dbi_module_callback dmc_stop;
508
509 #ifdef OVERHEAD_DEBUG
510                 printk("\nswap_sum_time = %ld in kprobe_handler()\n", swap_sum_time);
511                 printk("swap_sum_hit = %ld in kprobe_handler()\n", swap_sum_hit);
512                 swap_sum_time = 0;
513                 swap_sum_hit = 0;
514 #endif
515
516                 printk("\n### imi_sum_time = %ld in install_mapped_ips()\n", imi_sum_time);
517                 printk("### imi_sum_hit = %ld in install_mapped_ips()\n", imi_sum_hit);
518
519                 if (imi_sum_hit != 0) {
520                         printk("### time = %ld in install_mapped_ips()\n", imi_sum_time/imi_sum_hit);
521                 }
522
523                 imi_sum_time = 0;
524                 imi_sum_hit = 0;
525
526                 local_mh = get_dbi_modules_handlers();
527                 if(ec_user_stop() != 0) {
528                         result = -1;
529                         goto sad_cleanup;
530                 }
531                 nIgnoredBytes = copy_ec_info_to_user_space ((ec_info_t*)arg);
532                 if(nIgnoredBytes > 0) {
533                         result = -1;
534                         goto sad_cleanup;
535                 }
536
537                 sspt_procs_free_all();
538
539                 vfree(bundle);
540                 result = 0;
541                 DPRINTF("Stop and Detach Probes");
542 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
543                 DPRINTF("EC_IOCTL_STOP_AND_DETACH calling notification chain");
544                 blocking_notifier_call_chain(&swap_notifier_list, EC_IOCTL_STOP_AND_DETACH, (void*)&gl_nNotifyTgid);
545 #endif
546                 // call "stop"-callback for all modules according module priority
547                 spin_lock_irqsave(&local_mh->lock, dbi_flags);
548                 for (j = 0; j <= MAX_PRIORITY; j++) {
549                         list_for_each_entry_rcu(local_mhi, &local_mh->modules_handlers, dbi_list_head) {
550                                 if (local_mhi->dbi_module_priority_stop == j) {
551                                         if (local_mhi->dbi_module_callback_stop != NULL) {
552                                                 printk("Started module callback (stop) %s\n", local_mhi->dbi_module->name);
553                                                 dmc_stop = (dbi_module_callback )local_mhi->dbi_module_callback_stop;
554                                                 dmc_stop();
555                                         }
556                                 }
557                         }
558                 }
559                 spin_unlock_irqrestore(&local_mh->lock, dbi_flags);
560 sad_cleanup:
561                 spin_lock_irqsave(&local_mh->lock, dbi_flags);
562                 list_for_each_entry_rcu(local_mhi, &local_mh->modules_handlers, dbi_list_head) {
563                         local_module_refcount = module_refcount(local_mhi->dbi_module);
564                         if (local_module_refcount == 1) {
565                                 module_put(local_mhi->dbi_module);
566                         }
567                         else if (local_module_refcount > 1) {
568                                 printk("local_module_refcount too much - force set refcount to zero\n");
569                                 while (local_module_refcount--)
570                                         module_put(local_mhi->dbi_module);
571                         }
572                 }
573                 spin_unlock_irqrestore(&local_mh->lock, dbi_flags);
574                 break;
575         }
576         case EC_IOCTL_WAIT_NOTIFICATION:
577                 {
578                         static ec_info_t ec_info_copy;
579
580                         ioctl_wait_notification_t ioctl_args;
581
582                         result = copy_from_user (&ioctl_args, (void *) arg, sizeof (ioctl_args));
583                         if (result)
584                         {
585                                 result = -1;
586                                 break;
587                         }
588
589                         result = wait_event_interruptible (notification_waiters_queue, ioctl_args.notification_count != notification_count);
590                         if (result)
591                         {
592                                 result = -EINTR;        // woken by signal (ERESTARTSYS 512)
593                                 break;
594                         }
595
596                         ioctl_args.notification_count = notification_count;
597
598                         result = copy_to_user ((void *) arg, &ioctl_args, sizeof (ioctl_args));
599                         if (result)
600                         {
601                                 result = -1;
602                                 break;
603                         }
604
605                         // FIXME: synchronization is necessary here (ec_info must be locked).
606                         // ENTER_CRITICAL_SECTION
607                         memcpy (&ec_info_copy, &ec_info, sizeof (ec_info_copy));
608                         // LEAVE_CRITICAL_SECTION
609
610                         result = copy_to_user ((void *) ioctl_args.p_ec_info, &ec_info_copy, sizeof (ec_info_t));
611                         if (result)
612                         {
613                                 EPRINTF ("copy_to_user(%08X,%08X)=%d", (unsigned) ioctl_args.p_ec_info, (unsigned) &ec_info_copy, result);
614                                 result = -1;
615                                 break;
616                         }
617                         DPRINTF("Wake up");
618                         break;
619                 }
620         case EC_IOCTL_US_EVENT:
621                 {
622                         ioctl_us_event_t ioctl_args;
623                         result = copy_from_user (&ioctl_args, (void *) arg, sizeof (ioctl_args));
624                         if (result)
625                         {
626                                 result = -1;
627                                 EPRINTF ("copy_from_user() failure");
628                         }
629                         else
630                         {
631                                 if(ioctl_args.len == 0){
632                                         result = -EINVAL;
633                                         EPRINTF ("invalid event length!");
634                                 }
635                                 else {
636                                         char *buf = kmalloc(ioctl_args.len, GFP_KERNEL);
637                                         if(!buf){
638                                                 result = -ENOMEM;
639                                                 EPRINTF ("failed to alloc mem for event!");
640                                         }
641                                         else {
642                                                 result = copy_from_user (buf, (void *) ioctl_args.data, ioctl_args.len);
643                                                 if (result){
644                                                         result = -1;
645                                                         EPRINTF ("failed to copy event from user space!");
646                                                 }
647                                                 else
648                                                         result = put_us_event(buf, ioctl_args.len);
649                                                 kfree(buf);
650                                         }
651                                 }
652                         }
653 //                      DPRINTF("User Space Event"); // Frequent call
654                         break;
655                 }
656
657         case EC_IOCTL_SET_EVENT_MASK:
658                 {
659                         int mask;
660                         result = copy_from_user (&mask, (void *) arg, sizeof (mask));
661                         if (result)
662                         {
663                                 result = -EFAULT;
664                                 break;
665                         }
666
667                         result = set_event_mask (mask);
668                         if (result)
669                         {
670                                 break;
671                         }
672                         DPRINTF("Set Event Mask = %d", mask);
673                         break;
674                 }
675
676         case EC_IOCTL_GET_EVENT_MASK:
677                 {
678                         int mask = 0;
679                         result = get_event_mask(&mask);
680                         if (result)
681                         {
682                                 result = -EFAULT;
683                         }
684                         result = copy_to_user ((void *) arg, &mask, sizeof (mask));
685                         if (result)
686                         {
687                                 result = -EFAULT;
688                         }
689                         DPRINTF("Get Event Mask = %d", mask);
690                         break;
691                 }
692
693         case EC_IOCTL_SET_PREDEF_UPROBES:
694                 {
695                         result = -1;
696                         break;
697
698                         ioctl_predef_uprobes_info_t data;
699                         result = copy_from_user (&data, (void *) arg, sizeof (data));
700                         if (result)
701                         {
702                                 result = -EFAULT;
703                                 break;
704                         }
705
706                         result = set_predef_uprobes (&data);
707                         if (result)
708                         {
709                                 break;
710                         }
711                         DPRINTF("Set Predefined User Space Probes");
712                         break;
713                 }
714
715         case EC_IOCTL_GET_PREDEF_UPROBES:
716                 {
717 //                      result = 0;
718 //                      break;
719
720                         result = get_predef_uprobes((ioctl_predef_uprobes_info_t *)arg);
721                         if (result)
722                         {
723                                 result = -EFAULT;
724                         }
725                         DPRINTF("Get Predefined User Space Probes");
726                         break;
727                 }
728
729         case EC_IOCTL_GET_PREDEF_UPROBES_SIZE:
730                 {
731                         int size = 0;
732                         result = get_predef_uprobes_size(&size);
733                         if (result)
734                         {
735                                 result = -EFAULT;
736                         }
737                         result = copy_to_user ((void *) arg, &size, sizeof (size));
738                         if (result)
739                         {
740                                 result = -EFAULT;
741                         }
742                         DPRINTF("Get Size of Predefined User Space Probes");
743                         break;
744                 }
745
746         default:
747                 EPRINTF ("Unknown driver command = %u", cmd);
748                 result = -EINVAL;
749                 break;
750         }
751
752         return result;
753 }