Remove unused directories and files in video_in_hal
[staging/basesystem.git] / kernel-module-evklib / evk_lib.c
1 /*
2  * drivers/agl/evk_lib.c
3  *
4  * Event library (kernel space part)
5  *
6  * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License published
10  * by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #include <generated/autoconf.h>
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/version.h>
26 #include <linux/kernel.h>
27 #include <linux/slab.h>
28 #include <linux/sched.h>
29 #include <linux/wait.h>
30 #include <linux/poll.h>
31 #include <linux/list.h>
32 #include <asm/uaccess.h>
33 #include <linux/errno.h>
34 #include <linux/vmalloc.h>
35
36 #include <linux/proc_fs.h>
37 #include <linux/seq_file.h>
38
39 #include <linux/device.h>
40 #include <linux/cdev.h>
41
42 #ifndef STANDARD_INT_DEFINITIONS
43 #define STANDARD_INT_DEFINITIONS
44 typedef __u8 UINT8;
45 typedef __u16 UINT16;
46 typedef __u32 UINT32;
47 typedef __u64 UINT64;
48 typedef __s8 INT8;
49 typedef __s16 INT16;
50 typedef __s32 INT32;
51 typedef __s64 INT64;
52 #endif /* !STANDARD_INT_DEFINITIONS */
53
54 #define ENABLE_PROC_FS 1
55
56 #include <agldd/evk_lib.h>
57
58 /** @addtogroup EV_in */
59 /** @{ */
60 /** In Linux2.4, list_for_each_entry is not provided, so it is prepared by self (in 2.6)
61  */
62 #ifdef list_for_each_entry
63 #define __LINUX_26_OR_HIGHER
64 #endif
65
66 #ifndef __LINUX_26_OR_HIGHER /* linux v2.4 */
67
68 #define list_for_each_entry(pos, head, member)                          \
69         for (pos = list_entry((head)->next, typeof(*pos), member),      \
70                      prefetch(pos->member.next);                        \
71              &pos->member != (head);                                    \
72              pos = list_entry(pos->member.next, typeof(*pos), member),  \
73                      prefetch(pos->member.next))
74
75 #define list_for_each_entry_safe(pos, n, head, member)                  \
76         for (pos = list_entry((head)->next, typeof(*pos), member),      \
77                 n = list_entry(pos->member.next, typeof(*pos), member); \
78              &pos->member != (head);                                    \
79              pos = n, n = list_entry(n->member.next, typeof(*n), member))
80
81 #else /* linux v2.6 */
82
83 #include <linux/jiffies.h>
84
85 #endif /* linux v2.6 */
86
87 #define EVK_assert(cond, mesg) \
88   if (!(cond)) { \
89     printk(KERN_ALERT "[EVK]ASSERT(pid:%d): " #cond " at %s:%d; " \
90       #mesg "\n", current->pid, __FILE__, __LINE__); \
91     do {} while(1); \
92   }
93
94 #define EVK_BUG(mesg) \
95     printk(KERN_ALERT "[EVK]BUG: " mesg); \
96     do {} while(1);
97
98 #if 0
99 #define EVK_info0(s) printk(KERN_ALERT "[EVK]INFO: " s)
100 #define EVK_info1(s, t) printk(KERN_ALERT "[EVK]INFO: " s, t)
101 #else
102 #define EVK_info0(s)
103 #define EVK_info1(s, t)
104 #endif
105
106 static int devmajor = EVK_DEV_MAJOR;
107 static int devminor = 0;
108 static int nrdevs = 1;
109 static struct cdev cdev;
110 static struct class *pClass;
111
112 DEFINE_SEMAPHORE(evk_mtx);
113 static int down_pid;
114 static int down_line;
115 #define EVK_mutex_lock() { \
116   down(&evk_mtx); \
117   down_pid = current->pid; \
118   down_line = __LINE__; \
119 }
120 #define EVK_mutex_unlock() (up(&evk_mtx))
121
122 #ifdef EVK_USE_KMALLOC
123 #define evk_malloc(s) kmalloc((s), GFP_KERNEL)
124 #define evk_free kfree
125 #else // use vmalloc (this is the default)
126 #define evk_malloc(s) vmalloc((s))
127 #define evk_free vfree
128 #endif
129
130 enum {
131   evk_mem_user = 0,
132   evk_mem_kernel,
133 };
134
135 enum {
136   evk_enum_flag,
137   evk_enum_flag64,
138   evk_enum_queue,
139 };
140
141 #define GET_USER_OR_KERNEL(to, from) \
142 ({ \
143   int err; \
144   if (mem == evk_mem_user) { \
145     err = __get_user((to), &(from)); \
146   } else { \
147     (to) = (from); \
148     err = 0; \
149   } \
150   err; \
151 })
152
153 #define PUT_USER_OR_KERNEL(value, to) \
154 ({ \
155   int err; \
156   if (mem == evk_mem_user) { \
157     err = __put_user((value), &(to)); \
158   } else { \
159     (to) = (value); \
160     err = 0; \
161   } \
162   err; \
163 })
164
165
166 /** @brief Common part of the flag structure and message queue structure */
167 #define EVK_COMMON_QUEUE_ELEMS                                          \
168   struct list_head list;        /**< List structure */                  \
169   wait_queue_head_t wq_head;    /**< Wait_queue of a process waiting for a queue */\
170   EV_ID queueID;                /**< Flag ID/Queue ID */                \
171   UINT32 seq_num;               /**< Order of event arrival */          \
172   pid_t read_pid;               /**< Read process ID */ \
173   pid_t pid;                    /**< Owning process ID */
174
175 /** @brief Common part of the flag structure and message queue structure */
176 struct common_queue {
177   EVK_COMMON_QUEUE_ELEMS
178 };
179
180 /** @brief Flag structure */
181 struct flag {
182   EVK_COMMON_QUEUE_ELEMS
183   UINT32 value;/**< Flags value */
184 };
185 #define EVK_PFLAG(queue)        ((struct flag*)queue)
186
187 /** @brief 64-bit flag structure */
188 struct flag64 {
189   EVK_COMMON_QUEUE_ELEMS
190   UINT64 value;/**< Flags value */
191 };
192 #define EVK_PFLAG64(queue)      ((struct flag64*)queue)
193
194 /** @brief Message queue structure */
195 struct message_queue {
196   EVK_COMMON_QUEUE_ELEMS
197   UINT8 type;/**< Type */
198   UINT8 length;/**< Queue length */
199   UINT8 num;/**< Number of messages stored */
200   UINT8 readptr;/**< Next read position(0~length-1) */
201   UINT32 max_bytes;/**< -Maximum bytes per message */
202   UINT8 *message;/**< Message storage area (ring buffer) */
203 };
204 #define EVK_PQUEUE(queue)       ((struct message_queue*)queue)
205
206 /** @brief Number of bytes to allocate per message
207  *
208  * This function allocates an area to store the number of bytes actually stored, the time of occurrence, 
209  * and the senderInfo, in addition to the number of bytes specified by max_bytes.
210  */
211 #define EVK_message_block_size(max_bytes) (sizeof(UINT32) * 3 + (max_bytes))
212
213 #define HASH_KEY 15
214
215 /** @brief Maximum number of flags used by all systems */
216 #define EVK_MAX_FLAGS 48
217 /** @brief Maximum number of 64-bit flags used by all systems */
218 #define EVK_MAX_FLAG64S 4
219 /** @brief Maximum number of message event queues used by all systems */
220 /* M1SP BM3547 MESSAGE_QUEUES 128->144 */
221 /* M9AT BM2066 MESSAGE_QUEUES 144->218 */
222 #define EVK_MAX_MESSAGE_QUEUES 224
223
224 /** @brief Allocate flag structure statically */
225 static struct flag _flag_pool[EVK_MAX_FLAGS];
226 /** @brief Statically allocates a 64-bit flag structure */
227 static struct flag64 _flag64_pool[EVK_MAX_FLAG64S];
228 /** @brief Beginning of the list of unused flags */
229 static LIST_HEAD(flag_pool);
230 /** @brief Beginning of the list of unused 64-bit flags */
231 static LIST_HEAD(flag64_pool);
232
233 /** @brief Allocate message queue structure statically */
234 static struct message_queue _message_queue_pool[EVK_MAX_MESSAGE_QUEUES];
235 /** @brief Top of the list of unused message queues */
236 static LIST_HEAD(message_queue_pool);
237
238 /** @brief List of Flags/Message Queues in Use
239  *
240  * Connects the usage flag/message queue to a list for each hash value obtained from the ID.
241  * The hash value is the remainder of the ID divided by HASH_KEY.
242  */
243 static struct list_head queue_entry[HASH_KEY];
244
245 /** @brief Sequence number to use during automatic ID assignment */
246 static EV_ID sequence_id = 0;
247
248 /** @brief Number to be assigned in order of occurrence of the event */
249 static UINT32 sequence_number = 0;
250
251 unsigned int
252 evk_get_queue_entry(struct list_head **entries)
253 {
254   if (entries) {
255     *entries = queue_entry;
256     return HASH_KEY;
257   }
258   return 0;
259 }
260
261 static __inline__ int
262 calc_hash(UINT32 val)
263 {
264   return val % HASH_KEY;
265 }
266
267 static __inline__
268 struct flag *
269 alloc_flag(void)
270 {
271   struct flag *queue;
272   //EVK_assert(!list_empty(&flag_pool), "flag pool empty");
273   if (list_empty(&flag_pool)) {
274         printk("%s ERROR: flag pool empty\n", __func__);
275         return NULL;
276   }
277   queue = (struct flag *)flag_pool.next;
278   list_del_init(&(queue->list));
279   return queue;
280 }
281
282 static __inline__
283 struct flag64 *
284 alloc_flag64(void)
285 {
286   struct flag64 *queue;
287   //EVK_assert(!list_empty(&flag64_pool), "flag64 pool empty");
288   if (list_empty(&flag64_pool)) {
289         printk("%s ERROR: flag64 pool empty\n", __func__);
290         return NULL;
291   }
292   queue = (struct flag64 *)flag64_pool.next;
293   list_del_init(&(queue->list));
294   return queue;
295 }
296
297 static __inline__ void
298 free_flag(struct flag *queue)
299 {
300   list_add((struct list_head *)queue, &flag_pool);
301 }
302
303 static __inline__ void
304 free_flag64(struct flag64 *queue)
305 {
306   list_add((struct list_head *)queue, &flag64_pool);
307 }
308
309 static __inline__
310 struct message_queue *
311 alloc_message_queue(void)
312 {
313   struct message_queue *queue;
314   //EVK_assert(!list_empty(&message_queue_pool), "message queue pool empty");
315   if (list_empty(&message_queue_pool)) {
316         printk("%s ERROR: message queue pool empty\n", __func__);
317         return NULL;
318   }
319   queue = (struct message_queue *)message_queue_pool.next;
320   list_del_init(&(queue->list));
321   queue->message = NULL;
322   return queue;
323 }
324
325 static __inline__ void
326 free_message_queue(struct message_queue *queue)
327 {
328   if (queue->message != NULL) {
329     evk_free(queue->message);
330     queue->message = NULL;
331   }
332   list_add((struct list_head *)queue, &message_queue_pool);
333 }
334
335 static __inline__
336 struct common_queue *
337 find_queue_entry(EV_ID queueID)
338 {
339   struct list_head *list;
340   struct common_queue *queue;
341   int hash = calc_hash(queueID);
342   list = &(queue_entry[hash]);
343   list_for_each_entry(queue, list, list) {      /* pgr0060 */ /* pgr0039 */
344     if (queue->queueID == queueID) {
345       return queue;
346     }
347   }
348   return NULL;
349 }
350
351 static __inline__ void
352 attach_queue_entry(struct common_queue *queue, EV_ID queueID)
353 {
354   int hash = calc_hash(queueID);
355   list_add_tail((struct list_head *)queue, &(queue_entry[hash]));
356 }
357
358 static __inline__ void
359 detach_queue_entry(struct common_queue *queue)
360 {
361   list_del_init((struct list_head *)queue);
362 }
363
364 static __inline__ void
365 init_common_queue(struct common_queue *queue, EV_ID queueID)
366 {
367   queue->queueID = queueID;
368   queue->pid = current->pid;
369   queue->read_pid = 0;
370   init_waitqueue_head(&(queue->wq_head));
371 }
372
373 static __inline__ void
374 evk_init_flag(struct flag *queue, EV_ID queueID)
375 {
376   init_common_queue((struct common_queue *)queue, queueID);
377   queue->value = 0;
378 }
379
380 static __inline__ void
381 evk_init_flag64(struct flag64 *queue, EV_ID queueID)
382 {
383   init_common_queue((struct common_queue *)queue, queueID);
384   queue->value = 0;
385 }
386
387 static __inline__ int
388 evk_init_message_queue(struct message_queue *queue, EV_ID queueID,
389                          UINT8 length, UINT32 max_bytes, UINT8 type)
390 {
391   init_common_queue((struct common_queue *)queue, queueID);
392   queue->type = type;
393   queue->length = length;
394   queue->max_bytes = max_bytes;
395   queue->num = 0;
396   queue->readptr = 0;
397   EVK_assert(queue->message == NULL, "message buffer was not freed");
398   queue->message = evk_malloc(length * EVK_message_block_size(max_bytes));
399   EVK_assert(queue->message != NULL, "can't alloc message buffer");
400   return 0;
401 }
402
403 static void
404 __list_queues(void)
405 {
406   struct list_head *list;
407   struct common_queue *queue;
408   int i;
409   for(i = 0 ; i < HASH_KEY ; i++) {
410     list = &(queue_entry[i]);
411     if (!list_empty(list)) {
412       printk(KERN_ALERT "%d->", i);
413       list_for_each_entry(queue, list, list) {  /* pgr0060 */ /* pgr0039 */
414         printk("%x[%x] ", queue->queueID, queue->seq_num);
415       }
416       printk("\n");
417     }
418   }
419 }
420
421 static int
422 evk_destroy_queue(EV_ID queueID)
423 {
424   struct common_queue *queue;
425   int err = 0;
426   EVK_info1("flag destroy %x\n", queueID);
427
428   EVK_mutex_lock(); /*************************************/
429   queue = find_queue_entry(queueID);
430   if (queue == NULL) {
431     err = -ENOENT;
432     goto finish;
433   }
434
435   detach_queue_entry(queue);
436
437   /* wake up processes before destruction */
438   wake_up_interruptible(&(queue->wq_head));
439
440   init_common_queue(queue, EV_INVALID_ID);
441
442   if (EV_ID_IS_FLAG(queueID)) {
443     free_flag((struct flag *)queue);
444   } else if (EV_ID_IS_FLAG64(queueID)) {
445     free_flag64((struct flag64 *)queue);
446   } else if (EV_ID_IS_QUEUE(queueID)) {
447     free_message_queue((struct message_queue *)queue);
448   }
449   //__list_queues();
450  finish:
451   EVK_mutex_unlock(); /*************************************/
452   return err;
453 }
454
455 static int
456 evk_open(struct inode *inode, struct file *file)
457 {
458   // Recording of current and measures not to be read or deleted from others are required. */
459   file->private_data = (void *)EV_INVALID_ID;
460   return 0;
461 }
462
463 static int
464 evk_close(struct inode *inode, struct file *file)
465 {
466   if (EV_ID_IS_VALID((EV_ID)file->private_data)) {
467     evk_destroy_queue((EV_ID)file->private_data);
468   }
469   file->private_data = (void *)EV_INVALID_ID;
470   return 0;
471 }
472
473 static int
474 evk_create_flag(EV_ID queueID)
475 {
476   struct flag *queue;
477   int err = 0;
478   EVK_info1("flag create %x\n", queueID);
479
480   EVK_mutex_lock(); /*************************************/
481
482   queue = (struct flag *)find_queue_entry(queueID);
483   if (queue != NULL) {
484     err = -EEXIST;
485     goto finish;
486   }
487
488   queue = alloc_flag();
489   if (queue == NULL) {
490     err = -ENOMEM;
491     goto finish;
492   }
493
494   evk_init_flag(queue, queueID);
495   attach_queue_entry((struct common_queue *)queue, queueID);
496
497   //__list_queues();
498  finish:
499   EVK_mutex_unlock(); /***********************************/
500   return err;
501 }
502
503 static int
504 evk_create_flag64(EV_ID queueID)
505 {
506   struct flag64 *queue;
507   int err = 0;
508   EVK_info1("flag64 create %x\n", queueID);
509
510   EVK_mutex_lock(); /*************************************/
511
512   queue = (struct flag64 *)find_queue_entry(queueID);
513   if (queue != NULL) {
514     err = -EEXIST;
515     goto finish;
516   }
517
518   queue = alloc_flag64();
519   if (queue == NULL) {
520     err = -ENOMEM;
521     goto finish;
522   }
523
524   evk_init_flag64(queue, queueID);
525   attach_queue_entry((struct common_queue *)queue, queueID);
526
527   //__list_queues();
528  finish:
529   EVK_mutex_unlock(); /***********************************/
530   return err;
531 }
532
533 static int
534 evk_create_message_queue(EV_ID queueID, UINT8 length,
535                            UINT32 max_bytes, EV_Message_Queue_Type type)
536 {
537   struct message_queue *queue;
538   int err;
539   EVK_info1("message create %x\n", queueID);
540
541   err = 0;
542
543   EVK_mutex_lock(); /*************************************/
544
545   queue = (struct message_queue *)find_queue_entry(queueID);
546   if (queue != NULL) {
547     err = -EEXIST;
548     goto finish;
549   }
550
551   queue = alloc_message_queue();
552   if (queue == NULL) {
553     err = -ENOMEM;
554     goto finish;
555   }
556
557   err = evk_init_message_queue(queue, queueID, length, max_bytes, type);
558   if (err == 0) {
559     attach_queue_entry((struct common_queue *)queue, queueID);
560   } else {
561     free_message_queue(queue);
562   }
563
564   //__list_queues();
565  finish:
566   EVK_mutex_unlock(); /***********************************/
567   return err;
568 }
569
570 static EV_ID
571 get_seq_id(void)
572 {
573   EV_ID ret;
574   sequence_id++;
575   if ((sequence_id & EV_RESERVED_BIT) != 0) {/* round to 1 */
576     sequence_id = 1;
577     EVK_info0("auto ID rounded\n");
578   }
579   ret = sequence_id;
580   return ret;
581 }
582
583 static int
584 evk_alloc_flagID(EV_ID *queueID)
585 {
586   EV_ID seq_id;
587
588   EVK_mutex_lock(); /*************************************/
589   do {
590     seq_id = get_seq_id();
591     seq_id |= (EV_ID_BIT | EV_FLAG_BIT | EV_AUTO_ID_BIT);
592   } while(find_queue_entry(seq_id) != NULL);
593   EVK_mutex_unlock(); /*************************************/
594
595   *queueID = seq_id;
596   return 0;
597 }
598
599 static int
600 evk_alloc_flag64ID(EV_ID *queueID)
601 {
602   EV_ID seq_id;
603
604   EVK_mutex_lock(); /*************************************/
605   do {
606     seq_id = get_seq_id();
607     seq_id |= (EV_ID_BIT | EV_FLAG64_BIT | EV_AUTO_ID_BIT);
608   } while(find_queue_entry(seq_id) != NULL);
609   EVK_mutex_unlock(); /*************************************/
610
611   *queueID = seq_id;
612   return 0;
613 }
614
615 static int
616 evk_alloc_queueID(EV_ID *queueID)
617 {
618   EV_ID seq_id;
619
620   EVK_mutex_lock(); /*************************************/
621   do {
622     seq_id = get_seq_id();
623     seq_id |= (EV_ID_BIT | EV_QUEUE_BIT | EV_AUTO_ID_BIT);
624   } while(find_queue_entry(seq_id) != NULL);
625   EVK_mutex_unlock(); /*************************************/
626
627   *queueID = seq_id;
628   return 0;
629 }
630
631 static int
632 evk_store_flag(EV_Flag *ev, int mem)
633 {
634   struct flag *queue;
635   int ret = 0;
636   EV_ID flagID;
637   UINT32 bits;
638
639   if (GET_USER_OR_KERNEL(flagID, ev->flagID)) /* pgr0039 */
640     return -EFAULT;
641   if (GET_USER_OR_KERNEL(bits, ev->bits)) /* pgr0039 */
642     return -EFAULT;
643
644   EVK_mutex_lock(); /*************************************/
645
646   queue = (struct flag *)find_queue_entry(flagID);      /* pgr0000 */
647   if (queue == NULL) {
648     EVK_info1("set_flag: No such ID %x\n", flagID);
649     ret = -ENOENT;
650     goto finish;
651   }
652
653   if (queue->value == 0) {
654     queue->seq_num = sequence_number++;
655   }
656   queue->value |= bits; /* pgr0000 */
657
658   wake_up_interruptible(&(queue->wq_head));
659
660  finish:
661   EVK_mutex_unlock(); /***********************************/
662   return ret;
663 }
664
665 static int
666 evk_store_flag64(EV_Flag64 *ev, int mem)
667 {
668   struct flag64 *queue;
669   int ret = 0;
670   EV_ID flagID;
671   UINT64 bits = 0;
672
673   if (GET_USER_OR_KERNEL(flagID, ev->flagID)) /* pgr0039 */
674     return -EFAULT;
675   //GET_USER_OR_KERNEL(bits, ev->bits); /* pgr0039 */
676   if (mem == evk_mem_user) {
677     if (copy_from_user(&bits, &(ev->bits), sizeof(bits)))
678       return -EFAULT;
679   } else {
680     bits = ev->bits;
681   }
682
683   EVK_mutex_lock(); /*************************************/
684
685   queue = (struct flag64 *)find_queue_entry(flagID);    /* pgr0000 */
686   if (queue == NULL) {
687     EVK_info1("set_flag64: No such ID %x\n", flagID);
688     ret = -ENOENT;
689     goto finish;
690   }
691
692   if (queue->value == 0) {
693     queue->seq_num = sequence_number++;
694   }
695   queue->value |= bits; /* pgr0000 */
696
697   wake_up_interruptible(&(queue->wq_head));
698
699  finish:
700   EVK_mutex_unlock(); /***********************************/
701   return ret;
702 }
703
704 static int
705 evk_store_message(EV_Message *ev, int mem)
706 {
707   struct message_queue *queue;
708   UINT8 *ptr;
709   UINT8 writeptr;
710   int ret = 0;
711   EV_ID queueID;
712   UINT32 length, senderInfo, seq;
713
714   if (GET_USER_OR_KERNEL(queueID, ev->queueID)) /* pgr0039 */
715     return -EFAULT;
716   if (GET_USER_OR_KERNEL(length, ev->length)) /* pgr0039 */
717     return -EFAULT;
718   if (GET_USER_OR_KERNEL(senderInfo, ev->senderInfo)) /* pgr0039 */
719     return -EFAULT;
720
721   EVK_mutex_lock(); /*************************************/
722
723   queue = (struct message_queue *)find_queue_entry(queueID);    /* pgr0000 */
724   if (queue == NULL) {
725     EVK_info1("store_message: No such queueID %x\n", queueID);
726     ret = -ENOENT;
727     goto finish;
728   }
729
730   if (length > queue->max_bytes) {      /* pgr0000 */
731     EVK_info0("store_message: message is too long for the queue");
732     ret = -EINVAL;
733     goto finish;
734   }
735
736   if (queue->num == queue->length) {
737
738     switch(queue->type) {
739     case EV_MESSAGE_QUEUE_TYPE_BUSY:
740       EVK_info1("store_message: queue %x BUSY\n", queueID);
741       ret = -EBUSY;
742       goto finish;
743       break;
744
745     case EV_MESSAGE_QUEUE_TYPE_FIFO:
746       queue->readptr++;
747       queue->readptr %= queue->length;
748       queue->num--;
749       break;
750
751     case EV_MESSAGE_QUEUE_TYPE_REPLACE:
752       queue->num--;
753       break;
754
755     default:
756       EVK_BUG("internal error in store_message\n");
757       ret = -EINVAL;
758       goto finish;
759       break;
760     }
761   }
762
763   writeptr = (queue->readptr + queue->num) % queue->length;
764   ptr = queue->message + writeptr * EVK_message_block_size(queue->max_bytes);
765
766   memcpy(ptr, &length, sizeof(length));
767   ptr += sizeof(length);
768   memcpy(ptr, &senderInfo, sizeof(senderInfo));
769   ptr += sizeof(senderInfo);
770   seq = sequence_number++;
771   memcpy(ptr, &seq, sizeof(seq));
772   ptr += sizeof(seq);
773
774   if (queue->num == 0) {
775     queue->seq_num = seq;
776   }
777   queue->num++;
778
779   if (mem == evk_mem_user) {
780     if (copy_from_user(ptr, ev->message, length)) {
781       ret = -EFAULT;
782       goto finish;
783     }
784   } else {
785     memcpy(ptr, ev->message, length);
786   }
787
788   wake_up_interruptible(&(queue->wq_head));
789
790  finish:
791   EVK_mutex_unlock(); /***********************************/
792
793   return ret;
794 }
795
796 static int
797 evk_set_poll(struct file *filp, EV_ID queueID)
798 {
799   struct common_queue *queue;
800   int err = 0;
801
802   EVK_mutex_lock(); /*************************************/
803
804   queue = find_queue_entry(queueID);
805   if (queue == NULL) {
806     EVK_info1("set_poll: ID %x not found.\n", queueID);
807     err = -ENOENT;
808     goto finish;
809   }
810
811   filp->private_data = (void *)queueID;
812
813  finish:
814   EVK_mutex_unlock(); /*************************************/
815   return err;
816 }
817
818 static int
819 evk_get_flag_event(EV_Event *ev, int peek_only, int wait, int mem)
820 {
821   struct flag *queue, *queue2;
822   int err = 0;
823   int found = 0;
824   EV_ID flagID;
825
826   if (GET_USER_OR_KERNEL(flagID, ev->u.flag.flagID)) /* pgr0039 */
827     return -EFAULT;
828
829  retry:
830
831   queue = (struct flag *)find_queue_entry(flagID);      /* pgr0000 */
832   if (queue == NULL) {
833     EVK_info1("get_flag: No such flag %x\n", flagID);
834     err = -ENOENT;
835     goto finish;
836   }
837
838   if (queue->value != 0) {
839     UINT32 bits;
840
841     if (GET_USER_OR_KERNEL(bits, ev->u.flag.bits)) { /* pgr0039 */
842       err = -EFAULT;
843       goto finish;
844     }
845
846     if (bits == 0 || ((bits & queue->value) != 0)) {    /* pgr0000 */
847
848       if (PUT_USER_OR_KERNEL(EV_EVENT_Flag, ev->type)) { /* pgr0039 */
849         err = -EFAULT;
850         goto finish;
851       }
852       if (PUT_USER_OR_KERNEL(queue->value, ev->u.flag.bits)) { /* pgr0039 */
853         err = -EFAULT;
854         goto finish;
855       }
856       found = 1;
857
858       queue->read_pid = current->pid;
859       if (peek_only) {
860         ;
861       } else {
862         queue->value = 0;
863       }
864     }
865   }
866  finish:
867
868   if (queue != NULL && wait != 0 && found == 0) {
869     int wait_ret;
870     EVK_mutex_unlock(); /*************************************/
871
872     wait_ret
873       = wait_event_interruptible(queue->wq_head,
874                                  ((queue2 = (struct flag *)find_queue_entry(flagID)) == NULL
875                                   || queue2->value != 0));
876
877     EVK_mutex_lock(); /*************************************/
878
879     if (wait_ret != 0) {
880       EVK_info1("Interrupted while waiting for flag %x\n", flagID);
881       err = -EINTR;
882     } else if (queue2 == NULL) { /* pgr0039 */
883       EVK_info1("flag %x was destroyed while waiting for it\n", flagID);
884       err = -ENOENT;
885     } else {
886       goto retry;
887     }
888   }
889   return err;
890 }
891
892 static int
893 evk_get_flag64_event(EV_Event *ev, int peek_only, int wait, int mem)
894 {
895   struct flag64 *queue, *queue2;
896   int err = 0;
897   int found = 0;
898   EV_ID flagID;
899
900   if (GET_USER_OR_KERNEL(flagID, ev->u.flag64.flagID)) /* pgr0039 */
901     return -EFAULT;
902
903  retry:
904
905   queue = (struct flag64 *)find_queue_entry(flagID);    /* pgr0000 */
906   if (queue == NULL) {
907     EVK_info1("get_flag64: No such flag %x\n", flagID);
908     err = -ENOENT;
909     goto finish;
910   }
911
912   if (queue->value != 0) {
913     UINT64 bits = 0;
914
915     //GET_USER_OR_KERNEL(bits, ev->u.flag64.bits); /* pgr0039 */
916     if (mem == evk_mem_user) {
917       if (copy_from_user(&bits, &(ev->u.flag64.bits), sizeof(bits))) {
918         err = -EFAULT;
919         goto finish;
920       }
921     } else {
922       bits = ev->u.flag64.bits;
923     }
924
925     if (bits == 0 || ((bits & queue->value) != 0)) {    /* pgr0000 */
926
927       if (PUT_USER_OR_KERNEL(EV_EVENT_Flag64, ev->type)) { /* pgr0039 */
928         err = -EFAULT;
929         goto finish;
930       }
931       if (PUT_USER_OR_KERNEL(queue->value, ev->u.flag64.bits)) { /* pgr0039 */
932         err = -EFAULT;
933         goto finish;
934       }
935       found = 1;
936
937       queue->read_pid = current->pid;
938       if (peek_only) {
939         ;
940       } else {
941         queue->value = 0;
942       }
943     }
944   }
945  finish:
946
947   if (queue != NULL && wait != 0 && found == 0) {
948     int wait_ret;
949     EVK_mutex_unlock(); /*************************************/
950
951     wait_ret
952       = wait_event_interruptible(queue->wq_head,
953                                  ((queue2 = (struct flag64 *)find_queue_entry(flagID)) == NULL
954                                   || queue2->value != 0));
955
956     EVK_mutex_lock(); /*************************************/
957
958     if (wait_ret != 0) {
959       EVK_info1("Interrupted while waiting for flag %x\n", flagID);
960       err = -EINTR;
961     } else if (queue2 == NULL) { /* pgr0039 */
962       EVK_info1("flag %x was destroyed while waiting for it\n", flagID);
963       err = -ENOENT;
964     } else {
965       goto retry;
966     }
967   }
968   return err;
969 }
970
971 static __inline__ void
972 remove_message_event(struct message_queue *queue, UINT8 removeptr)
973 {
974   UINT8 *ptr;
975   int i, from, to;
976   UINT8 *pFrom, *pTo;
977   UINT32 size;
978   int offset;
979
980   queue->num--;
981   offset = (int)removeptr - (int)(queue->readptr);
982
983   if (offset == 0) {/* To remove the head of the queue, advance the queue by one readptr only */
984     queue->readptr++;
985     queue->readptr %= queue->length;
986
987     if (queue->num > 0) {
988       /* Reset the occurrence time of the first message in the queue to the occurrence time of the queue. */
989       ptr = (queue->message
990              + queue->readptr * EVK_message_block_size(queue->max_bytes));
991       ptr += sizeof(UINT32) * 2;
992       memcpy(&(queue->seq_num), ptr, sizeof(UINT32));
993     }
994     return;
995   }
996   if (offset < 0) {
997     offset += queue->length;
998   }
999   if (offset == queue->num) {/* Do nothing to delete the end of the queue */
1000     return;
1001   }
1002
1003   /* To delete a message in the middle of the queue, pack the following messages. */
1004   to = removeptr;
1005   size = EVK_message_block_size(queue->max_bytes);
1006
1007   for(i = 0 ; i < queue->num - offset ; i++, to++) {
1008     to %= queue->length;
1009     from = (to + 1) % queue->length;
1010     pFrom = queue->message + from * size;
1011     pTo = queue->message + to * size;
1012     memcpy(pTo, pFrom, size);
1013   }
1014 }
1015
1016 static int
1017 evk_get_message_event(EV_Event *ev, int peek_only, int wait, int mem)
1018 {
1019   struct message_queue *queue, *queue2;
1020   int err = 0;
1021   EV_ID queueID;
1022   UINT8 num;
1023   UINT8 readptr;
1024   UINT8 i, *ptr;
1025   int matched = 0;
1026
1027   if (GET_USER_OR_KERNEL(queueID, ev->u.message.queueID)) /* pgr0039 */
1028     return -EFAULT;
1029
1030  retry:
1031   queue = (struct message_queue *)find_queue_entry(queueID);    /* pgr0000 */
1032   if (queue == NULL) {
1033     EVK_info1("get_message: No such queue %x\n", queueID);
1034     err = -ENOENT;
1035     goto finish;
1036   }
1037
1038   num = queue->num;
1039   readptr = queue->readptr;
1040   for(i = 0 ; i < num ; i++, readptr = (readptr + 1) % queue->length) {
1041     UINT32 size, senderInfo, seq;
1042     UINT32 length, q_senderInfo;
1043
1044     ptr = (queue->message
1045            + readptr * EVK_message_block_size(queue->max_bytes));
1046
1047     memcpy(&size, ptr, sizeof(size));
1048     ptr += sizeof(size);
1049     memcpy(&senderInfo, ptr, sizeof(senderInfo));
1050     ptr += sizeof(senderInfo);
1051     memcpy(&seq, ptr, sizeof(seq));
1052     ptr += sizeof(seq);
1053
1054     if (GET_USER_OR_KERNEL(length, ev->u.message.length)) { /* pgr0039 */
1055       err = -EFAULT;
1056       goto finish;
1057     }
1058     if (GET_USER_OR_KERNEL(q_senderInfo, ev->u.message.senderInfo)) { /* pgr0039 */
1059       err = -EFAULT;
1060       goto finish;
1061     }
1062
1063     if (q_senderInfo == 0 && length == 0) {     /* pgr0000 */
1064       matched = 1;
1065     } else if (q_senderInfo != 0 && q_senderInfo == senderInfo) {
1066       matched = 1;
1067     } else if (length > 0 && size >= length) {  /* pgr0000 */
1068
1069       if (mem == evk_mem_user) {
1070         void *compbytes;
1071         compbytes = evk_malloc(length);
1072         if (compbytes != NULL) {
1073           if (copy_from_user(compbytes, &(ev->u.message.message), length)) {
1074             err = -EFAULT;
1075             evk_free(compbytes);
1076             goto finish;
1077           }
1078           if (memcmp(ptr, compbytes, length) == 0) {
1079             matched = 1;
1080           }
1081           evk_free(compbytes);
1082         }
1083       } else {
1084         if (memcmp(ptr, ev->u.message.message, length) == 0) {
1085           matched = 1;
1086         }
1087       }
1088     }
1089
1090     if (matched) {
1091
1092       if (PUT_USER_OR_KERNEL(EV_EVENT_Message, ev->type)) { /* pgr0039 */
1093         err = -EFAULT;
1094         goto finish;
1095       }
1096       if (PUT_USER_OR_KERNEL(size, ev->u.message.length)) { /* pgr0039 */
1097         err = -EFAULT;
1098         goto finish;
1099       }
1100       if (PUT_USER_OR_KERNEL(senderInfo, ev->u.message.senderInfo)) { /* pgr0039 */
1101         err = -EFAULT;
1102         goto finish;
1103       }
1104       if (mem == evk_mem_user) {
1105         if (copy_to_user(ev->u.message.message, ptr, size)) {
1106           err = -EFAULT;
1107           goto finish;
1108         }
1109       } else {
1110         memcpy(ev->u.message.message, ptr, size);
1111       }
1112
1113       queue->read_pid = current->pid;
1114       if (peek_only) {
1115         ;
1116       } else {
1117         remove_message_event(queue, readptr);
1118       }
1119       goto finish;
1120     }
1121   }
1122
1123  finish:
1124
1125   if (queue != NULL && wait != 0 && matched == 0) {
1126     int wait_ret;
1127     EVK_mutex_unlock(); /*************************************/
1128     wait_ret
1129       = wait_event_interruptible(queue->wq_head,
1130                                  ((queue2 = (struct message_queue *)find_queue_entry(queueID))==NULL
1131                                   || queue2->num > 0));
1132
1133     EVK_mutex_lock(); /*************************************/
1134
1135     if (wait_ret != 0) {
1136       EVK_info1("Interrupted while waiting for queue %x\n", queueID);
1137       err = -EINTR;
1138     } else if (queue2 == NULL) { /* pgr0039 */
1139       EVK_info1("queue %x was destroyed while waiting for it\n", queueID);
1140       err = -ENOENT;
1141     } else {
1142       goto retry;
1143     }
1144   }
1145
1146   return err;
1147 }
1148
1149 static int
1150 evk_get_event(EV_Event *ev, int peek_only, int wait, int mem)
1151 {
1152   EV_Type type;
1153   int ret = -EINVAL;
1154
1155   if (GET_USER_OR_KERNEL(type, ev->type)) /* pgr0039 */
1156     return -EFAULT;
1157   if (PUT_USER_OR_KERNEL(EV_EVENT_None, ev->type)) /* pgr0039 */
1158     return -EFAULT;
1159
1160   switch(type) {        /* pgr0000 */
1161   case EV_EVENT_Flag:
1162     EVK_mutex_lock(); /*************************************/
1163     ret = evk_get_flag_event(ev, peek_only, wait, mem);
1164     EVK_mutex_unlock(); /*************************************/
1165     break;
1166
1167   case EV_EVENT_Flag64:
1168     EVK_mutex_lock(); /*************************************/
1169     ret = evk_get_flag64_event(ev, peek_only, wait, mem);
1170     EVK_mutex_unlock(); /*************************************/
1171     break;
1172
1173   case EV_EVENT_Message:
1174     EVK_mutex_lock(); /*************************************/
1175     ret = evk_get_message_event(ev, peek_only, wait, mem);
1176     EVK_mutex_unlock(); /*************************************/
1177     break;
1178
1179   default:
1180     break;
1181   }
1182   return ret;
1183 }
1184
1185 static int
1186 evk_get_next_event(EVK_Next_Event_Query *query /* user */, int peek_only)
1187 {
1188   EV_ID *ids;
1189   int i, num, ret, first, found;
1190   struct common_queue *queue;
1191   UINT32 seq_oldest = 0;
1192
1193   ids = (EV_ID *)kmalloc( (sizeof(EV_ID)*EV_MAX_IDS_IN_PROCESS), GFP_KERNEL );
1194   if( ids == NULL ){
1195     return -ENOMEM;
1196   }
1197
1198   if (__get_user(num, &(query->num))) { /* pgr0039 */
1199     ret = -EFAULT;
1200     goto finish0;
1201   }
1202   if (copy_from_user(&ids[0], query->ids, num * sizeof(EV_ID))) { /* pgr0039 */
1203     ret = -EFAULT;
1204     goto finish0;
1205   }
1206   if (__put_user(EV_EVENT_None, &(query->ev.type))) { /* pgr0039 */
1207     ret = -EFAULT;
1208     goto finish0;
1209   }
1210
1211   ret = 0;
1212   first = 1;
1213   found = -1;
1214
1215   EVK_mutex_lock(); /*************************************/
1216
1217   for(i = 0 ; i < num /* pgr0039 */ ; i++) {
1218     queue = find_queue_entry(ids[i]);
1219     if (queue != NULL) {/* Have the specified queue ID */
1220       if ((EV_ID_IS_FLAG(ids[i])
1221            && ((struct flag *)queue)->value != 0)
1222           || (EV_ID_IS_FLAG64(ids[i])
1223            && ((struct flag64 *)queue)->value != 0)
1224           || (EV_ID_IS_QUEUE(ids[i])
1225               && ((struct message_queue *)queue)->num > 0)) {/*There are events.*/
1226         /* Compare with time_before macros for round 0 */
1227         if (first || time_before((unsigned long)queue->seq_num, /* pgr0006 */ /* pgr0039 */
1228                                  (unsigned long)seq_oldest)) {
1229           first = 0;
1230           seq_oldest = queue->seq_num;
1231           found = i;
1232         }
1233       }
1234     }
1235   }
1236
1237   if (found >= 0) {
1238     if (EV_ID_IS_FLAG(ids[found])) {
1239       if (__put_user(ids[found], &(query->ev.u.flag.flagID))) { /* pgr0039 */
1240         ret = -EFAULT;
1241         goto finish1;
1242       }
1243       ret = evk_get_flag_event(&(query->ev), peek_only, 0, evk_mem_user);
1244     } else if (EV_ID_IS_FLAG64(ids[found])) {
1245       if (__put_user(ids[found], &(query->ev.u.flag64.flagID))) { /* pgr0039 */
1246         ret = -EFAULT;
1247         goto finish1;
1248       }
1249       ret = evk_get_flag64_event(&(query->ev), peek_only, 0, evk_mem_user);
1250     } else if (EV_ID_IS_QUEUE(ids[found])) {
1251       if (__put_user(ids[found], &(query->ev.u.message.queueID))) { /* pgr0039 */
1252         ret = -EFAULT;
1253         goto finish1;
1254       }
1255       ret = evk_get_message_event(&(query->ev), peek_only, 0, evk_mem_user);
1256     }
1257   }
1258
1259  finish1:
1260   EVK_mutex_unlock(); /*************************************/
1261  finish0:
1262   kfree(ids);
1263   return ret;
1264 }
1265
1266 static long
1267 evk_ioctl(struct file *filp, unsigned int cmd,
1268             unsigned long arg)
1269 {
1270   EVK_Message_Queue_Request mesq;
1271   int peek_only, wait;
1272   EV_ID queueID;
1273   int ret = -EINVAL;
1274
1275   //lock_kernel();
1276
1277   switch(cmd) {
1278   case EVK_IOC_CREATE_FLAG:
1279     queueID = (EV_ID)arg;
1280     ret = evk_create_flag(queueID);
1281     break;
1282
1283   case EVK_IOC_CREATE_FLAG64:
1284     queueID = (EV_ID)arg;
1285     ret = evk_create_flag64(queueID);
1286     break;
1287
1288   case EVK_IOC_CREATE_MESSAGE_QUEUE:
1289 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
1290     if (access_ok(arg, sizeof(mesq))) { /* pgr0039 */
1291 #else
1292      if (access_ok(VERIFY_READ, arg, sizeof(mesq))) { /* pgr0039 */
1293 #endif
1294       if (copy_from_user(&mesq, (EV_Flag *)arg, sizeof(mesq))) {
1295         ret = -EFAULT;
1296         break;
1297       }
1298
1299       ret = evk_create_message_queue(mesq.queueID, mesq.length,
1300                                      mesq.max_bytes, mesq.type);
1301     } else {
1302       ret = -EFAULT;
1303     }
1304     break;
1305
1306   case EVK_IOC_ALLOC_FLAG_ID:
1307 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
1308     if (access_ok(arg, sizeof(queueID))) { /* pgr0039 */
1309 #else
1310     if (access_ok(VERIFY_WRITE, arg, sizeof(queueID))) { /* pgr0039 */
1311 #endif
1312       evk_alloc_flagID(&queueID);
1313       if (put_user(queueID, (EV_ID *)arg)) { /* pgr0039 */
1314         ret = -EFAULT;
1315         break;
1316       }
1317       ret = 0;
1318     } else {
1319       ret = -EFAULT;
1320     }
1321     break;
1322
1323   case EVK_IOC_ALLOC_FLAG64_ID:
1324 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
1325     if (access_ok(arg, sizeof(queueID))) { /* pgr0039 */
1326 #else
1327     if (access_ok(VERIFY_WRITE, arg, sizeof(queueID))) { /* pgr0039 */
1328 #endif
1329       evk_alloc_flag64ID(&queueID);
1330       if (put_user(queueID, (EV_ID *)arg)) { /* pgr0039 */
1331         ret = -EFAULT;
1332         break;
1333       }
1334       ret = 0;
1335     } else {
1336       ret = -EFAULT;
1337     }
1338     break;
1339
1340   case EVK_IOC_ALLOC_QUEUE_ID:
1341 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
1342     if (access_ok(arg, sizeof(queueID))) { /* pgr0039 */
1343 #else
1344     if (access_ok(VERIFY_WRITE, arg, sizeof(queueID))) { /* pgr0039 */
1345 #endif
1346       evk_alloc_queueID(&queueID);
1347       if (put_user(queueID, (EV_ID *)arg)) { /* pgr0039 */
1348         ret = -EFAULT;
1349         break;
1350       }
1351       ret = 0;
1352     } else {
1353       ret = -EFAULT;
1354     }
1355     break;
1356
1357   case EVK_IOC_DESTROY_QUEUE:
1358     queueID = (EV_ID)arg;
1359     ret = evk_destroy_queue(queueID);
1360     break;
1361
1362   case EVK_IOC_STORE_FLAG:
1363 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
1364     if (access_ok(arg, sizeof(EV_Flag))) { /* pgr0039 */
1365 #else
1366     if (access_ok(VERIFY_READ, arg, sizeof(EV_Flag))) { /* pgr0039 */
1367 #endif
1368       ret = evk_store_flag((EV_Flag *)arg, evk_mem_user);
1369     } else {
1370       ret = -EFAULT;
1371     }
1372     break;
1373
1374   case EVK_IOC_STORE_FLAG64:
1375 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
1376     if (access_ok(arg, sizeof(EV_Flag64))) { /* pgr0039 */
1377 #else
1378     if (access_ok(VERIFY_READ, arg, sizeof(EV_Flag64))) { /* pgr0039 */
1379 #endif
1380       ret = evk_store_flag64((EV_Flag64 *)arg, evk_mem_user);
1381     } else {
1382       ret = -EFAULT;
1383     }
1384     break;
1385
1386   case EVK_IOC_STORE_MESSAGE:
1387 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
1388     if (access_ok(arg, sizeof(EV_Message))) { /* pgr0039 */
1389 #else
1390     if (access_ok(VERIFY_READ, arg, sizeof(EV_Message))) { /* pgr0039 */
1391 #endif
1392       ret = evk_store_message((EV_Message *)arg, evk_mem_user);
1393     } else {
1394       ret = -EFAULT;
1395     }
1396     break;
1397
1398   case EVK_IOC_SET_POLL:
1399     queueID = (EV_ID)arg;
1400     ret = evk_set_poll(filp, queueID);
1401     break;
1402
1403   case EVK_IOC_PEEK_EVENT:
1404     peek_only = 1;
1405     wait = 0;
1406     goto get_event;
1407     break;
1408
1409   case EVK_IOC_WAIT_EVENT:
1410     peek_only = 0;
1411     wait = 1;
1412     goto get_event;
1413     break;
1414
1415   case EVK_IOC_GET_EVENT:
1416     peek_only = 0;
1417     wait = 0;
1418   get_event:
1419 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
1420     if (access_ok(arg, sizeof(EV_Event))) { /* pgr0039 */
1421 #else
1422     if (access_ok(VERIFY_WRITE, arg, sizeof(EV_Event))) { /* pgr0039 */
1423 #endif
1424       ret = evk_get_event((EV_Event *)arg, peek_only, wait, evk_mem_user);
1425     } else {
1426       ret = -EFAULT;
1427     }
1428     break;
1429
1430   case EVK_IOC_PEEK_NEXT_EVENT:
1431     peek_only = 1;
1432     goto get_next;
1433     break;
1434
1435   case EVK_IOC_GET_NEXT_EVENT:
1436     peek_only = 0;
1437   get_next:
1438 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
1439     if (access_ok(arg, sizeof(EVK_Next_Event_Query))) { /* pgr0039 */
1440 #else
1441     if (access_ok(VERIFY_WRITE, arg, sizeof(EVK_Next_Event_Query))) { /* pgr0039 */
1442 #endif
1443       ret = evk_get_next_event((EVK_Next_Event_Query *)arg, peek_only);
1444     } else {
1445       ret = -EFAULT;
1446     }
1447     break;
1448
1449   case EVK_IOC_DEBUG_LIST:
1450     __list_queues();
1451     //__list_message();
1452     ret = 0;
1453     break;
1454
1455   default:
1456     ret = -EINVAL;
1457     break;
1458   }
1459
1460   //unlock_kernel();
1461   return ret;
1462 }
1463
1464 static unsigned int
1465 evk_poll(struct file *filp, poll_table *wait)
1466 {
1467   unsigned int ret = 0;
1468   struct common_queue *queue;
1469
1470   EV_ID queueID = (EV_ID)(filp->private_data);
1471   // Returns errors without stopping at assert if queueID is invalid
1472   // (Troubleshooting for Continuous Printing)
1473   if (!EV_ID_IS_VALID(queueID)) {
1474     printk("evk_poll ERROR: invalid queueID=%x\n", queueID);
1475     return POLLERR|POLLHUP;
1476   }
1477   //EVK_assert(EV_ID_IS_VALID(queueID), "poll: flag/queueID not set");
1478
1479   EVK_mutex_lock();/*****************************************/
1480
1481   queue = find_queue_entry(queueID);
1482   if (queue == NULL) {
1483     EVK_info1("poll: No such flag/queueID %x\n", queueID);
1484     ret = POLLERR|POLLHUP;
1485     goto finish;
1486   }
1487
1488   poll_wait(filp, &(queue->wq_head), wait);
1489
1490   if (EV_ID_IS_FLAG(queueID)) {
1491     if (((struct flag *)queue)->value != 0) {
1492       ret = POLLIN;
1493     }
1494   } else if (EV_ID_IS_FLAG64(queueID)) {
1495     if (((struct flag64 *)queue)->value != 0) {
1496       ret = POLLIN;
1497     }
1498   } else {
1499     if (((struct message_queue *)queue)->num > 0) {
1500       ret = POLLIN;
1501     }
1502   }
1503
1504  finish:
1505   EVK_mutex_unlock(); /***************************************/
1506
1507   return ret;
1508 }
1509
1510 /** List of system call corresponding function registrations */
1511 static struct file_operations evk_fops = {
1512   .open           = evk_open,
1513   .release        = evk_close,
1514   .unlocked_ioctl = evk_ioctl,
1515   .poll           = evk_poll,
1516 };
1517
1518 #ifdef ENABLE_PROC_FS
1519 static int
1520 evk_procFS_show(struct seq_file *m, int mode)
1521 {
1522   int i, num;
1523   struct list_head *list, *entries;
1524   struct common_queue *queue;
1525
1526   seq_printf(m, "[ev library status ");
1527
1528   switch(mode) {
1529   case evk_enum_flag:
1530     seq_printf(m, "(flag)]\n");
1531     seq_printf(m, "PID      moduleID    flagID[hash]   value\n");
1532     break;
1533   case evk_enum_flag64:
1534     seq_printf(m, "(flag64)]\n");
1535     seq_printf(m, "PID      moduleID     flagID[hash]   value\n");
1536     break;
1537   case evk_enum_queue:
1538     seq_printf(m, "(queue)]\n");
1539     seq_printf(m, "PID      moduleID    queueID[hash]  maxbytes remain type\n");
1540     break;
1541   }
1542
1543   EVK_mutex_lock();
1544
1545   num = evk_get_queue_entry(&entries);
1546
1547   for (i = 0 ; i < num ; i++) {
1548     list = &(entries[i]);
1549     if (!list_empty(list)) {
1550       list_for_each_entry(queue, list, list) {
1551         if ((mode == evk_enum_flag && (!EV_ID_IS_FLAG(queue->queueID)))
1552             || (mode == evk_enum_flag64 && (!EV_ID_IS_FLAG64(queue->queueID)))
1553             || (mode == evk_enum_queue && (!EV_ID_IS_QUEUE(queue->queueID))))
1554         {
1555           continue;
1556         }
1557
1558         seq_printf(m, "%08d ", queue->pid);
1559         seq_printf(m, "%05d(%04x) ", ((queue->queueID & 0x00ffff00) >> 8), ((queue->queueID & 0x00ffff00) >> 8));
1560         seq_printf(m, "0x%08x[%2d] ", queue->queueID, calc_hash(queue->queueID));
1561
1562         switch(mode) {
1563         case evk_enum_flag:
1564           seq_printf(m, "0x%x", EVK_PFLAG(queue)->value);
1565           break;
1566
1567         case evk_enum_flag64:
1568           seq_printf(m, "0x%llx", EVK_PFLAG64(queue)->value);
1569           break;
1570
1571         case evk_enum_queue:
1572           seq_printf(m, "%04d %02d  ", EVK_PQUEUE(queue)->max_bytes, EVK_PQUEUE(queue)->length);
1573           seq_printf(m, "%02d     ", EVK_PQUEUE(queue)->num);
1574           seq_printf(m, "%d    ", EVK_PQUEUE(queue)->type);
1575           break;
1576         }
1577         seq_printf(m, "\n");
1578       }
1579     }
1580   }
1581
1582   EVK_mutex_unlock();
1583   return 0;
1584 }
1585
1586 static int
1587 evk_procFS_flag_show(struct seq_file *m, void *v)
1588 {
1589   return evk_procFS_show(m, evk_enum_flag);
1590 }
1591
1592 static int
1593 evk_procFS_flag64_show(struct seq_file *m, void *v)
1594 {
1595   return evk_procFS_show(m, evk_enum_flag64);
1596 }
1597
1598 static int
1599 evk_procFS_queue_show(struct seq_file *m, void *v)
1600 {
1601   return evk_procFS_show(m, evk_enum_queue);
1602 }
1603
1604 static int
1605 evk_procFS_flag_open(struct inode *inode, struct file *file)
1606 {
1607   return single_open(file, evk_procFS_flag_show, NULL);
1608 }
1609
1610 static int
1611 evk_procFS_flag64_open(struct inode *inode, struct file *file)
1612 {
1613   return single_open(file, evk_procFS_flag64_show, NULL);
1614 }
1615
1616 static int
1617 evk_procFS_queue_open(struct inode *inode, struct file *file)
1618 {
1619   return single_open(file, evk_procFS_queue_show, NULL);
1620 }
1621
1622 static struct file_operations evk_proc_flag_fops = {
1623   .owner   = THIS_MODULE,
1624   .open    = evk_procFS_flag_open,
1625   .read    = seq_read,
1626   .llseek  = seq_lseek,
1627   .release = single_release,
1628 };
1629
1630 static struct file_operations evk_proc_flag64_fops = {
1631   .owner   = THIS_MODULE,
1632   .open    = evk_procFS_flag64_open,
1633   .read    = seq_read,
1634   .llseek  = seq_lseek,
1635   .release = single_release,
1636 };
1637
1638 static struct file_operations evk_proc_queue_fops = {
1639   .owner   = THIS_MODULE,
1640   .open    = evk_procFS_queue_open,
1641   .read    = seq_read,
1642   .llseek  = seq_lseek,
1643   .release = single_release,
1644 };
1645 #endif /*ENABLE_PROC_FS*/
1646
1647 __init int
1648 EVK_init(void)
1649 {
1650   int err;
1651 #ifdef CONFIG_PROC_FS
1652 #ifdef ENABLE_PROC_FS
1653   struct proc_dir_entry *ret;
1654 #endif /* ENABLE_PROC_FS */
1655 #endif /* CONFIG_PROC_FS */
1656   int i;
1657   dev_t dev;
1658
1659   dev = MKDEV(devmajor, devminor);
1660   err = register_chrdev_region(dev, nrdevs, EVK_NAME);
1661   if (err) {
1662     EVK_info1("register_chrdev_region error %d\n",  -err);
1663     return -EBUSY;
1664   }
1665
1666   cdev_init(&cdev, &evk_fops);
1667   cdev.owner = THIS_MODULE;
1668   cdev.ops = &evk_fops;
1669
1670   err = cdev_add(&cdev, dev, 1);
1671   if (err) {
1672     EVK_info1("cdev_add error %d\n", -err);
1673     return -EBUSY;
1674   }
1675
1676   /* Initialization */
1677   for(i = 0 ; i < EVK_MAX_FLAGS ; i++) {
1678     list_add_tail((struct list_head *)&(_flag_pool[i]),
1679                   &flag_pool);
1680   }
1681   for(i = 0 ; i < EVK_MAX_FLAG64S ; i++) {
1682     list_add_tail((struct list_head *)&(_flag64_pool[i]),
1683                   &flag64_pool);
1684   }
1685   for(i = 0 ; i < EVK_MAX_MESSAGE_QUEUES ; i++) {
1686     list_add_tail((struct list_head *)&(_message_queue_pool[i]),
1687                   &message_queue_pool);
1688   }
1689   for(i = 0 ; i < HASH_KEY ; i++) {
1690     INIT_LIST_HEAD(&(queue_entry[i]));
1691   }
1692
1693 #ifdef CONFIG_PROC_FS
1694 #ifdef ENABLE_PROC_FS
1695   ret = proc_create("driver/ev_flag", 0, NULL, &evk_proc_flag_fops);
1696   if( ret == NULL ) {
1697     EVK_info1("Unable to initialize /proc entry %d\n",  -err);
1698     return -EBUSY;
1699   }
1700
1701   ret = proc_create("driver/ev_flag64", 0, NULL, &evk_proc_flag64_fops);
1702   if( ret == NULL ) {
1703     EVK_info1("Unable to initialize /proc entry %d\n",  -err);
1704     return -EBUSY;
1705   }
1706
1707   ret = proc_create("driver/ev_queue", 0, NULL, &evk_proc_queue_fops);
1708   if( ret == NULL ) {
1709     EVK_info1("Unable to initialize /proc entry %d\n",  -err);
1710     return -EBUSY;
1711   }
1712 #endif /* ENABLE_PROC_FS */
1713 #endif /* CONFIG_PROC_FS */
1714
1715   pClass = class_create(THIS_MODULE, EVK_NAME);
1716   device_create(pClass, NULL, dev, NULL, "agl/"EVK_NAME);
1717
1718   return 0;
1719 }
1720
1721 void
1722 //#ifndef CONFIG_COMBINE_MODULES
1723 //__exit
1724 //#endif
1725 EVK_exit(void)
1726 {
1727   dev_t dev = MKDEV(devmajor, devminor);
1728   device_destroy(pClass, dev);
1729   class_destroy(pClass);
1730
1731   cdev_del(&cdev);
1732
1733   unregister_chrdev_region(dev, nrdevs);
1734
1735   remove_proc_entry( "driver/ev_flag", 0 );
1736   remove_proc_entry( "driver/ev_flag64", 0 );
1737   remove_proc_entry( "driver/ev_queue", 0 );
1738 }
1739
1740 /** @} */
1741 /** @addtogroup EV
1742  * @{ */
1743 static EV_ERR
1744 EVK_create_flag_in(EV_ID flagID)
1745 {
1746   int ret = evk_create_flag(flagID);
1747
1748   if (ret == -EEXIST) {
1749     return EV_ERR_Exist;
1750   } else if (ret < 0) {
1751     return EV_ERR_Fatal;
1752   } else {
1753     return EV_OK;
1754   }
1755 }
1756
1757 static EV_ERR
1758 EVK_create_flag64_in(EV_ID flagID)
1759 {
1760   int ret = evk_create_flag64(flagID);
1761
1762   if (ret == -EEXIST) {
1763     return EV_ERR_Exist;
1764   } else if (ret < 0) {
1765     return EV_ERR_Fatal;
1766   } else {
1767     return EV_OK;
1768   }
1769 }
1770
1771 /** @see EV_create_flag */
1772 EV_ERR
1773 EVK_create_flag(EV_ID flagID)
1774 {
1775   if (!EV_ID_IS_FLAG(flagID) || EV_ID_IS_AUTO_ID(flagID)) {
1776     return EV_ERR_Invalid_ID;
1777   }
1778   return EVK_create_flag_in(flagID);
1779 }
1780
1781 /** @see EV_create_flag64 */
1782 EV_ERR
1783 EVK_create_flag64(EV_ID flagID)
1784 {
1785   if (!EV_ID_IS_FLAG64(flagID) || EV_ID_IS_AUTO_ID(flagID)) {
1786     return EV_ERR_Invalid_ID;
1787   }
1788   return EVK_create_flag64_in(flagID);
1789 }
1790
1791 static EV_ERR
1792 EVK_create_queue_in(EV_ID queueID, UINT8 length, UINT16 max_bytes,
1793                     EV_Message_Queue_Type type)
1794 {
1795   int ret = evk_create_message_queue(queueID, length, max_bytes, type);
1796
1797   if (ret == -EEXIST) {
1798     return EV_ERR_Exist;
1799   } else if (ret < 0) {
1800     return EV_ERR_Fatal;
1801   } else {
1802     return EV_OK;
1803   }
1804 }
1805
1806 /** @see EV_create_queue */
1807 EV_ERR
1808 EVK_create_queue(EV_ID queueID, UINT8 length, UINT16 max_bytes,
1809                  EV_Message_Queue_Type type)
1810 {
1811   if (!EV_ID_IS_QUEUE(queueID) || EV_ID_IS_AUTO_ID(queueID)) {
1812     return EV_ERR_Invalid_ID;
1813   }
1814   return EVK_create_queue_in(queueID, length, max_bytes, type);
1815 }
1816
1817 /** @see EV_create_flag_auto_id */
1818 EV_ERR
1819 EVK_create_flag_auto_id(/* OUT */EV_ID *flagID)
1820 {
1821   EV_ERR err;
1822   EVK_assert(flagID != NULL, "NULL pointer was specified");
1823
1824   if (evk_alloc_flagID(flagID) < 0) {
1825     return EV_ERR_Fatal;
1826   }
1827
1828   err = EVK_create_flag_in(*flagID);
1829   if (err != EV_OK) {
1830     *flagID = EV_NO_ID;
1831   }
1832   return err;
1833 }
1834
1835 /** @see EV_create_flag64_auto_id */
1836 EV_ERR
1837 EVK_create_flag64_auto_id(/* OUT */EV_ID *flagID)
1838 {
1839   EV_ERR err;
1840   EVK_assert(flagID != NULL, "NULL pointer was specified");
1841
1842   if (evk_alloc_flag64ID(flagID) < 0) {
1843     return EV_ERR_Fatal;
1844   }
1845
1846   err = EVK_create_flag64_in(*flagID);
1847   if (err != EV_OK) {
1848     *flagID = EV_NO_ID;
1849   }
1850   return err;
1851 }
1852
1853 /** @see EV_create_queue_auto_id */
1854 EV_ERR
1855 EVK_create_queue_auto_id(/* OUT */EV_ID *queueID, UINT8 length,
1856                          UINT16 max_bytes, EV_Message_Queue_Type type)
1857 {
1858   EV_ERR err;
1859   EVK_assert(queueID != NULL, "NULL pointer was specified");
1860
1861   if (evk_alloc_queueID(queueID) < 0) {
1862     return EV_ERR_Fatal;
1863   }
1864
1865   err = EVK_create_queue_in(*queueID, length, max_bytes, type);
1866   if (err != EV_OK) {
1867     *queueID = EV_NO_ID;
1868   }
1869   return err;
1870 }
1871
1872 /** @see EV_destroy_flag */
1873 EV_ERR
1874 EVK_destroy_flag(EV_ID flagID)
1875 {
1876   int err;
1877   err = evk_destroy_queue(flagID);
1878
1879   if (err == -ENOENT) {
1880     return EV_ERR_Invalid_ID;
1881   } else if (err < 0) {
1882     return EV_ERR_Fatal;
1883   } else {
1884     return EV_OK;
1885   }
1886 }
1887
1888 /** @see EV_destroy_queue */
1889 EV_ERR
1890 EVK_destroy_queue(EV_ID queueID)
1891 {
1892   return EVK_destroy_flag(queueID);
1893 }
1894
1895 /* Sending the event */
1896 /** @see EV_set_flag */
1897 EV_ERR
1898 EVK_set_flag(EV_ID flagID, UINT32 bits)
1899 {
1900   EV_Flag flag;
1901   int ret;
1902
1903   if (!EV_ID_IS_FLAG(flagID)) {
1904     return EV_ERR_Invalid_ID;
1905   }
1906   flag.flagID = flagID;
1907   flag.bits = bits;
1908
1909   ret = evk_store_flag(&flag, evk_mem_kernel);
1910   if (ret == -ENOENT) {
1911     return EV_ERR_Invalid_ID;
1912   } else if (ret < 0) {
1913     return EV_ERR_Fatal;
1914   } else {
1915     return EV_OK;
1916   }
1917 }
1918
1919 /** @see EV_set_flag64 */
1920 EV_ERR
1921 EVK_set_flag64(EV_ID flagID, UINT64 bits)
1922 {
1923   EV_Flag64 flag;
1924   int ret;
1925
1926   if (!EV_ID_IS_FLAG64(flagID)) {
1927     return EV_ERR_Invalid_ID;
1928   }
1929   flag.flagID = flagID;
1930   flag.bits = bits;
1931
1932   ret = evk_store_flag64(&flag, evk_mem_kernel);
1933   if (ret == -ENOENT) {
1934     return EV_ERR_Invalid_ID;
1935   } else if (ret < 0) {
1936     return EV_ERR_Fatal;
1937   } else {
1938     return EV_OK;
1939   }
1940 }
1941
1942 /** @see EV_send_message */
1943 EV_ERR
1944 EVK_send_message(EV_ID queueID, UINT16 bytes, const void *message,
1945                  UINT32 senderInfo)
1946 {
1947   EV_Message *msg = NULL;
1948   EV_ERR ev_ret;
1949   int ret;
1950
1951   msg = evk_malloc( sizeof( EV_Message ) );
1952   if( msg == NULL )
1953   {
1954     ev_ret = EV_ERR_Fatal;
1955     goto L_END;
1956   }
1957
1958   if (!EV_ID_IS_QUEUE(queueID)) {
1959     ev_ret = EV_ERR_Invalid_ID;
1960     goto L_END;
1961   }
1962   EVK_assert(message != NULL, "NULL pointer was specified");
1963   EVK_assert(bytes <= EV_MAX_MESSAGE_LENGTH, "send_message: message too long");
1964
1965   msg->queueID = queueID;
1966   msg->senderInfo = senderInfo;
1967   msg->length = bytes;
1968   memcpy(msg->message, message, bytes);
1969
1970   ret = evk_store_message(msg, evk_mem_kernel);
1971   if (ret == -ENOENT) {
1972     ev_ret = EV_ERR_Invalid_ID;
1973   } else if (ret == -EBUSY) {
1974     ev_ret = EV_ERR_Busy;
1975   } else if (ret < 0) {
1976     ev_ret = EV_ERR_Fatal;
1977   } else {
1978     ev_ret = EV_OK;
1979   }
1980
1981 L_END:
1982   if( msg != NULL )
1983   {
1984     evk_free( msg );
1985   }
1986   return ev_ret;
1987 }
1988
1989 /* Event acquisition(Order of arrival time) */
1990 //EV_ERR EV_get_next_event(/* OUT */EV_Event *ev);
1991
1992 static EV_ERR
1993 EVK_get_flag_in(EV_ID flagID, EV_Flag *flag, int peek_only, int wait)
1994 {
1995   EV_Event *ev = NULL;
1996   EV_ERR ev_ret;
1997   int ret;
1998
1999   ev = evk_malloc( sizeof( EV_Event ) );
2000   if( ev == NULL )
2001   {
2002     ev_ret = EV_ERR_Fatal;
2003     goto L_END;
2004   }
2005
2006   EVK_assert(flag != NULL, "get_flag: NULL pointer was specified");
2007   flag->flagID = EV_NO_ID;
2008   flag->bits = 0;
2009
2010   if (!EV_ID_IS_FLAG(flagID)) {
2011     ev_ret = EV_ERR_Invalid_ID;
2012     goto L_END;
2013   }
2014
2015   ev->type = EV_EVENT_Flag;
2016   ev->u.flag.flagID = flagID;
2017   ev->u.flag.bits = 0;
2018
2019   ret = evk_get_event(ev, peek_only, wait, evk_mem_kernel);
2020
2021   if (ret < 0) {
2022     if (ret == -ENOENT) {
2023       ev_ret = EV_ERR_Invalid_ID;
2024     } else if (ret == -EINTR) {
2025       ev_ret = EV_ERR_Interrupted;
2026     } else {
2027       ev_ret = EV_ERR_Fatal;
2028     }
2029     goto L_END;
2030   }
2031
2032   if (ev->type == EV_EVENT_Flag) {
2033     flag->flagID = ev->u.flag.flagID;
2034     flag->bits = ev->u.flag.bits;
2035   }
2036   ev_ret = EV_OK;
2037
2038 L_END:
2039   if( ev != NULL )
2040   {
2041     evk_free( ev );
2042   }
2043   return ev_ret;
2044 }
2045
2046 static EV_ERR
2047 EVK_get_flag64_in(EV_ID flagID, EV_Flag64 *flag, int peek_only, int wait)
2048 {
2049   EV_Event *ev = NULL;
2050   EV_ERR ev_ret;
2051   int ret;
2052
2053   ev = evk_malloc( sizeof( EV_Event ) );
2054   if( ev == NULL )
2055   {
2056     ev_ret = EV_ERR_Fatal;
2057     goto L_END;
2058   }
2059
2060   EVK_assert(flag != NULL, "get_flag64: NULL pointer was specified");
2061   flag->flagID = EV_NO_ID;
2062   flag->bits = 0;
2063
2064   if (!EV_ID_IS_FLAG64(flagID)) {
2065     ev_ret = EV_ERR_Invalid_ID;
2066     goto L_END;
2067   }
2068
2069   ev->type = EV_EVENT_Flag64;
2070   ev->u.flag64.flagID = flagID;
2071   ev->u.flag64.bits = 0;
2072
2073   ret = evk_get_event(ev, peek_only, wait, evk_mem_kernel);
2074
2075   if (ret < 0) {
2076     if (ret == -ENOENT) {
2077       ev_ret = EV_ERR_Invalid_ID;
2078     } else if (ret == -EINTR) {
2079       ev_ret = EV_ERR_Interrupted;
2080     } else {
2081       ev_ret = EV_ERR_Fatal;
2082     }
2083     goto L_END;
2084   }
2085
2086   if (ev->type == EV_EVENT_Flag64) {
2087     flag->flagID = ev->u.flag64.flagID;
2088     flag->bits = ev->u.flag64.bits;
2089   }
2090   ev_ret = EV_OK;
2091
2092 L_END:
2093   if( ev != NULL )
2094   {
2095     evk_free( ev );
2096   }
2097   return ev_ret;
2098 }
2099
2100 /* Event acquisition(With Search Criteria) */
2101 /** @see EV_get_flag */
2102 EV_ERR
2103 EVK_get_flag(EV_ID flagID, /* OUT */EV_Flag *flag)
2104 {
2105   return EVK_get_flag_in(flagID, flag, 0, 0);
2106 }
2107
2108 /** @see EV_get_flag64 */
2109 EV_ERR
2110 EVK_get_flag64(EV_ID flagID, /* OUT */EV_Flag64 *flag)
2111 {
2112   return EVK_get_flag64_in(flagID, flag, 0, 0);
2113 }
2114
2115 /** @see EV_wait_flag */
2116 EV_ERR
2117 EVK_wait_flag(EV_ID flagID, /* OUT */EV_Flag *flag)/* block */
2118 {
2119   return EVK_get_flag_in(flagID, flag, 0, 1);
2120 }
2121
2122 /** @see EV_wait_flag64 */
2123 EV_ERR
2124 EVK_wait_flag64(EV_ID flagID, /* OUT */EV_Flag64 *flag)/* block */
2125 {
2126   return EVK_get_flag64_in(flagID, flag, 0, 1);
2127 }
2128
2129 /** @see EV_peek_flag */
2130 EV_ERR
2131 EVK_peek_flag(EV_ID flagID, /* OUT */EV_Flag *flag)
2132 {
2133   return EVK_get_flag_in(flagID, flag, 1, 0);
2134 }
2135
2136 /** @see EV_peek_flag64 */
2137 EV_ERR
2138 EVK_peek_flag64(EV_ID flagID, /* OUT */EV_Flag64 *flag)
2139 {
2140   return EVK_get_flag64_in(flagID, flag, 1, 0);
2141 }
2142
2143 static EV_ERR
2144 EVK_get_message_in(EV_ID queueID, EV_Message *message, UINT32 senderInfo,
2145                    UINT32 length, const void *compare_bytes,
2146                    int peek_only, int wait)
2147 {
2148   EV_Event *ev = NULL;
2149   EV_ERR ev_ret;
2150   int ret;
2151
2152   ev = evk_malloc( sizeof( EV_Event ) );
2153   if( ev == NULL )
2154   {
2155     ev_ret = EV_ERR_Fatal;
2156     goto L_END;
2157   }
2158
2159   EVK_assert(message != NULL, "get_message: NULL pointer was specified");
2160   if (!EV_ID_IS_QUEUE(queueID)) {
2161     ev_ret = EV_ERR_Invalid_ID;
2162     goto L_END;
2163   }
2164   message->queueID = EV_NO_ID;
2165   message->senderInfo = 0;
2166   message->length = 0;
2167
2168   ev->type = EV_EVENT_Message;
2169   ev->u.message.queueID = queueID;
2170   ev->u.message.senderInfo = senderInfo;
2171   if (compare_bytes != NULL) {
2172     ev->u.message.length = length;
2173     memcpy(ev->u.message.message, compare_bytes, length);
2174   } else {
2175     ev->u.message.length = 0;
2176   }
2177
2178   ret = evk_get_event(ev, peek_only, wait, evk_mem_kernel);
2179
2180   if (ret < 0) {
2181     if (ret == -ENOENT) {
2182       ev_ret = EV_ERR_Invalid_ID;
2183     } else if (ret == -EINTR) {
2184       ev_ret = EV_ERR_Interrupted;
2185     } else {
2186       ev_ret = EV_ERR_Fatal;
2187     }
2188     goto L_END;
2189   }
2190
2191   if (ev->type == EV_EVENT_Message) {
2192     message->queueID = ev->u.message.queueID;
2193     message->senderInfo = ev->u.message.senderInfo;
2194     message->length = ev->u.message.length;
2195     memcpy(message->message, ev->u.message.message, ev->u.message.length);
2196   }
2197   ev_ret = EV_OK;
2198
2199 L_END:
2200   if( ev != NULL )
2201   {
2202     evk_free( ev );
2203   }
2204   return ev_ret;
2205 }
2206
2207 /** @see EV_get_message */
2208 EV_ERR
2209 EVK_get_message(EV_ID queueID, /* OUT */EV_Message *message)
2210 {
2211   return EVK_get_message_in(queueID, message, 0, 0, NULL, 0, 0);
2212 }
2213
2214 /** @see EV_wait_message */
2215 EV_ERR
2216 EVK_wait_message(EV_ID queueID, /* OUT */EV_Message *message)/* block */
2217 {
2218   return EVK_get_message_in(queueID, message, 0, 0, NULL, 0, 1);
2219 }
2220
2221 /** @see EV_peek_message */
2222 EV_ERR
2223 EVK_peek_message(EV_ID queueID, /* OUT */EV_Message *message)
2224 {
2225   return EVK_get_message_in(queueID, message, 0, 0, NULL, 1, 0);
2226 }
2227
2228 /** @see EV_find_message_by_sender */
2229 EV_ERR
2230 EVK_find_message_by_sender(EV_ID queueID, UINT32 senderInfo,
2231                            /* OUT */EV_Message *message)
2232 {
2233   // Not mounted
2234   return EV_ERR_Fatal;
2235 }
2236
2237 /** @see EV_find_message_by_content */
2238 EV_ERR
2239 EVK_find_message_by_content(EV_ID queueID, UINT16 length,
2240                             const void *compare_bytes,
2241                             /* OUT */EV_Message *message)
2242 {
2243   // Not mounted
2244   return EV_ERR_Fatal;
2245 }
2246 /** @} */
2247
2248 EXPORT_SYMBOL(evk_get_queue_entry);
2249 EXPORT_SYMBOL(EVK_init);
2250 EXPORT_SYMBOL(EVK_exit);
2251
2252 EXPORT_SYMBOL(EVK_create_flag);
2253 EXPORT_SYMBOL(EVK_create_flag64);
2254 EXPORT_SYMBOL(EVK_create_queue);
2255 EXPORT_SYMBOL(EVK_create_flag_auto_id);
2256 EXPORT_SYMBOL(EVK_create_flag64_auto_id);
2257 EXPORT_SYMBOL(EVK_create_queue_auto_id);
2258 EXPORT_SYMBOL(EVK_destroy_flag);
2259 EXPORT_SYMBOL(EVK_destroy_queue);
2260 EXPORT_SYMBOL(EVK_set_flag);
2261 EXPORT_SYMBOL(EVK_set_flag64);
2262 EXPORT_SYMBOL(EVK_send_message);
2263 EXPORT_SYMBOL(EVK_get_flag);
2264 EXPORT_SYMBOL(EVK_wait_flag);
2265 EXPORT_SYMBOL(EVK_peek_flag);
2266 EXPORT_SYMBOL(EVK_get_flag64);
2267 EXPORT_SYMBOL(EVK_wait_flag64);
2268 EXPORT_SYMBOL(EVK_peek_flag64);
2269 EXPORT_SYMBOL(EVK_get_message);
2270 EXPORT_SYMBOL(EVK_wait_message);
2271 EXPORT_SYMBOL(EVK_peek_message);
2272
2273 #ifndef CONFIG_COMBINE_MODULES
2274 //MODULE_LICENSE("proprietary");
2275 MODULE_LICENSE("GPL");
2276 MODULE_DESCRIPTION("EVent library for Kernel");
2277 //MODULE_SUPPORTED_DEVICE(name);
2278 //MODULE_PARM(var,type)
2279 //MODULE_PARM_DESC(var,desc)
2280 module_init(EVK_init);
2281 module_exit(EVK_exit);
2282 #endif /* !CONFIG_COMBINE_MODULES */