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