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