diff options
Diffstat (limited to 'kernel-module-evklib')
-rwxr-xr-x | kernel-module-evklib/Makefile | 30 | ||||
-rwxr-xr-x | kernel-module-evklib/agldd/agldd.h | 94 | ||||
-rwxr-xr-x | kernel-module-evklib/agldd/ev_common.h | 135 | ||||
-rwxr-xr-x | kernel-module-evklib/agldd/ev_id.h | 104 | ||||
-rwxr-xr-x | kernel-module-evklib/agldd/evk_lib.h | 116 | ||||
-rwxr-xr-x | kernel-module-evklib/agldd/moduleid.h | 69 | ||||
-rwxr-xr-x | kernel-module-evklib/evk_lib.c | 2282 |
7 files changed, 0 insertions, 2830 deletions
diff --git a/kernel-module-evklib/Makefile b/kernel-module-evklib/Makefile deleted file mode 100755 index 2c37667..0000000 --- a/kernel-module-evklib/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Makefile for linux/drivers/agl -# -CFILES = evk_lib.c - -obj-m := evk_lib.o -evklib-objs := $(CFILES:.c=.o) - -U_INCLUDE += -I$(PWD) -U_INCLUDE += -I$(KERNEL_SRC)/include -ccflags-y += $(U_INCLUDE) - -all: - make -C $(KERNEL_SRC) M=$(PWD) modules -clean: - make -C $(KERNEL_SRC) M=$(PWD) clean - diff --git a/kernel-module-evklib/agldd/agldd.h b/kernel-module-evklib/agldd/agldd.h deleted file mode 100755 index 112dbae..0000000 --- a/kernel-module-evklib/agldd/agldd.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * adcpf common header - * - * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _AGLDD_H_ -#define _AGLDD_H_ -#ifdef __KERNEL__ -#include <linux/types.h> -#else -#include <stdint.h> -#if !defined(__cplusplus) -#include <stdbool.h> -#endif /* !defined(__cplusplus) */ -#endif /* __KERNEL__ */ - -#ifndef __KERNEL__ -#define __LINUX_ARM_ARCH__ 7 -#define BITS_PER_LONG 32 - -#define __AGLDD_TYPEDEF_I64 -typedef long long i64; /* 8-byte signed integer */ - -#define __AGLDD_TYPEDEF_U64 -typedef unsigned long long u64; /* 8-byte unsigned integer */ - -#define __AGLDD_TYPEDEF_U32 -typedef unsigned long u32; /* 4-byte unsigned integer */ - -#define __AGLDD_TYPEDEF_U16 -typedef unsigned short u16; /* 2-byte unsigned integer */ - -#define __AGLDD_TYPEDEF_I16 -typedef short i16; /* 2-byte signed integer */ - -#define __AGLDD_TYPEDEF_U8 -typedef unsigned char u8; /* 1-byte unsigned integer */ - -#define __AGLDD_TYPEDEF_I8 -typedef char i8; /* 1-byte signed integer */ -#endif - -#define __AGLDD_TYPEDEF_INT8 -typedef signed char INT8; - -#define __AGLDD_TYPEDEF_INT16 -typedef signed short INT16; - -#define __AGLDD_TYPEDEF_INT32 -typedef signed int INT32; - -#define __AGLDD_TYPEDEF_INT64 -typedef signed long long INT64; - -#define __AGLDD_TYPEDEF_UINT8 -typedef unsigned char UINT8; - -#define __AGLDD_TYPEDEF_UINT16 -typedef unsigned short UINT16; - -#define __AGLDD_TYPEDEF_UINT32 -typedef unsigned int UINT32; - -#define __AGLDD_TYPEDEF_UINT64 -typedef unsigned long long UINT64; - -#ifndef __KERNEL__ -#if !defined __WIN_TYPEDEF_BOOL -#define __AGLDD_TYPEDEF_BOOL -typedef UINT32 BOOL; -#endif -#endif - -#ifndef TRUE -#define TRUE true -#endif -#ifndef FALSE -#define FALSE false -#endif - -#endif/* _AGLDD_H_ */ diff --git a/kernel-module-evklib/agldd/ev_common.h b/kernel-module-evklib/agldd/ev_common.h deleted file mode 100755 index 0cc1183..0000000 --- a/kernel-module-evklib/agldd/ev_common.h +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file ev_common.h - * @brief Event library -- User kernel common data structure - * - * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _ev_common_h_ -#define _ev_common_h_ - -#include <agldd/ev_id.h> - -/** @addtogroup EV - * @{ */ -/** @brief Maximum number of bytes for message event */ -#define EV_MAX_MESSAGE_LENGTH 2048 - -/** @brief -Maximum number of flag queue that can be created within a thread */ -#define EV_MAX_IDS_IN_THREAD 24 - -/** @brief -Muximum number of threads that can be registered to the EV in a process */ -#define EV_MAX_THREADS_IN_PROCESS 16 - -/** @brief -Maximum number of flag queue that can be creat within a process - */ -#define EV_MAX_IDS_IN_PROCESS \ - (EV_MAX_IDS_IN_THREAD * EV_MAX_THREADS_IN_PROCESS) - -/** @brief Return values for even library function - * - * @see EV_ERR - */ -enum ev_err -{ - EV_OK = 0, /**< Normal completion */ - EV_ERR_Exist, /**< The specified flag message queue does exist */ - EV_ERR_Invalid_ID, /**< The specified flag message queue does not exist */ - EV_ERR_Busy, /**< Message queue full failed to send */ - EV_ERR_Interrupted, /**< Waiting function was interrupted by an interrupt */ - EV_ERR_Thread_Over, /**< Exceeding the number of threads in the process */ - EV_ERR_Invalid_Thread, /**< Invalid thread ID */ - EV_ERR_Fatal, /**< Fatal error */ -}; -/** @brief Return values type for even library function - * - * @see ev_err - */ -typedef INT32 EV_ERR; - -/** @brief Event type - * - * Use in the type of EV_Event structs - * @see ev_type - */ -typedef UINT32 EV_Type; - -/** @brief Bit value representing the type of event */ -enum ev_type { - EV_EVENT_None = 0x00000000, - - /** Flag event: Judged by EV_EVENT_IS_FLAG() */ - EV_EVENT_Flag = 0x0001, -#define EV_EVENT_IS_FLAG(tp) (((tp) & EV_EVENT_Flag) != 0) - - /** Message event: Judged by EV_EVENT_IS_MESSAGE() */ - EV_EVENT_Message = 0x0002, -#define EV_EVENT_IS_MESSAGE(tp) (((tp) & EV_EVENT_Message) != 0) - - /** 64bit flag event: Judged by EV_EVENT_IS_FLAG64() */ - EV_EVENT_Flag64 = 0x0003, -#define EV_EVENT_IS_FLAG64(tp) (((tp) & EV_EVENT_Flag64) != 0) - -}; - -/** @brief Flag event structure */ -typedef struct { - EV_ID flagID;/**< Flag ID */ - UINT32 bits;/**< Bit pattern */ -} EV_Flag; - -/** @brief 64bit flag event structure */ -typedef struct { - EV_ID flagID;/**< Flag ID */ - UINT64 bits;/**< Bit pattern */ -} EV_Flag64; - -/** @brief Message event structure */ -typedef struct { - EV_ID queueID;/**< queue ID */ - UINT32 senderInfo;/**< Source information */ - UINT32 length;/**< Number of bytes in the message */ - UINT32 dummy;/** dummy for pading */ - UINT8 message[EV_MAX_MESSAGE_LENGTH];/**< Message */ -} EV_Message; - -/** @brief Event structure */ -typedef struct { - EV_Type type; /**< Event type */ - union { - EV_Flag flag; /**< Flag event structure */ - EV_Flag64 flag64; /**< Flag event structure */ - EV_Message message; /**< Message event structure */ - } u; /**< Union of structures per eventtype */ -} EV_Event; - -/** @brief Message event queue type - * - * Specify the action to be taken when the queue overflows (more events are received when the queue is full). - */ -enum ev_message_queue_type { - EV_MESSAGE_QUEUE_TYPE_BUSY,/**< Return a BUSY to the source */ - EV_MESSAGE_QUEUE_TYPE_FIFO,/**< Delete the oldest event */ - EV_MESSAGE_QUEUE_TYPE_REPLACE,/**< Replace the most recent event */ -}; - -/** @brief Messge event queue type - * - * @see ev_message_queue_type - */ -typedef UINT8 EV_Message_Queue_Type; - -/** @} */ - -#endif /* !_ev_common_h_ */ diff --git a/kernel-module-evklib/agldd/ev_id.h b/kernel-module-evklib/agldd/ev_id.h deleted file mode 100755 index 2026ef7..0000000 --- a/kernel-module-evklib/agldd/ev_id.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file ev_id.h - * @brief Event library(kernel) -- Defining flag queue ID - * - * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _ev_id_h_ -#define _ev_id_h_ - -/** @addtogroup EV_ID_spec - * @{ */ - -/** @brief Flag ID and queue ID types used when sending and receiving events - * - * Assign a 32-bit value as follows - * - * - Most significant 8 bits: Reserved - * - Next 16 bits: Modue ID - * - Lower 8 bits: Define in module - * - * Where module is the modules that creates the queue. - * The modules define ID according to the above assignments using EV_Flag_ID_Base and EV_Queue_ID_Base macros. - * @see EV_Flag_ID_Base - * @see EV_Queue_ID_Base - */ -typedef UINT32 EV_ID; - -#define EV_ID_BIT 0x80000000UL -#define EV_FLAG64_BIT 0x40000000UL -#define EV_FLAG_BIT 0x20000000UL -#define EV_QUEUE_BIT 0x10000000UL -#define EV_AUTO_ID_BIT 0x08000000UL -#define EV_RESERVED_BIT 0xff000000UL -#define EV_INVALID_ID EV_ID_BIT -#define EV_NO_ID EV_INVALID_ID - -#define EV_ID_IS_FLAG(queueID) \ - (((queueID) & (EV_ID_BIT|EV_FLAG_BIT)) == (EV_ID_BIT|EV_FLAG_BIT)) -#define EV_ID_IS_FLAG64(queueID) \ - (((queueID) & (EV_ID_BIT|EV_FLAG64_BIT)) == (EV_ID_BIT|EV_FLAG64_BIT)) -#define EV_ID_IS_QUEUE(queueID) \ - (((queueID) & (EV_ID_BIT|EV_QUEUE_BIT)) == (EV_ID_BIT|EV_QUEUE_BIT)) -#define EV_ID_IS_AUTO_ID(queueID) \ - (((queueID) & (EV_ID_BIT|EV_AUTO_ID_BIT)) == (EV_ID_BIT|EV_AUTO_ID_BIT)) -#define EV_ID_IS_VALID(queueID) \ - (EV_ID_IS_FLAG(queueID) || EV_ID_IS_FLAG64(queueID) || EV_ID_IS_QUEUE(queueID)) - -/** @brief Macros for defining flag ID - * - * Define the module ID as an argument as follows. - * - #define XXX_Module_ID 1 - * - #define XXX_Flag_ID_Base EV_Flag_ID_Base(XXX_Module_ID) - * - - * - #define XXX_Flag_foo (XXX_Flag_ID_Base + 1) - * - #define XXX_Flag_bar (XXX_Flag_ID_Base + 2) - * - * The module ID is 16 bits and 0 to 65535 can be specified. - * In addition, 0 to 255 added to Base can be defined as ID. - */ -#define EV_Flag_ID_Base(mod) (EV_ID_BIT|EV_FLAG_BIT|((mod)<<8)) - -/** @brief Macros for defining 64 bits flag ID - * - * Define the module ID as an argument as follows. - * - #define XXX_Module_ID 1 - * - #define XXX_Flag64_ID_Base EV_Flag64_ID_Base(XXX_Module_ID) - * - - * - #define XXX_Flag64_foo (XXX_Flag64_ID_Base + 1) - * - #define XXX_Flag64_bar (XXX_Flag64_ID_Base + 2) - * - * The module ID is 16 bits and 0 to 65535 can be specified. - * In addition, 0 to 255 added to Base can be defined as ID. - */ -#define EV_Flag64_ID_Base(mod) (EV_ID_BIT|EV_FLAG64_BIT|((mod)<<8)) - -/** @brief Macros for defining mesage queue ID - * - * Define the module ID as an argument as follows. - * - #define XXX_Module_ID 1 - * - #define XXX_Queue_ID_Base EV_Queue_ID_Base(XXX_Module_ID) - * - - * - #define XXX_Queue_foo (XXX_Queue_ID_Base + 1) - * - #define XXX_Queue_bar (XXX_Queue_ID_Base + 2) - * - * The module ID is 16 bits and 0 to 65535 can be specified. - * In addition, 0 to 255 added to Base can be defined as ID. - */ -#define EV_Queue_ID_Base(mod) (EV_ID_BIT|EV_QUEUE_BIT|((mod)<<8)) - -/** @} */ - -#endif /* ! _ev_id_h_ */ diff --git a/kernel-module-evklib/agldd/evk_lib.h b/kernel-module-evklib/agldd/evk_lib.h deleted file mode 100755 index 416fb0f..0000000 --- a/kernel-module-evklib/agldd/evk_lib.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file evk_lib.h - * @brief Event library -- API specifications for kernel modules - * - * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _evk_lib_h_ -#define _evk_lib_h_ - -#include <agldd/ev_common.h> -#include <linux/types.h> -#include <linux/ioctl.h> - -/* API definition */ - -/** @addtogroup EV - * @{ */ -#ifdef __KERNEL__ -/* Flag message queue create/delete */ -EV_ERR EVK_create_flag(EV_ID flagID); -EV_ERR EVK_create_flag64(EV_ID flagID); -EV_ERR EVK_create_queue(EV_ID queueID, - UINT8 length, - UINT16 max_bytes, - EV_Message_Queue_Type type); - -EV_ERR EVK_create_flag_auto_id(/* OUT */EV_ID *flagID); -EV_ERR EVK_create_flag64_auto_id(/* OUT */EV_ID *flagID); -EV_ERR EVK_create_queue_auto_id(/* OUT */EV_ID *queueID, - UINT8 length, - UINT16 max_bytes, - EV_Message_Queue_Type type); - -EV_ERR EVK_destroy_flag(EV_ID flagID); -EV_ERR EVK_destroy_queue(EV_ID queueID); - -/* Send events */ -EV_ERR EVK_set_flag(EV_ID flagID, UINT32 bits); -EV_ERR EVK_set_flag64(EV_ID flagID, UINT64 bits); -EV_ERR EVK_send_message(EV_ID queueID, UINT16 bytes, const void *message, - UINT32 senderInfo); - -/* Get event(with search conditions) */ -EV_ERR EVK_get_flag(EV_ID flagID, /* OUT */EV_Flag *flag); -EV_ERR EVK_wait_flag(EV_ID flagID, /* OUT */EV_Flag *flag);/* block */ -EV_ERR EVK_peek_flag(EV_ID flagID, /* OUT */EV_Flag *flag); -EV_ERR EVK_get_flag64(EV_ID flagID, /* OUT */EV_Flag64 *flag); -EV_ERR EVK_wait_flag64(EV_ID flagID, /* OUT */EV_Flag64 *flag);/* block */ -EV_ERR EVK_peek_flag64(EV_ID flagID, /* OUT */EV_Flag64 *flag); - -EV_ERR EVK_get_message(EV_ID queueID, /* OUT */EV_Message *message); -EV_ERR EVK_wait_message(EV_ID queueID, /* OUT */EV_Message *message);/* block */ -EV_ERR EVK_peek_message(EV_ID queueID, /* OUT */EV_Message *message); - -EV_ERR EVK_find_message_by_sender(EV_ID queueID, UINT32 senderInfo, - /* OUT */EV_Message *message); -EV_ERR EVK_find_message_by_content(EV_ID queueID, UINT16 length, - const void *compare_bytes, - /* OUT */EV_Message *message); -#endif - -/** @} */ - -/** @addtogroup EVK_in - * @{ */ -#define EVK_NAME "evk" -#define EVK_DEV_NAME "/dev/agl/"EVK_NAME -#define EVK_DEV_MAJOR (1033 % 256) -#define EVK_IOC_MAGIC 0xE7 - -#define EVK_IOC_CREATE_FLAG _IO(EVK_IOC_MAGIC, 0x00) -#define EVK_IOC_CREATE_FLAG64 _IO(EVK_IOC_MAGIC, 0x01) -#define EVK_IOC_CREATE_MESSAGE_QUEUE _IO(EVK_IOC_MAGIC, 0x02) -#define EVK_IOC_ALLOC_FLAG_ID _IO(EVK_IOC_MAGIC, 0x03) -#define EVK_IOC_ALLOC_FLAG64_ID _IO(EVK_IOC_MAGIC, 0x04) -#define EVK_IOC_ALLOC_QUEUE_ID _IO(EVK_IOC_MAGIC, 0x05) -#define EVK_IOC_DESTROY_QUEUE _IO(EVK_IOC_MAGIC, 0x06) -#define EVK_IOC_STORE_FLAG _IO(EVK_IOC_MAGIC, 0x07) -#define EVK_IOC_STORE_FLAG64 _IO(EVK_IOC_MAGIC, 0x08) -#define EVK_IOC_STORE_MESSAGE _IO(EVK_IOC_MAGIC, 0x09) -#define EVK_IOC_SET_POLL _IO(EVK_IOC_MAGIC, 0x0a) -#define EVK_IOC_GET_EVENT _IO(EVK_IOC_MAGIC, 0x0b) -#define EVK_IOC_PEEK_EVENT _IO(EVK_IOC_MAGIC, 0x0c) -#define EVK_IOC_WAIT_EVENT _IO(EVK_IOC_MAGIC, 0x0d) -#define EVK_IOC_GET_NEXT_EVENT _IO(EVK_IOC_MAGIC, 0x0e) -#define EVK_IOC_PEEK_NEXT_EVENT _IO(EVK_IOC_MAGIC, 0x0f) -#define EVK_IOC_DEBUG_LIST _IO(EVK_IOC_MAGIC, 0x10) - -typedef struct { - EV_ID queueID;/**< Queue ID */ - UINT32 max_bytes;/**< Maximum number of bytes for an event */ - UINT8 length;/**< Queue length */ - EV_Message_Queue_Type type;/**< Type */ -} EVK_Message_Queue_Request; - -typedef struct { - INT32 num; /**< Number of queue ID of search */ - EV_ID ids[EV_MAX_IDS_IN_PROCESS]; /**< Queue ID of search */ - EV_Event ev; /**< [OUT] First event that occured */ -} EVK_Next_Event_Query; - -/** @} */ - -#endif /* !_evk_lib_h */ diff --git a/kernel-module-evklib/agldd/moduleid.h b/kernel-module-evklib/agldd/moduleid.h deleted file mode 100755 index b18c1a1..0000000 --- a/kernel-module-evklib/agldd/moduleid.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <linux/autoconf.h> -#ifndef _AGLDD_MODULEID_H_ -#define _AGLDD_MODULEID_H_ - -/* - * Define module ID to be used by programs in moduleid_id.h . - * Define in the format of "#define XXX_MID ID number" (XXX is the module name). - * - * MID allocation policy shall be as follows. - * - UI Application : 0xxxh - * - Application Service : 1xxxh to 2xxxh - * + HMI : 10xxh - * + AV : 12xxh - * + Radio : 14xxh - * + Connectivity : 16xxh - * + Navigation/Location: 18xxh - * + Vehicle : 1Axxh - * + Communication : 1Cxxh - * + BasePF : 1Exxh - * + System : 20xxh - * + Other : 22xxh - * - Common Service : 3xxxh - * - Extension Service : 4xxxh - * - System/Device Driver : 5xxxh - */ - -/* UI Application : 0xxxh */ - -/* Application Service : 1xxxh to 2xxxh */ -#define MODEMANAGER_MID 0x1000 -#define ACTIVITYMANAGER_MID 0x1001 - -/* Common Service : 3xxxh */ -#define IPMANAGER_MID 0x3000 -#define DEVICEMANAGER_MID 0x3001 -#define MSGBRK_MID 0x3002 -#define TIMERENTRYDRV_MID 0x3003 -#define SOUNDAGENT_MID 0x3004 -#define CAN_MID 0x3006 -#define _CWORD83__MID 0x3007 -#define SENSOR_MID 0x3008 -#define GPS_MID 0x3009 -#define RESMGR_MID 0x300A -#define GRAPHICS_MID 0x300B - -/* Extension Service : 4xxxh */ - -/* System/Device Driver : 5xxxh */ -#define EV_MID 0x5001 -#define RPC_MID 0x5002 -#define EVK_MID 0x5801 - -#endif /* !_AGLDD_MODULEID_H_ */ diff --git a/kernel-module-evklib/evk_lib.c b/kernel-module-evklib/evk_lib.c deleted file mode 100755 index 05d881a..0000000 --- a/kernel-module-evklib/evk_lib.c +++ /dev/null @@ -1,2282 +0,0 @@ -/* - * drivers/agl/evk_lib.c - * - * Event library (kernel space part) - * - * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include <generated/autoconf.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/version.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/poll.h> -#include <linux/list.h> -#include <asm/uaccess.h> -#include <linux/errno.h> -#include <linux/vmalloc.h> - -#include <linux/proc_fs.h> -#include <linux/seq_file.h> - -#include <linux/device.h> -#include <linux/cdev.h> - -#ifndef STANDARD_INT_DEFINITIONS -#define STANDARD_INT_DEFINITIONS -typedef __u8 UINT8; -typedef __u16 UINT16; -typedef __u32 UINT32; -typedef __u64 UINT64; -typedef __s8 INT8; -typedef __s16 INT16; -typedef __s32 INT32; -typedef __s64 INT64; -#endif /* !STANDARD_INT_DEFINITIONS */ - -#define ENABLE_PROC_FS 1 - -#include <agldd/evk_lib.h> - -/** @addtogroup EV_in */ -/** @{ */ -/** In Linux2.4, list_for_each_entry is not provided, so it is prepared by self (in 2.6) - */ -#ifdef list_for_each_entry -#define __LINUX_26_OR_HIGHER -#endif - -#ifndef __LINUX_26_OR_HIGHER /* linux v2.4 */ - -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - prefetch(pos->member.next); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member), \ - prefetch(pos->member.next)) - -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -#else /* linux v2.6 */ - -#include <linux/jiffies.h> - -#endif /* linux v2.6 */ - -#define EVK_assert(cond, mesg) \ - if (!(cond)) { \ - printk(KERN_ALERT "[EVK]ASSERT(pid:%d): " #cond " at %s:%d; " \ - #mesg "\n", current->pid, __FILE__, __LINE__); \ - do {} while(1); \ - } - -#define EVK_BUG(mesg) \ - printk(KERN_ALERT "[EVK]BUG: " mesg); \ - do {} while(1); - -#if 0 -#define EVK_info0(s) printk(KERN_ALERT "[EVK]INFO: " s) -#define EVK_info1(s, t) printk(KERN_ALERT "[EVK]INFO: " s, t) -#else -#define EVK_info0(s) -#define EVK_info1(s, t) -#endif - -static int devmajor = EVK_DEV_MAJOR; -static int devminor = 0; -static int nrdevs = 1; -static struct cdev cdev; -static struct class *pClass; - -DEFINE_SEMAPHORE(evk_mtx); -static int down_pid; -static int down_line; -#define EVK_mutex_lock() { \ - down(&evk_mtx); \ - down_pid = current->pid; \ - down_line = __LINE__; \ -} -#define EVK_mutex_unlock() (up(&evk_mtx)) - -#ifdef EVK_USE_KMALLOC -#define evk_malloc(s) kmalloc((s), GFP_KERNEL) -#define evk_free kfree -#else // use vmalloc (this is the default) -#define evk_malloc(s) vmalloc((s)) -#define evk_free vfree -#endif - -enum { - evk_mem_user = 0, - evk_mem_kernel, -}; - -enum { - evk_enum_flag, - evk_enum_flag64, - evk_enum_queue, -}; - -#define GET_USER_OR_KERNEL(to, from) \ -({ \ - int err; \ - if (mem == evk_mem_user) { \ - err = __get_user((to), &(from)); \ - } else { \ - (to) = (from); \ - err = 0; \ - } \ - err; \ -}) - -#define PUT_USER_OR_KERNEL(value, to) \ -({ \ - int err; \ - if (mem == evk_mem_user) { \ - err = __put_user((value), &(to)); \ - } else { \ - (to) = (value); \ - err = 0; \ - } \ - err; \ -}) - - -/** @brief Common part of the flag structure and message queue structure */ -#define EVK_COMMON_QUEUE_ELEMS \ - struct list_head list; /**< List structure */ \ - wait_queue_head_t wq_head; /**< Wait_queue of a process waiting for a queue */\ - EV_ID queueID; /**< Flag ID/Queue ID */ \ - UINT32 seq_num; /**< Order of event arrival */ \ - pid_t read_pid; /**< Read process ID */ \ - pid_t pid; /**< Owning process ID */ - -/** @brief Common part of the flag structure and message queue structure */ -struct common_queue { - EVK_COMMON_QUEUE_ELEMS -}; - -/** @brief Flag structure */ -struct flag { - EVK_COMMON_QUEUE_ELEMS - UINT32 value;/**< Flags value */ -}; -#define EVK_PFLAG(queue) ((struct flag*)queue) - -/** @brief 64-bit flag structure */ -struct flag64 { - EVK_COMMON_QUEUE_ELEMS - UINT64 value;/**< Flags value */ -}; -#define EVK_PFLAG64(queue) ((struct flag64*)queue) - -/** @brief Message queue structure */ -struct message_queue { - EVK_COMMON_QUEUE_ELEMS - UINT8 type;/**< Type */ - UINT8 length;/**< Queue length */ - UINT8 num;/**< Number of messages stored */ - UINT8 readptr;/**< Next read position(0~length-1) */ - UINT32 max_bytes;/**< -Maximum bytes per message */ - UINT8 *message;/**< Message storage area (ring buffer) */ -}; -#define EVK_PQUEUE(queue) ((struct message_queue*)queue) - -/** @brief Number of bytes to allocate per message - * - * This function allocates an area to store the number of bytes actually stored, the time of occurrence, - * and the senderInfo, in addition to the number of bytes specified by max_bytes. - */ -#define EVK_message_block_size(max_bytes) (sizeof(UINT32) * 3 + (max_bytes)) - -#define HASH_KEY 15 - -/** @brief Maximum number of flags used by all systems */ -#define EVK_MAX_FLAGS 48 -/** @brief Maximum number of 64-bit flags used by all systems */ -#define EVK_MAX_FLAG64S 4 -/** @brief Maximum number of message event queues used by all systems */ -/* M1SP BM3547 MESSAGE_QUEUES 128->144 */ -/* M9AT BM2066 MESSAGE_QUEUES 144->218 */ -#define EVK_MAX_MESSAGE_QUEUES 224 - -/** @brief Allocate flag structure statically */ -static struct flag _flag_pool[EVK_MAX_FLAGS]; -/** @brief Statically allocates a 64-bit flag structure */ -static struct flag64 _flag64_pool[EVK_MAX_FLAG64S]; -/** @brief Beginning of the list of unused flags */ -static LIST_HEAD(flag_pool); -/** @brief Beginning of the list of unused 64-bit flags */ -static LIST_HEAD(flag64_pool); - -/** @brief Allocate message queue structure statically */ -static struct message_queue _message_queue_pool[EVK_MAX_MESSAGE_QUEUES]; -/** @brief Top of the list of unused message queues */ -static LIST_HEAD(message_queue_pool); - -/** @brief List of Flags/Message Queues in Use - * - * Connects the usage flag/message queue to a list for each hash value obtained from the ID. - * The hash value is the remainder of the ID divided by HASH_KEY. - */ -static struct list_head queue_entry[HASH_KEY]; - -/** @brief Sequence number to use during automatic ID assignment */ -static EV_ID sequence_id = 0; - -/** @brief Number to be assigned in order of occurrence of the event */ -static UINT32 sequence_number = 0; - -unsigned int -evk_get_queue_entry(struct list_head **entries) -{ - if (entries) { - *entries = queue_entry; - return HASH_KEY; - } - return 0; -} - -static __inline__ int -calc_hash(UINT32 val) -{ - return val % HASH_KEY; -} - -static __inline__ -struct flag * -alloc_flag(void) -{ - struct flag *queue; - //EVK_assert(!list_empty(&flag_pool), "flag pool empty"); - if (list_empty(&flag_pool)) { - printk("%s ERROR: flag pool empty\n", __func__); - return NULL; - } - queue = (struct flag *)flag_pool.next; - list_del_init(&(queue->list)); - return queue; -} - -static __inline__ -struct flag64 * -alloc_flag64(void) -{ - struct flag64 *queue; - //EVK_assert(!list_empty(&flag64_pool), "flag64 pool empty"); - if (list_empty(&flag64_pool)) { - printk("%s ERROR: flag64 pool empty\n", __func__); - return NULL; - } - queue = (struct flag64 *)flag64_pool.next; - list_del_init(&(queue->list)); - return queue; -} - -static __inline__ void -free_flag(struct flag *queue) -{ - list_add((struct list_head *)queue, &flag_pool); -} - -static __inline__ void -free_flag64(struct flag64 *queue) -{ - list_add((struct list_head *)queue, &flag64_pool); -} - -static __inline__ -struct message_queue * -alloc_message_queue(void) -{ - struct message_queue *queue; - //EVK_assert(!list_empty(&message_queue_pool), "message queue pool empty"); - if (list_empty(&message_queue_pool)) { - printk("%s ERROR: message queue pool empty\n", __func__); - return NULL; - } - queue = (struct message_queue *)message_queue_pool.next; - list_del_init(&(queue->list)); - queue->message = NULL; - return queue; -} - -static __inline__ void -free_message_queue(struct message_queue *queue) -{ - if (queue->message != NULL) { - evk_free(queue->message); - queue->message = NULL; - } - list_add((struct list_head *)queue, &message_queue_pool); -} - -static __inline__ -struct common_queue * -find_queue_entry(EV_ID queueID) -{ - struct list_head *list; - struct common_queue *queue; - int hash = calc_hash(queueID); - list = &(queue_entry[hash]); - list_for_each_entry(queue, list, list) { /* pgr0060 */ /* pgr0039 */ - if (queue->queueID == queueID) { - return queue; - } - } - return NULL; -} - -static __inline__ void -attach_queue_entry(struct common_queue *queue, EV_ID queueID) -{ - int hash = calc_hash(queueID); - list_add_tail((struct list_head *)queue, &(queue_entry[hash])); -} - -static __inline__ void -detach_queue_entry(struct common_queue *queue) -{ - list_del_init((struct list_head *)queue); -} - -static __inline__ void -init_common_queue(struct common_queue *queue, EV_ID queueID) -{ - queue->queueID = queueID; - queue->pid = current->pid; - queue->read_pid = 0; - init_waitqueue_head(&(queue->wq_head)); -} - -static __inline__ void -evk_init_flag(struct flag *queue, EV_ID queueID) -{ - init_common_queue((struct common_queue *)queue, queueID); - queue->value = 0; -} - -static __inline__ void -evk_init_flag64(struct flag64 *queue, EV_ID queueID) -{ - init_common_queue((struct common_queue *)queue, queueID); - queue->value = 0; -} - -static __inline__ int -evk_init_message_queue(struct message_queue *queue, EV_ID queueID, - UINT8 length, UINT32 max_bytes, UINT8 type) -{ - init_common_queue((struct common_queue *)queue, queueID); - queue->type = type; - queue->length = length; - queue->max_bytes = max_bytes; - queue->num = 0; - queue->readptr = 0; - EVK_assert(queue->message == NULL, "message buffer was not freed"); - queue->message = evk_malloc(length * EVK_message_block_size(max_bytes)); - EVK_assert(queue->message != NULL, "can't alloc message buffer"); - return 0; -} - -static void -__list_queues(void) -{ - struct list_head *list; - struct common_queue *queue; - int i; - for(i = 0 ; i < HASH_KEY ; i++) { - list = &(queue_entry[i]); - if (!list_empty(list)) { - printk(KERN_ALERT "%d->", i); - list_for_each_entry(queue, list, list) { /* pgr0060 */ /* pgr0039 */ - printk("%x[%x] ", queue->queueID, queue->seq_num); - } - printk("\n"); - } - } -} - -static int -evk_destroy_queue(EV_ID queueID) -{ - struct common_queue *queue; - int err = 0; - EVK_info1("flag destroy %x\n", queueID); - - EVK_mutex_lock(); /*************************************/ - queue = find_queue_entry(queueID); - if (queue == NULL) { - err = -ENOENT; - goto finish; - } - - detach_queue_entry(queue); - - /* wake up processes before destruction */ - wake_up_interruptible(&(queue->wq_head)); - - init_common_queue(queue, EV_INVALID_ID); - - if (EV_ID_IS_FLAG(queueID)) { - free_flag((struct flag *)queue); - } else if (EV_ID_IS_FLAG64(queueID)) { - free_flag64((struct flag64 *)queue); - } else if (EV_ID_IS_QUEUE(queueID)) { - free_message_queue((struct message_queue *)queue); - } - //__list_queues(); - finish: - EVK_mutex_unlock(); /*************************************/ - return err; -} - -static int -evk_open(struct inode *inode, struct file *file) -{ - // Recording of current and measures not to be read or deleted from others are required. */ - file->private_data = (void *)EV_INVALID_ID; - return 0; -} - -static int -evk_close(struct inode *inode, struct file *file) -{ - if (EV_ID_IS_VALID((EV_ID)file->private_data)) { - evk_destroy_queue((EV_ID)file->private_data); - } - file->private_data = (void *)EV_INVALID_ID; - return 0; -} - -static int -evk_create_flag(EV_ID queueID) -{ - struct flag *queue; - int err = 0; - EVK_info1("flag create %x\n", queueID); - - EVK_mutex_lock(); /*************************************/ - - queue = (struct flag *)find_queue_entry(queueID); - if (queue != NULL) { - err = -EEXIST; - goto finish; - } - - queue = alloc_flag(); - if (queue == NULL) { - err = -ENOMEM; - goto finish; - } - - evk_init_flag(queue, queueID); - attach_queue_entry((struct common_queue *)queue, queueID); - - //__list_queues(); - finish: - EVK_mutex_unlock(); /***********************************/ - return err; -} - -static int -evk_create_flag64(EV_ID queueID) -{ - struct flag64 *queue; - int err = 0; - EVK_info1("flag64 create %x\n", queueID); - - EVK_mutex_lock(); /*************************************/ - - queue = (struct flag64 *)find_queue_entry(queueID); - if (queue != NULL) { - err = -EEXIST; - goto finish; - } - - queue = alloc_flag64(); - if (queue == NULL) { - err = -ENOMEM; - goto finish; - } - - evk_init_flag64(queue, queueID); - attach_queue_entry((struct common_queue *)queue, queueID); - - //__list_queues(); - finish: - EVK_mutex_unlock(); /***********************************/ - return err; -} - -static int -evk_create_message_queue(EV_ID queueID, UINT8 length, - UINT32 max_bytes, EV_Message_Queue_Type type) -{ - struct message_queue *queue; - int err; - EVK_info1("message create %x\n", queueID); - - err = 0; - - EVK_mutex_lock(); /*************************************/ - - queue = (struct message_queue *)find_queue_entry(queueID); - if (queue != NULL) { - err = -EEXIST; - goto finish; - } - - queue = alloc_message_queue(); - if (queue == NULL) { - err = -ENOMEM; - goto finish; - } - - err = evk_init_message_queue(queue, queueID, length, max_bytes, type); - if (err == 0) { - attach_queue_entry((struct common_queue *)queue, queueID); - } else { - free_message_queue(queue); - } - - //__list_queues(); - finish: - EVK_mutex_unlock(); /***********************************/ - return err; -} - -static EV_ID -get_seq_id(void) -{ - EV_ID ret; - sequence_id++; - if ((sequence_id & EV_RESERVED_BIT) != 0) {/* round to 1 */ - sequence_id = 1; - EVK_info0("auto ID rounded\n"); - } - ret = sequence_id; - return ret; -} - -static int -evk_alloc_flagID(EV_ID *queueID) -{ - EV_ID seq_id; - - EVK_mutex_lock(); /*************************************/ - do { - seq_id = get_seq_id(); - seq_id |= (EV_ID_BIT | EV_FLAG_BIT | EV_AUTO_ID_BIT); - } while(find_queue_entry(seq_id) != NULL); - EVK_mutex_unlock(); /*************************************/ - - *queueID = seq_id; - return 0; -} - -static int -evk_alloc_flag64ID(EV_ID *queueID) -{ - EV_ID seq_id; - - EVK_mutex_lock(); /*************************************/ - do { - seq_id = get_seq_id(); - seq_id |= (EV_ID_BIT | EV_FLAG64_BIT | EV_AUTO_ID_BIT); - } while(find_queue_entry(seq_id) != NULL); - EVK_mutex_unlock(); /*************************************/ - - *queueID = seq_id; - return 0; -} - -static int -evk_alloc_queueID(EV_ID *queueID) -{ - EV_ID seq_id; - - EVK_mutex_lock(); /*************************************/ - do { - seq_id = get_seq_id(); - seq_id |= (EV_ID_BIT | EV_QUEUE_BIT | EV_AUTO_ID_BIT); - } while(find_queue_entry(seq_id) != NULL); - EVK_mutex_unlock(); /*************************************/ - - *queueID = seq_id; - return 0; -} - -static int -evk_store_flag(EV_Flag *ev, int mem) -{ - struct flag *queue; - int ret = 0; - EV_ID flagID; - UINT32 bits; - - if (GET_USER_OR_KERNEL(flagID, ev->flagID)) /* pgr0039 */ - return -EFAULT; - if (GET_USER_OR_KERNEL(bits, ev->bits)) /* pgr0039 */ - return -EFAULT; - - EVK_mutex_lock(); /*************************************/ - - queue = (struct flag *)find_queue_entry(flagID); /* pgr0000 */ - if (queue == NULL) { - EVK_info1("set_flag: No such ID %x\n", flagID); - ret = -ENOENT; - goto finish; - } - - if (queue->value == 0) { - queue->seq_num = sequence_number++; - } - queue->value |= bits; /* pgr0000 */ - - wake_up_interruptible(&(queue->wq_head)); - - finish: - EVK_mutex_unlock(); /***********************************/ - return ret; -} - -static int -evk_store_flag64(EV_Flag64 *ev, int mem) -{ - struct flag64 *queue; - int ret = 0; - EV_ID flagID; - UINT64 bits = 0; - - if (GET_USER_OR_KERNEL(flagID, ev->flagID)) /* pgr0039 */ - return -EFAULT; - //GET_USER_OR_KERNEL(bits, ev->bits); /* pgr0039 */ - if (mem == evk_mem_user) { - if (copy_from_user(&bits, &(ev->bits), sizeof(bits))) - return -EFAULT; - } else { - bits = ev->bits; - } - - EVK_mutex_lock(); /*************************************/ - - queue = (struct flag64 *)find_queue_entry(flagID); /* pgr0000 */ - if (queue == NULL) { - EVK_info1("set_flag64: No such ID %x\n", flagID); - ret = -ENOENT; - goto finish; - } - - if (queue->value == 0) { - queue->seq_num = sequence_number++; - } - queue->value |= bits; /* pgr0000 */ - - wake_up_interruptible(&(queue->wq_head)); - - finish: - EVK_mutex_unlock(); /***********************************/ - return ret; -} - -static int -evk_store_message(EV_Message *ev, int mem) -{ - struct message_queue *queue; - UINT8 *ptr; - UINT8 writeptr; - int ret = 0; - EV_ID queueID; - UINT32 length, senderInfo, seq; - - if (GET_USER_OR_KERNEL(queueID, ev->queueID)) /* pgr0039 */ - return -EFAULT; - if (GET_USER_OR_KERNEL(length, ev->length)) /* pgr0039 */ - return -EFAULT; - if (GET_USER_OR_KERNEL(senderInfo, ev->senderInfo)) /* pgr0039 */ - return -EFAULT; - - EVK_mutex_lock(); /*************************************/ - - queue = (struct message_queue *)find_queue_entry(queueID); /* pgr0000 */ - if (queue == NULL) { - EVK_info1("store_message: No such queueID %x\n", queueID); - ret = -ENOENT; - goto finish; - } - - if (length > queue->max_bytes) { /* pgr0000 */ - EVK_info0("store_message: message is too long for the queue"); - ret = -EINVAL; - goto finish; - } - - if (queue->num == queue->length) { - - switch(queue->type) { - case EV_MESSAGE_QUEUE_TYPE_BUSY: - EVK_info1("store_message: queue %x BUSY\n", queueID); - ret = -EBUSY; - goto finish; - break; - - case EV_MESSAGE_QUEUE_TYPE_FIFO: - queue->readptr++; - queue->readptr %= queue->length; - queue->num--; - break; - - case EV_MESSAGE_QUEUE_TYPE_REPLACE: - queue->num--; - break; - - default: - EVK_BUG("internal error in store_message\n"); - ret = -EINVAL; - goto finish; - break; - } - } - - writeptr = (queue->readptr + queue->num) % queue->length; - ptr = queue->message + writeptr * EVK_message_block_size(queue->max_bytes); - - memcpy(ptr, &length, sizeof(length)); - ptr += sizeof(length); - memcpy(ptr, &senderInfo, sizeof(senderInfo)); - ptr += sizeof(senderInfo); - seq = sequence_number++; - memcpy(ptr, &seq, sizeof(seq)); - ptr += sizeof(seq); - - if (queue->num == 0) { - queue->seq_num = seq; - } - queue->num++; - - if (mem == evk_mem_user) { - if (copy_from_user(ptr, ev->message, length)) { - ret = -EFAULT; - goto finish; - } - } else { - memcpy(ptr, ev->message, length); - } - - wake_up_interruptible(&(queue->wq_head)); - - finish: - EVK_mutex_unlock(); /***********************************/ - - return ret; -} - -static int -evk_set_poll(struct file *filp, EV_ID queueID) -{ - struct common_queue *queue; - int err = 0; - - EVK_mutex_lock(); /*************************************/ - - queue = find_queue_entry(queueID); - if (queue == NULL) { - EVK_info1("set_poll: ID %x not found.\n", queueID); - err = -ENOENT; - goto finish; - } - - filp->private_data = (void *)queueID; - - finish: - EVK_mutex_unlock(); /*************************************/ - return err; -} - -static int -evk_get_flag_event(EV_Event *ev, int peek_only, int wait, int mem) -{ - struct flag *queue, *queue2; - int err = 0; - int found = 0; - EV_ID flagID; - - if (GET_USER_OR_KERNEL(flagID, ev->u.flag.flagID)) /* pgr0039 */ - return -EFAULT; - - retry: - - queue = (struct flag *)find_queue_entry(flagID); /* pgr0000 */ - if (queue == NULL) { - EVK_info1("get_flag: No such flag %x\n", flagID); - err = -ENOENT; - goto finish; - } - - if (queue->value != 0) { - UINT32 bits; - - if (GET_USER_OR_KERNEL(bits, ev->u.flag.bits)) { /* pgr0039 */ - err = -EFAULT; - goto finish; - } - - if (bits == 0 || ((bits & queue->value) != 0)) { /* pgr0000 */ - - if (PUT_USER_OR_KERNEL(EV_EVENT_Flag, ev->type)) { /* pgr0039 */ - err = -EFAULT; - goto finish; - } - if (PUT_USER_OR_KERNEL(queue->value, ev->u.flag.bits)) { /* pgr0039 */ - err = -EFAULT; - goto finish; - } - found = 1; - - queue->read_pid = current->pid; - if (peek_only) { - ; - } else { - queue->value = 0; - } - } - } - finish: - - if (queue != NULL && wait != 0 && found == 0) { - int wait_ret; - EVK_mutex_unlock(); /*************************************/ - - wait_ret - = wait_event_interruptible(queue->wq_head, - ((queue2 = (struct flag *)find_queue_entry(flagID)) == NULL - || queue2->value != 0)); - - EVK_mutex_lock(); /*************************************/ - - if (wait_ret != 0) { - EVK_info1("Interrupted while waiting for flag %x\n", flagID); - err = -EINTR; - } else if (queue2 == NULL) { /* pgr0039 */ - EVK_info1("flag %x was destroyed while waiting for it\n", flagID); - err = -ENOENT; - } else { - goto retry; - } - } - return err; -} - -static int -evk_get_flag64_event(EV_Event *ev, int peek_only, int wait, int mem) -{ - struct flag64 *queue, *queue2; - int err = 0; - int found = 0; - EV_ID flagID; - - if (GET_USER_OR_KERNEL(flagID, ev->u.flag64.flagID)) /* pgr0039 */ - return -EFAULT; - - retry: - - queue = (struct flag64 *)find_queue_entry(flagID); /* pgr0000 */ - if (queue == NULL) { - EVK_info1("get_flag64: No such flag %x\n", flagID); - err = -ENOENT; - goto finish; - } - - if (queue->value != 0) { - UINT64 bits = 0; - - //GET_USER_OR_KERNEL(bits, ev->u.flag64.bits); /* pgr0039 */ - if (mem == evk_mem_user) { - if (copy_from_user(&bits, &(ev->u.flag64.bits), sizeof(bits))) { - err = -EFAULT; - goto finish; - } - } else { - bits = ev->u.flag64.bits; - } - - if (bits == 0 || ((bits & queue->value) != 0)) { /* pgr0000 */ - - if (PUT_USER_OR_KERNEL(EV_EVENT_Flag64, ev->type)) { /* pgr0039 */ - err = -EFAULT; - goto finish; - } - if (PUT_USER_OR_KERNEL(queue->value, ev->u.flag64.bits)) { /* pgr0039 */ - err = -EFAULT; - goto finish; - } - found = 1; - - queue->read_pid = current->pid; - if (peek_only) { - ; - } else { - queue->value = 0; - } - } - } - finish: - - if (queue != NULL && wait != 0 && found == 0) { - int wait_ret; - EVK_mutex_unlock(); /*************************************/ - - wait_ret - = wait_event_interruptible(queue->wq_head, - ((queue2 = (struct flag64 *)find_queue_entry(flagID)) == NULL - || queue2->value != 0)); - - EVK_mutex_lock(); /*************************************/ - - if (wait_ret != 0) { - EVK_info1("Interrupted while waiting for flag %x\n", flagID); - err = -EINTR; - } else if (queue2 == NULL) { /* pgr0039 */ - EVK_info1("flag %x was destroyed while waiting for it\n", flagID); - err = -ENOENT; - } else { - goto retry; - } - } - return err; -} - -static __inline__ void -remove_message_event(struct message_queue *queue, UINT8 removeptr) -{ - UINT8 *ptr; - int i, from, to; - UINT8 *pFrom, *pTo; - UINT32 size; - int offset; - - queue->num--; - offset = (int)removeptr - (int)(queue->readptr); - - if (offset == 0) {/* To remove the head of the queue, advance the queue by one readptr only */ - queue->readptr++; - queue->readptr %= queue->length; - - if (queue->num > 0) { - /* Reset the occurrence time of the first message in the queue to the occurrence time of the queue. */ - ptr = (queue->message - + queue->readptr * EVK_message_block_size(queue->max_bytes)); - ptr += sizeof(UINT32) * 2; - memcpy(&(queue->seq_num), ptr, sizeof(UINT32)); - } - return; - } - if (offset < 0) { - offset += queue->length; - } - if (offset == queue->num) {/* Do nothing to delete the end of the queue */ - return; - } - - /* To delete a message in the middle of the queue, pack the following messages. */ - to = removeptr; - size = EVK_message_block_size(queue->max_bytes); - - for(i = 0 ; i < queue->num - offset ; i++, to++) { - to %= queue->length; - from = (to + 1) % queue->length; - pFrom = queue->message + from * size; - pTo = queue->message + to * size; - memcpy(pTo, pFrom, size); - } -} - -static int -evk_get_message_event(EV_Event *ev, int peek_only, int wait, int mem) -{ - struct message_queue *queue, *queue2; - int err = 0; - EV_ID queueID; - UINT8 num; - UINT8 readptr; - UINT8 i, *ptr; - int matched = 0; - - if (GET_USER_OR_KERNEL(queueID, ev->u.message.queueID)) /* pgr0039 */ - return -EFAULT; - - retry: - queue = (struct message_queue *)find_queue_entry(queueID); /* pgr0000 */ - if (queue == NULL) { - EVK_info1("get_message: No such queue %x\n", queueID); - err = -ENOENT; - goto finish; - } - - num = queue->num; - readptr = queue->readptr; - for(i = 0 ; i < num ; i++, readptr = (readptr + 1) % queue->length) { - UINT32 size, senderInfo, seq; - UINT32 length, q_senderInfo; - - ptr = (queue->message - + readptr * EVK_message_block_size(queue->max_bytes)); - - memcpy(&size, ptr, sizeof(size)); - ptr += sizeof(size); - memcpy(&senderInfo, ptr, sizeof(senderInfo)); - ptr += sizeof(senderInfo); - memcpy(&seq, ptr, sizeof(seq)); - ptr += sizeof(seq); - - if (GET_USER_OR_KERNEL(length, ev->u.message.length)) { /* pgr0039 */ - err = -EFAULT; - goto finish; - } - if (GET_USER_OR_KERNEL(q_senderInfo, ev->u.message.senderInfo)) { /* pgr0039 */ - err = -EFAULT; - goto finish; - } - - if (q_senderInfo == 0 && length == 0) { /* pgr0000 */ - matched = 1; - } else if (q_senderInfo != 0 && q_senderInfo == senderInfo) { - matched = 1; - } else if (length > 0 && size >= length) { /* pgr0000 */ - - if (mem == evk_mem_user) { - void *compbytes; - compbytes = evk_malloc(length); - if (compbytes != NULL) { - if (copy_from_user(compbytes, &(ev->u.message.message), length)) { - err = -EFAULT; - evk_free(compbytes); - goto finish; - } - if (memcmp(ptr, compbytes, length) == 0) { - matched = 1; - } - evk_free(compbytes); - } - } else { - if (memcmp(ptr, ev->u.message.message, length) == 0) { - matched = 1; - } - } - } - - if (matched) { - - if (PUT_USER_OR_KERNEL(EV_EVENT_Message, ev->type)) { /* pgr0039 */ - err = -EFAULT; - goto finish; - } - if (PUT_USER_OR_KERNEL(size, ev->u.message.length)) { /* pgr0039 */ - err = -EFAULT; - goto finish; - } - if (PUT_USER_OR_KERNEL(senderInfo, ev->u.message.senderInfo)) { /* pgr0039 */ - err = -EFAULT; - goto finish; - } - if (mem == evk_mem_user) { - if (copy_to_user(ev->u.message.message, ptr, size)) { - err = -EFAULT; - goto finish; - } - } else { - memcpy(ev->u.message.message, ptr, size); - } - - queue->read_pid = current->pid; - if (peek_only) { - ; - } else { - remove_message_event(queue, readptr); - } - goto finish; - } - } - - finish: - - if (queue != NULL && wait != 0 && matched == 0) { - int wait_ret; - EVK_mutex_unlock(); /*************************************/ - wait_ret - = wait_event_interruptible(queue->wq_head, - ((queue2 = (struct message_queue *)find_queue_entry(queueID))==NULL - || queue2->num > 0)); - - EVK_mutex_lock(); /*************************************/ - - if (wait_ret != 0) { - EVK_info1("Interrupted while waiting for queue %x\n", queueID); - err = -EINTR; - } else if (queue2 == NULL) { /* pgr0039 */ - EVK_info1("queue %x was destroyed while waiting for it\n", queueID); - err = -ENOENT; - } else { - goto retry; - } - } - - return err; -} - -static int -evk_get_event(EV_Event *ev, int peek_only, int wait, int mem) -{ - EV_Type type; - int ret = -EINVAL; - - if (GET_USER_OR_KERNEL(type, ev->type)) /* pgr0039 */ - return -EFAULT; - if (PUT_USER_OR_KERNEL(EV_EVENT_None, ev->type)) /* pgr0039 */ - return -EFAULT; - - switch(type) { /* pgr0000 */ - case EV_EVENT_Flag: - EVK_mutex_lock(); /*************************************/ - ret = evk_get_flag_event(ev, peek_only, wait, mem); - EVK_mutex_unlock(); /*************************************/ - break; - - case EV_EVENT_Flag64: - EVK_mutex_lock(); /*************************************/ - ret = evk_get_flag64_event(ev, peek_only, wait, mem); - EVK_mutex_unlock(); /*************************************/ - break; - - case EV_EVENT_Message: - EVK_mutex_lock(); /*************************************/ - ret = evk_get_message_event(ev, peek_only, wait, mem); - EVK_mutex_unlock(); /*************************************/ - break; - - default: - break; - } - return ret; -} - -static int -evk_get_next_event(EVK_Next_Event_Query *query /* user */, int peek_only) -{ - EV_ID *ids; - int i, num, ret, first, found; - struct common_queue *queue; - UINT32 seq_oldest = 0; - - ids = (EV_ID *)kmalloc( (sizeof(EV_ID)*EV_MAX_IDS_IN_PROCESS), GFP_KERNEL ); - if( ids == NULL ){ - return -ENOMEM; - } - - if (__get_user(num, &(query->num))) { /* pgr0039 */ - ret = -EFAULT; - goto finish0; - } - if (copy_from_user(&ids[0], query->ids, num * sizeof(EV_ID))) { /* pgr0039 */ - ret = -EFAULT; - goto finish0; - } - if (__put_user(EV_EVENT_None, &(query->ev.type))) { /* pgr0039 */ - ret = -EFAULT; - goto finish0; - } - - ret = 0; - first = 1; - found = -1; - - EVK_mutex_lock(); /*************************************/ - - for(i = 0 ; i < num /* pgr0039 */ ; i++) { - queue = find_queue_entry(ids[i]); - if (queue != NULL) {/* Have the specified queue ID */ - if ((EV_ID_IS_FLAG(ids[i]) - && ((struct flag *)queue)->value != 0) - || (EV_ID_IS_FLAG64(ids[i]) - && ((struct flag64 *)queue)->value != 0) - || (EV_ID_IS_QUEUE(ids[i]) - && ((struct message_queue *)queue)->num > 0)) {/*There are events.*/ - /* Compare with time_before macros for round 0 */ - if (first || time_before((unsigned long)queue->seq_num, /* pgr0006 */ /* pgr0039 */ - (unsigned long)seq_oldest)) { - first = 0; - seq_oldest = queue->seq_num; - found = i; - } - } - } - } - - if (found >= 0) { - if (EV_ID_IS_FLAG(ids[found])) { - if (__put_user(ids[found], &(query->ev.u.flag.flagID))) { /* pgr0039 */ - ret = -EFAULT; - goto finish1; - } - ret = evk_get_flag_event(&(query->ev), peek_only, 0, evk_mem_user); - } else if (EV_ID_IS_FLAG64(ids[found])) { - if (__put_user(ids[found], &(query->ev.u.flag64.flagID))) { /* pgr0039 */ - ret = -EFAULT; - goto finish1; - } - ret = evk_get_flag64_event(&(query->ev), peek_only, 0, evk_mem_user); - } else if (EV_ID_IS_QUEUE(ids[found])) { - if (__put_user(ids[found], &(query->ev.u.message.queueID))) { /* pgr0039 */ - ret = -EFAULT; - goto finish1; - } - ret = evk_get_message_event(&(query->ev), peek_only, 0, evk_mem_user); - } - } - - finish1: - EVK_mutex_unlock(); /*************************************/ - finish0: - kfree(ids); - return ret; -} - -static long -evk_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - EVK_Message_Queue_Request mesq; - int peek_only, wait; - EV_ID queueID; - int ret = -EINVAL; - - //lock_kernel(); - - switch(cmd) { - case EVK_IOC_CREATE_FLAG: - queueID = (EV_ID)arg; - ret = evk_create_flag(queueID); - break; - - case EVK_IOC_CREATE_FLAG64: - queueID = (EV_ID)arg; - ret = evk_create_flag64(queueID); - break; - - case EVK_IOC_CREATE_MESSAGE_QUEUE: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - if (access_ok(arg, sizeof(mesq))) { /* pgr0039 */ -#else - if (access_ok(VERIFY_READ, arg, sizeof(mesq))) { /* pgr0039 */ -#endif - if (copy_from_user(&mesq, (EV_Flag *)arg, sizeof(mesq))) { - ret = -EFAULT; - break; - } - - ret = evk_create_message_queue(mesq.queueID, mesq.length, - mesq.max_bytes, mesq.type); - } else { - ret = -EFAULT; - } - break; - - case EVK_IOC_ALLOC_FLAG_ID: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - if (access_ok(arg, sizeof(queueID))) { /* pgr0039 */ -#else - if (access_ok(VERIFY_WRITE, arg, sizeof(queueID))) { /* pgr0039 */ -#endif - evk_alloc_flagID(&queueID); - if (put_user(queueID, (EV_ID *)arg)) { /* pgr0039 */ - ret = -EFAULT; - break; - } - ret = 0; - } else { - ret = -EFAULT; - } - break; - - case EVK_IOC_ALLOC_FLAG64_ID: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - if (access_ok(arg, sizeof(queueID))) { /* pgr0039 */ -#else - if (access_ok(VERIFY_WRITE, arg, sizeof(queueID))) { /* pgr0039 */ -#endif - evk_alloc_flag64ID(&queueID); - if (put_user(queueID, (EV_ID *)arg)) { /* pgr0039 */ - ret = -EFAULT; - break; - } - ret = 0; - } else { - ret = -EFAULT; - } - break; - - case EVK_IOC_ALLOC_QUEUE_ID: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - if (access_ok(arg, sizeof(queueID))) { /* pgr0039 */ -#else - if (access_ok(VERIFY_WRITE, arg, sizeof(queueID))) { /* pgr0039 */ -#endif - evk_alloc_queueID(&queueID); - if (put_user(queueID, (EV_ID *)arg)) { /* pgr0039 */ - ret = -EFAULT; - break; - } - ret = 0; - } else { - ret = -EFAULT; - } - break; - - case EVK_IOC_DESTROY_QUEUE: - queueID = (EV_ID)arg; - ret = evk_destroy_queue(queueID); - break; - - case EVK_IOC_STORE_FLAG: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - if (access_ok(arg, sizeof(EV_Flag))) { /* pgr0039 */ -#else - if (access_ok(VERIFY_READ, arg, sizeof(EV_Flag))) { /* pgr0039 */ -#endif - ret = evk_store_flag((EV_Flag *)arg, evk_mem_user); - } else { - ret = -EFAULT; - } - break; - - case EVK_IOC_STORE_FLAG64: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - if (access_ok(arg, sizeof(EV_Flag64))) { /* pgr0039 */ -#else - if (access_ok(VERIFY_READ, arg, sizeof(EV_Flag64))) { /* pgr0039 */ -#endif - ret = evk_store_flag64((EV_Flag64 *)arg, evk_mem_user); - } else { - ret = -EFAULT; - } - break; - - case EVK_IOC_STORE_MESSAGE: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - if (access_ok(arg, sizeof(EV_Message))) { /* pgr0039 */ -#else - if (access_ok(VERIFY_READ, arg, sizeof(EV_Message))) { /* pgr0039 */ -#endif - ret = evk_store_message((EV_Message *)arg, evk_mem_user); - } else { - ret = -EFAULT; - } - break; - - case EVK_IOC_SET_POLL: - queueID = (EV_ID)arg; - ret = evk_set_poll(filp, queueID); - break; - - case EVK_IOC_PEEK_EVENT: - peek_only = 1; - wait = 0; - goto get_event; - break; - - case EVK_IOC_WAIT_EVENT: - peek_only = 0; - wait = 1; - goto get_event; - break; - - case EVK_IOC_GET_EVENT: - peek_only = 0; - wait = 0; - get_event: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - if (access_ok(arg, sizeof(EV_Event))) { /* pgr0039 */ -#else - if (access_ok(VERIFY_WRITE, arg, sizeof(EV_Event))) { /* pgr0039 */ -#endif - ret = evk_get_event((EV_Event *)arg, peek_only, wait, evk_mem_user); - } else { - ret = -EFAULT; - } - break; - - case EVK_IOC_PEEK_NEXT_EVENT: - peek_only = 1; - goto get_next; - break; - - case EVK_IOC_GET_NEXT_EVENT: - peek_only = 0; - get_next: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - if (access_ok(arg, sizeof(EVK_Next_Event_Query))) { /* pgr0039 */ -#else - if (access_ok(VERIFY_WRITE, arg, sizeof(EVK_Next_Event_Query))) { /* pgr0039 */ -#endif - ret = evk_get_next_event((EVK_Next_Event_Query *)arg, peek_only); - } else { - ret = -EFAULT; - } - break; - - case EVK_IOC_DEBUG_LIST: - __list_queues(); - //__list_message(); - ret = 0; - break; - - default: - ret = -EINVAL; - break; - } - - //unlock_kernel(); - return ret; -} - -static unsigned int -evk_poll(struct file *filp, poll_table *wait) -{ - unsigned int ret = 0; - struct common_queue *queue; - - EV_ID queueID = (EV_ID)(filp->private_data); - // Returns errors without stopping at assert if queueID is invalid - // (Troubleshooting for Continuous Printing) - if (!EV_ID_IS_VALID(queueID)) { - printk("evk_poll ERROR: invalid queueID=%x\n", queueID); - return POLLERR|POLLHUP; - } - //EVK_assert(EV_ID_IS_VALID(queueID), "poll: flag/queueID not set"); - - EVK_mutex_lock();/*****************************************/ - - queue = find_queue_entry(queueID); - if (queue == NULL) { - EVK_info1("poll: No such flag/queueID %x\n", queueID); - ret = POLLERR|POLLHUP; - goto finish; - } - - poll_wait(filp, &(queue->wq_head), wait); - - if (EV_ID_IS_FLAG(queueID)) { - if (((struct flag *)queue)->value != 0) { - ret = POLLIN; - } - } else if (EV_ID_IS_FLAG64(queueID)) { - if (((struct flag64 *)queue)->value != 0) { - ret = POLLIN; - } - } else { - if (((struct message_queue *)queue)->num > 0) { - ret = POLLIN; - } - } - - finish: - EVK_mutex_unlock(); /***************************************/ - - return ret; -} - -/** List of system call corresponding function registrations */ -static struct file_operations evk_fops = { - .open = evk_open, - .release = evk_close, - .unlocked_ioctl = evk_ioctl, - .poll = evk_poll, -}; - -#ifdef ENABLE_PROC_FS -static int -evk_procFS_show(struct seq_file *m, int mode) -{ - int i, num; - struct list_head *list, *entries; - struct common_queue *queue; - - seq_printf(m, "[ev library status "); - - switch(mode) { - case evk_enum_flag: - seq_printf(m, "(flag)]\n"); - seq_printf(m, "PID moduleID flagID[hash] value\n"); - break; - case evk_enum_flag64: - seq_printf(m, "(flag64)]\n"); - seq_printf(m, "PID moduleID flagID[hash] value\n"); - break; - case evk_enum_queue: - seq_printf(m, "(queue)]\n"); - seq_printf(m, "PID moduleID queueID[hash] maxbytes remain type\n"); - break; - } - - EVK_mutex_lock(); - - num = evk_get_queue_entry(&entries); - - for (i = 0 ; i < num ; i++) { - list = &(entries[i]); - if (!list_empty(list)) { - list_for_each_entry(queue, list, list) { - if ((mode == evk_enum_flag && (!EV_ID_IS_FLAG(queue->queueID))) - || (mode == evk_enum_flag64 && (!EV_ID_IS_FLAG64(queue->queueID))) - || (mode == evk_enum_queue && (!EV_ID_IS_QUEUE(queue->queueID)))) - { - continue; - } - - seq_printf(m, "%08d ", queue->pid); - seq_printf(m, "%05d(%04x) ", ((queue->queueID & 0x00ffff00) >> 8), ((queue->queueID & 0x00ffff00) >> 8)); - seq_printf(m, "0x%08x[%2d] ", queue->queueID, calc_hash(queue->queueID)); - - switch(mode) { - case evk_enum_flag: - seq_printf(m, "0x%x", EVK_PFLAG(queue)->value); - break; - - case evk_enum_flag64: - seq_printf(m, "0x%llx", EVK_PFLAG64(queue)->value); - break; - - case evk_enum_queue: - seq_printf(m, "%04d %02d ", EVK_PQUEUE(queue)->max_bytes, EVK_PQUEUE(queue)->length); - seq_printf(m, "%02d ", EVK_PQUEUE(queue)->num); - seq_printf(m, "%d ", EVK_PQUEUE(queue)->type); - break; - } - seq_printf(m, "\n"); - } - } - } - - EVK_mutex_unlock(); - return 0; -} - -static int -evk_procFS_flag_show(struct seq_file *m, void *v) -{ - return evk_procFS_show(m, evk_enum_flag); -} - -static int -evk_procFS_flag64_show(struct seq_file *m, void *v) -{ - return evk_procFS_show(m, evk_enum_flag64); -} - -static int -evk_procFS_queue_show(struct seq_file *m, void *v) -{ - return evk_procFS_show(m, evk_enum_queue); -} - -static int -evk_procFS_flag_open(struct inode *inode, struct file *file) -{ - return single_open(file, evk_procFS_flag_show, NULL); -} - -static int -evk_procFS_flag64_open(struct inode *inode, struct file *file) -{ - return single_open(file, evk_procFS_flag64_show, NULL); -} - -static int -evk_procFS_queue_open(struct inode *inode, struct file *file) -{ - return single_open(file, evk_procFS_queue_show, NULL); -} - -static struct file_operations evk_proc_flag_fops = { - .owner = THIS_MODULE, - .open = evk_procFS_flag_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static struct file_operations evk_proc_flag64_fops = { - .owner = THIS_MODULE, - .open = evk_procFS_flag64_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static struct file_operations evk_proc_queue_fops = { - .owner = THIS_MODULE, - .open = evk_procFS_queue_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif /*ENABLE_PROC_FS*/ - -__init int -EVK_init(void) -{ - int err; -#ifdef CONFIG_PROC_FS -#ifdef ENABLE_PROC_FS - struct proc_dir_entry *ret; -#endif /* ENABLE_PROC_FS */ -#endif /* CONFIG_PROC_FS */ - int i; - dev_t dev; - - dev = MKDEV(devmajor, devminor); - err = register_chrdev_region(dev, nrdevs, EVK_NAME); - if (err) { - EVK_info1("register_chrdev_region error %d\n", -err); - return -EBUSY; - } - - cdev_init(&cdev, &evk_fops); - cdev.owner = THIS_MODULE; - cdev.ops = &evk_fops; - - err = cdev_add(&cdev, dev, 1); - if (err) { - EVK_info1("cdev_add error %d\n", -err); - return -EBUSY; - } - - /* Initialization */ - for(i = 0 ; i < EVK_MAX_FLAGS ; i++) { - list_add_tail((struct list_head *)&(_flag_pool[i]), - &flag_pool); - } - for(i = 0 ; i < EVK_MAX_FLAG64S ; i++) { - list_add_tail((struct list_head *)&(_flag64_pool[i]), - &flag64_pool); - } - for(i = 0 ; i < EVK_MAX_MESSAGE_QUEUES ; i++) { - list_add_tail((struct list_head *)&(_message_queue_pool[i]), - &message_queue_pool); - } - for(i = 0 ; i < HASH_KEY ; i++) { - INIT_LIST_HEAD(&(queue_entry[i])); - } - -#ifdef CONFIG_PROC_FS -#ifdef ENABLE_PROC_FS - ret = proc_create("driver/ev_flag", 0, NULL, &evk_proc_flag_fops); - if( ret == NULL ) { - EVK_info1("Unable to initialize /proc entry %d\n", -err); - return -EBUSY; - } - - ret = proc_create("driver/ev_flag64", 0, NULL, &evk_proc_flag64_fops); - if( ret == NULL ) { - EVK_info1("Unable to initialize /proc entry %d\n", -err); - return -EBUSY; - } - - ret = proc_create("driver/ev_queue", 0, NULL, &evk_proc_queue_fops); - if( ret == NULL ) { - EVK_info1("Unable to initialize /proc entry %d\n", -err); - return -EBUSY; - } -#endif /* ENABLE_PROC_FS */ -#endif /* CONFIG_PROC_FS */ - - pClass = class_create(THIS_MODULE, EVK_NAME); - device_create(pClass, NULL, dev, NULL, "agl/"EVK_NAME); - - return 0; -} - -void -//#ifndef CONFIG_COMBINE_MODULES -//__exit -//#endif -EVK_exit(void) -{ - dev_t dev = MKDEV(devmajor, devminor); - device_destroy(pClass, dev); - class_destroy(pClass); - - cdev_del(&cdev); - - unregister_chrdev_region(dev, nrdevs); - - remove_proc_entry( "driver/ev_flag", 0 ); - remove_proc_entry( "driver/ev_flag64", 0 ); - remove_proc_entry( "driver/ev_queue", 0 ); -} - -/** @} */ -/** @addtogroup EV - * @{ */ -static EV_ERR -EVK_create_flag_in(EV_ID flagID) -{ - int ret = evk_create_flag(flagID); - - if (ret == -EEXIST) { - return EV_ERR_Exist; - } else if (ret < 0) { - return EV_ERR_Fatal; - } else { - return EV_OK; - } -} - -static EV_ERR -EVK_create_flag64_in(EV_ID flagID) -{ - int ret = evk_create_flag64(flagID); - - if (ret == -EEXIST) { - return EV_ERR_Exist; - } else if (ret < 0) { - return EV_ERR_Fatal; - } else { - return EV_OK; - } -} - -/** @see EV_create_flag */ -EV_ERR -EVK_create_flag(EV_ID flagID) -{ - if (!EV_ID_IS_FLAG(flagID) || EV_ID_IS_AUTO_ID(flagID)) { - return EV_ERR_Invalid_ID; - } - return EVK_create_flag_in(flagID); -} - -/** @see EV_create_flag64 */ -EV_ERR -EVK_create_flag64(EV_ID flagID) -{ - if (!EV_ID_IS_FLAG64(flagID) || EV_ID_IS_AUTO_ID(flagID)) { - return EV_ERR_Invalid_ID; - } - return EVK_create_flag64_in(flagID); -} - -static EV_ERR -EVK_create_queue_in(EV_ID queueID, UINT8 length, UINT16 max_bytes, - EV_Message_Queue_Type type) -{ - int ret = evk_create_message_queue(queueID, length, max_bytes, type); - - if (ret == -EEXIST) { - return EV_ERR_Exist; - } else if (ret < 0) { - return EV_ERR_Fatal; - } else { - return EV_OK; - } -} - -/** @see EV_create_queue */ -EV_ERR -EVK_create_queue(EV_ID queueID, UINT8 length, UINT16 max_bytes, - EV_Message_Queue_Type type) -{ - if (!EV_ID_IS_QUEUE(queueID) || EV_ID_IS_AUTO_ID(queueID)) { - return EV_ERR_Invalid_ID; - } - return EVK_create_queue_in(queueID, length, max_bytes, type); -} - -/** @see EV_create_flag_auto_id */ -EV_ERR -EVK_create_flag_auto_id(/* OUT */EV_ID *flagID) -{ - EV_ERR err; - EVK_assert(flagID != NULL, "NULL pointer was specified"); - - if (evk_alloc_flagID(flagID) < 0) { - return EV_ERR_Fatal; - } - - err = EVK_create_flag_in(*flagID); - if (err != EV_OK) { - *flagID = EV_NO_ID; - } - return err; -} - -/** @see EV_create_flag64_auto_id */ -EV_ERR -EVK_create_flag64_auto_id(/* OUT */EV_ID *flagID) -{ - EV_ERR err; - EVK_assert(flagID != NULL, "NULL pointer was specified"); - - if (evk_alloc_flag64ID(flagID) < 0) { - return EV_ERR_Fatal; - } - - err = EVK_create_flag64_in(*flagID); - if (err != EV_OK) { - *flagID = EV_NO_ID; - } - return err; -} - -/** @see EV_create_queue_auto_id */ -EV_ERR -EVK_create_queue_auto_id(/* OUT */EV_ID *queueID, UINT8 length, - UINT16 max_bytes, EV_Message_Queue_Type type) -{ - EV_ERR err; - EVK_assert(queueID != NULL, "NULL pointer was specified"); - - if (evk_alloc_queueID(queueID) < 0) { - return EV_ERR_Fatal; - } - - err = EVK_create_queue_in(*queueID, length, max_bytes, type); - if (err != EV_OK) { - *queueID = EV_NO_ID; - } - return err; -} - -/** @see EV_destroy_flag */ -EV_ERR -EVK_destroy_flag(EV_ID flagID) -{ - int err; - err = evk_destroy_queue(flagID); - - if (err == -ENOENT) { - return EV_ERR_Invalid_ID; - } else if (err < 0) { - return EV_ERR_Fatal; - } else { - return EV_OK; - } -} - -/** @see EV_destroy_queue */ -EV_ERR -EVK_destroy_queue(EV_ID queueID) -{ - return EVK_destroy_flag(queueID); -} - -/* Sending the event */ -/** @see EV_set_flag */ -EV_ERR -EVK_set_flag(EV_ID flagID, UINT32 bits) -{ - EV_Flag flag; - int ret; - - if (!EV_ID_IS_FLAG(flagID)) { - return EV_ERR_Invalid_ID; - } - flag.flagID = flagID; - flag.bits = bits; - - ret = evk_store_flag(&flag, evk_mem_kernel); - if (ret == -ENOENT) { - return EV_ERR_Invalid_ID; - } else if (ret < 0) { - return EV_ERR_Fatal; - } else { - return EV_OK; - } -} - -/** @see EV_set_flag64 */ -EV_ERR -EVK_set_flag64(EV_ID flagID, UINT64 bits) -{ - EV_Flag64 flag; - int ret; - - if (!EV_ID_IS_FLAG64(flagID)) { - return EV_ERR_Invalid_ID; - } - flag.flagID = flagID; - flag.bits = bits; - - ret = evk_store_flag64(&flag, evk_mem_kernel); - if (ret == -ENOENT) { - return EV_ERR_Invalid_ID; - } else if (ret < 0) { - return EV_ERR_Fatal; - } else { - return EV_OK; - } -} - -/** @see EV_send_message */ -EV_ERR -EVK_send_message(EV_ID queueID, UINT16 bytes, const void *message, - UINT32 senderInfo) -{ - EV_Message *msg = NULL; - EV_ERR ev_ret; - int ret; - - msg = evk_malloc( sizeof( EV_Message ) ); - if( msg == NULL ) - { - ev_ret = EV_ERR_Fatal; - goto L_END; - } - - if (!EV_ID_IS_QUEUE(queueID)) { - ev_ret = EV_ERR_Invalid_ID; - goto L_END; - } - EVK_assert(message != NULL, "NULL pointer was specified"); - EVK_assert(bytes <= EV_MAX_MESSAGE_LENGTH, "send_message: message too long"); - - msg->queueID = queueID; - msg->senderInfo = senderInfo; - msg->length = bytes; - memcpy(msg->message, message, bytes); - - ret = evk_store_message(msg, evk_mem_kernel); - if (ret == -ENOENT) { - ev_ret = EV_ERR_Invalid_ID; - } else if (ret == -EBUSY) { - ev_ret = EV_ERR_Busy; - } else if (ret < 0) { - ev_ret = EV_ERR_Fatal; - } else { - ev_ret = EV_OK; - } - -L_END: - if( msg != NULL ) - { - evk_free( msg ); - } - return ev_ret; -} - -/* Event acquisition(Order of arrival time) */ -//EV_ERR EV_get_next_event(/* OUT */EV_Event *ev); - -static EV_ERR -EVK_get_flag_in(EV_ID flagID, EV_Flag *flag, int peek_only, int wait) -{ - EV_Event *ev = NULL; - EV_ERR ev_ret; - int ret; - - ev = evk_malloc( sizeof( EV_Event ) ); - if( ev == NULL ) - { - ev_ret = EV_ERR_Fatal; - goto L_END; - } - - EVK_assert(flag != NULL, "get_flag: NULL pointer was specified"); - flag->flagID = EV_NO_ID; - flag->bits = 0; - - if (!EV_ID_IS_FLAG(flagID)) { - ev_ret = EV_ERR_Invalid_ID; - goto L_END; - } - - ev->type = EV_EVENT_Flag; - ev->u.flag.flagID = flagID; - ev->u.flag.bits = 0; - - ret = evk_get_event(ev, peek_only, wait, evk_mem_kernel); - - if (ret < 0) { - if (ret == -ENOENT) { - ev_ret = EV_ERR_Invalid_ID; - } else if (ret == -EINTR) { - ev_ret = EV_ERR_Interrupted; - } else { - ev_ret = EV_ERR_Fatal; - } - goto L_END; - } - - if (ev->type == EV_EVENT_Flag) { - flag->flagID = ev->u.flag.flagID; - flag->bits = ev->u.flag.bits; - } - ev_ret = EV_OK; - -L_END: - if( ev != NULL ) - { - evk_free( ev ); - } - return ev_ret; -} - -static EV_ERR -EVK_get_flag64_in(EV_ID flagID, EV_Flag64 *flag, int peek_only, int wait) -{ - EV_Event *ev = NULL; - EV_ERR ev_ret; - int ret; - - ev = evk_malloc( sizeof( EV_Event ) ); - if( ev == NULL ) - { - ev_ret = EV_ERR_Fatal; - goto L_END; - } - - EVK_assert(flag != NULL, "get_flag64: NULL pointer was specified"); - flag->flagID = EV_NO_ID; - flag->bits = 0; - - if (!EV_ID_IS_FLAG64(flagID)) { - ev_ret = EV_ERR_Invalid_ID; - goto L_END; - } - - ev->type = EV_EVENT_Flag64; - ev->u.flag64.flagID = flagID; - ev->u.flag64.bits = 0; - - ret = evk_get_event(ev, peek_only, wait, evk_mem_kernel); - - if (ret < 0) { - if (ret == -ENOENT) { - ev_ret = EV_ERR_Invalid_ID; - } else if (ret == -EINTR) { - ev_ret = EV_ERR_Interrupted; - } else { - ev_ret = EV_ERR_Fatal; - } - goto L_END; - } - - if (ev->type == EV_EVENT_Flag64) { - flag->flagID = ev->u.flag64.flagID; - flag->bits = ev->u.flag64.bits; - } - ev_ret = EV_OK; - -L_END: - if( ev != NULL ) - { - evk_free( ev ); - } - return ev_ret; -} - -/* Event acquisition(With Search Criteria) */ -/** @see EV_get_flag */ -EV_ERR -EVK_get_flag(EV_ID flagID, /* OUT */EV_Flag *flag) -{ - return EVK_get_flag_in(flagID, flag, 0, 0); -} - -/** @see EV_get_flag64 */ -EV_ERR -EVK_get_flag64(EV_ID flagID, /* OUT */EV_Flag64 *flag) -{ - return EVK_get_flag64_in(flagID, flag, 0, 0); -} - -/** @see EV_wait_flag */ -EV_ERR -EVK_wait_flag(EV_ID flagID, /* OUT */EV_Flag *flag)/* block */ -{ - return EVK_get_flag_in(flagID, flag, 0, 1); -} - -/** @see EV_wait_flag64 */ -EV_ERR -EVK_wait_flag64(EV_ID flagID, /* OUT */EV_Flag64 *flag)/* block */ -{ - return EVK_get_flag64_in(flagID, flag, 0, 1); -} - -/** @see EV_peek_flag */ -EV_ERR -EVK_peek_flag(EV_ID flagID, /* OUT */EV_Flag *flag) -{ - return EVK_get_flag_in(flagID, flag, 1, 0); -} - -/** @see EV_peek_flag64 */ -EV_ERR -EVK_peek_flag64(EV_ID flagID, /* OUT */EV_Flag64 *flag) -{ - return EVK_get_flag64_in(flagID, flag, 1, 0); -} - -static EV_ERR -EVK_get_message_in(EV_ID queueID, EV_Message *message, UINT32 senderInfo, - UINT32 length, const void *compare_bytes, - int peek_only, int wait) -{ - EV_Event *ev = NULL; - EV_ERR ev_ret; - int ret; - - ev = evk_malloc( sizeof( EV_Event ) ); - if( ev == NULL ) - { - ev_ret = EV_ERR_Fatal; - goto L_END; - } - - EVK_assert(message != NULL, "get_message: NULL pointer was specified"); - if (!EV_ID_IS_QUEUE(queueID)) { - ev_ret = EV_ERR_Invalid_ID; - goto L_END; - } - message->queueID = EV_NO_ID; - message->senderInfo = 0; - message->length = 0; - - ev->type = EV_EVENT_Message; - ev->u.message.queueID = queueID; - ev->u.message.senderInfo = senderInfo; - if (compare_bytes != NULL) { - ev->u.message.length = length; - memcpy(ev->u.message.message, compare_bytes, length); - } else { - ev->u.message.length = 0; - } - - ret = evk_get_event(ev, peek_only, wait, evk_mem_kernel); - - if (ret < 0) { - if (ret == -ENOENT) { - ev_ret = EV_ERR_Invalid_ID; - } else if (ret == -EINTR) { - ev_ret = EV_ERR_Interrupted; - } else { - ev_ret = EV_ERR_Fatal; - } - goto L_END; - } - - if (ev->type == EV_EVENT_Message) { - message->queueID = ev->u.message.queueID; - message->senderInfo = ev->u.message.senderInfo; - message->length = ev->u.message.length; - memcpy(message->message, ev->u.message.message, ev->u.message.length); - } - ev_ret = EV_OK; - -L_END: - if( ev != NULL ) - { - evk_free( ev ); - } - return ev_ret; -} - -/** @see EV_get_message */ -EV_ERR -EVK_get_message(EV_ID queueID, /* OUT */EV_Message *message) -{ - return EVK_get_message_in(queueID, message, 0, 0, NULL, 0, 0); -} - -/** @see EV_wait_message */ -EV_ERR -EVK_wait_message(EV_ID queueID, /* OUT */EV_Message *message)/* block */ -{ - return EVK_get_message_in(queueID, message, 0, 0, NULL, 0, 1); -} - -/** @see EV_peek_message */ -EV_ERR -EVK_peek_message(EV_ID queueID, /* OUT */EV_Message *message) -{ - return EVK_get_message_in(queueID, message, 0, 0, NULL, 1, 0); -} - -/** @see EV_find_message_by_sender */ -EV_ERR -EVK_find_message_by_sender(EV_ID queueID, UINT32 senderInfo, - /* OUT */EV_Message *message) -{ - // Not mounted - return EV_ERR_Fatal; -} - -/** @see EV_find_message_by_content */ -EV_ERR -EVK_find_message_by_content(EV_ID queueID, UINT16 length, - const void *compare_bytes, - /* OUT */EV_Message *message) -{ - // Not mounted - return EV_ERR_Fatal; -} -/** @} */ - -EXPORT_SYMBOL(evk_get_queue_entry); -EXPORT_SYMBOL(EVK_init); -EXPORT_SYMBOL(EVK_exit); - -EXPORT_SYMBOL(EVK_create_flag); -EXPORT_SYMBOL(EVK_create_flag64); -EXPORT_SYMBOL(EVK_create_queue); -EXPORT_SYMBOL(EVK_create_flag_auto_id); -EXPORT_SYMBOL(EVK_create_flag64_auto_id); -EXPORT_SYMBOL(EVK_create_queue_auto_id); -EXPORT_SYMBOL(EVK_destroy_flag); -EXPORT_SYMBOL(EVK_destroy_queue); -EXPORT_SYMBOL(EVK_set_flag); -EXPORT_SYMBOL(EVK_set_flag64); -EXPORT_SYMBOL(EVK_send_message); -EXPORT_SYMBOL(EVK_get_flag); -EXPORT_SYMBOL(EVK_wait_flag); -EXPORT_SYMBOL(EVK_peek_flag); -EXPORT_SYMBOL(EVK_get_flag64); -EXPORT_SYMBOL(EVK_wait_flag64); -EXPORT_SYMBOL(EVK_peek_flag64); -EXPORT_SYMBOL(EVK_get_message); -EXPORT_SYMBOL(EVK_wait_message); -EXPORT_SYMBOL(EVK_peek_message); - -#ifndef CONFIG_COMBINE_MODULES -//MODULE_LICENSE("proprietary"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("EVent library for Kernel"); -//MODULE_SUPPORTED_DEVICE(name); -//MODULE_PARM(var,type) -//MODULE_PARM_DESC(var,desc) -module_init(EVK_init); -module_exit(EVK_exit); -#endif /* !CONFIG_COMBINE_MODULES */ |