blob: 4a4e02a23e938e97035c465ca0757cba3b59cb2e [file] [log] [blame]
/*
* Copyright (c) [2009-2013] Marvell International Ltd. and its affiliates.
* All rights reserved.
* This software file (the "File") is owned and distributed by Marvell
* International Ltd. and/or its affiliates ("Marvell") under the following
* licensing terms.
* If you received this File from Marvell, you may opt to use, redistribute
* and/or modify this File in accordance with the terms and conditions of
* the General Public License Version 2, June 1991 (the "GPL License"), a
* copy of which is available along with the File in the license.txt file
* or by writing to the Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 or on the worldwide web at
* http://www.gnu.org/licenses/gpl.txt. THE FILE IS DISTRIBUTED AS-IS,
* WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED WARRANTIES OF
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
* DISCLAIMED. The GPL License provides additional details about this
* warranty disclaimer.
*/
#include <linux/time.h>
#include "tzdd_internal.h"
#define INIT_MAGIC(_n) \
do { \
((uint8_t *)_n)[0] = 'T'; \
((uint8_t *)_n)[1] = 'Z'; \
((uint8_t *)_n)[2] = 'D'; \
((uint8_t *)_n)[3] = 'D'; \
} while (0)
#define IS_MAGIC_VALID(_n) \
(('T' == ((uint8_t *)_n)[0]) && \
('Z' == ((uint8_t *)_n)[1]) && \
('D' == ((uint8_t *)_n)[2]) && \
('D' == ((uint8_t *)_n)[3]))
#define CLEANUP_MAGIC(_n) \
do { \
((uint8_t *)_n)[0] = '\0'; \
((uint8_t *)_n)[1] = '\0'; \
((uint8_t *)_n)[2] = '\0'; \
((uint8_t *)_n)[3] = '\0'; \
} while (0)
static void _tzdd_ctx_list_add(TEEC_Context *teec_context,
tzdd_ctx_node_t *tzdd_ctx_node)
{
tzdd_pid_list_t *tzdd_pid = NULL;
osa_list_t *entry;
uint32_t flag = 0;
pid_t pid;
pid = current->tgid;
osa_list_iterate(&(tzdd_dev->pid_list), entry) {
OSA_LIST_ENTRY(entry, tzdd_pid_list_t, node, tzdd_pid);
if (pid == tzdd_pid->pid) {
flag = FIND_PID_IN_PID_LIST;
break;
}
}
if (flag == FIND_PID_IN_PID_LIST) {
osa_list_init_head(&(tzdd_ctx_node->shm_list));
osa_list_init_head(&(tzdd_ctx_node->ss_list));
osa_list_add(&(tzdd_ctx_node->node),
&(tzdd_pid->ctx_list));
INIT_MAGIC(tzdd_ctx_node->magic);
tzdd_ctx_node->tee_ctx_ntw = teec_context;
}
return;
}
static void _tzdd_ctx_list_del(tzdd_ctx_node_t *tzdd_ctx_node)
{
tzdd_pid_list_t *tzdd_pid = NULL;
osa_list_t *entry;
uint32_t flag = 0;
pid_t pid;
pid = current->tgid;
osa_list_iterate(&(tzdd_dev->pid_list), entry) {
OSA_LIST_ENTRY(entry, tzdd_pid_list_t, node, tzdd_pid);
if (pid == tzdd_pid->pid) {
flag = FIND_PID_IN_PID_LIST;
break;
}
}
if (flag == FIND_PID_IN_PID_LIST) {
if (!(IS_MAGIC_VALID(tzdd_ctx_node->magic)))
OSA_ASSERT(0);
CLEANUP_MAGIC(tzdd_ctx_node->magic);
osa_list_del(&(tzdd_ctx_node->node));
}
return;
}
static void _tzdd_shm_list_add(TEEC_Context *teec_context,
TEEC_SharedMemory *teec_shared_memory,
tzdd_shm_node_t *tzdd_shm_node)
{
tzdd_ctx_node_t *tzdd_ctx_node;
_TEEC_MRVL_Context *_teec_mrvl_context;
_teec_mrvl_context = (_TEEC_MRVL_Context *)(teec_context->imp);
tzdd_ctx_node = (tzdd_ctx_node_t *)(_teec_mrvl_context->private_data);
osa_list_add(&(tzdd_shm_node->node), &(tzdd_ctx_node->shm_list));
INIT_MAGIC(tzdd_shm_node->magic);
tzdd_shm_node->tee_ctx_ntw = teec_context;
tzdd_shm_node->tee_shm_ntw = teec_shared_memory;
return;
}
static void _tzdd_shm_list_del(tzdd_shm_node_t *tzdd_shm_node)
{
TEEC_Context *teec_context;
_TEEC_MRVL_Context *_teec_mrvl_context;
tzdd_ctx_node_t *tzdd_ctx_node;
if (!(IS_MAGIC_VALID(tzdd_shm_node->magic)))
OSA_ASSERT(0);
teec_context = tzdd_shm_node->tee_ctx_ntw;
_teec_mrvl_context = (_TEEC_MRVL_Context *)(teec_context->imp);
tzdd_ctx_node = (tzdd_ctx_node_t *)(_teec_mrvl_context->private_data);
if (!(IS_MAGIC_VALID(tzdd_ctx_node->magic)))
OSA_ASSERT(0);
CLEANUP_MAGIC(tzdd_shm_node->magic);
osa_list_del(&(tzdd_shm_node->node));
return;
}
static void _tzdd_ss_list_add(TEEC_Context *teec_context,
TEEC_Session *teec_session,
tzdd_ss_node_t *tzdd_ss_node)
{
tzdd_ctx_node_t *tzdd_ctx_node;
_TEEC_MRVL_Context *_teec_mrvl_context;
_teec_mrvl_context = (_TEEC_MRVL_Context *)(teec_context->imp);
tzdd_ctx_node = (tzdd_ctx_node_t *)(_teec_mrvl_context->private_data);
osa_list_add(&(tzdd_ss_node->node), &(tzdd_ctx_node->ss_list));
INIT_MAGIC(tzdd_ss_node->magic);
tzdd_ss_node->tee_ctx_ntw = teec_context;
tzdd_ss_node->tee_ss_ntw = teec_session;
return;
}
static void _tzdd_ss_list_del(tzdd_ss_node_t *tzdd_ss_node)
{
TEEC_Context *teec_context;
_TEEC_MRVL_Context *_teec_mrvl_context;
tzdd_ctx_node_t *tzdd_ctx_node;
if (!(IS_MAGIC_VALID(tzdd_ss_node->magic)))
OSA_ASSERT(0);
teec_context = tzdd_ss_node->tee_ctx_ntw;
_teec_mrvl_context = (_TEEC_MRVL_Context *)(teec_context->imp);
tzdd_ctx_node = (tzdd_ctx_node_t *)(_teec_mrvl_context->private_data);
if (!(IS_MAGIC_VALID(tzdd_ctx_node->magic)))
OSA_ASSERT(0);
CLEANUP_MAGIC(tzdd_ss_node->magic);
osa_list_del(&(tzdd_ss_node->node));
return;
}
TEEC_Result _teec_initialize_context(const char *name, tee_impl *tee_ctx_ntw)
{
TEEC_Context *teec_context;
TEEC_Result result;
tzdd_ctx_node_t *tzdd_ctx_node;
_TEEC_MRVL_Context *_teec_mrvl_context;
if (!name || (!osa_memcmp(name, DEVICE_NAME, DEVICE_NAME_SIZE))) {
TZDD_DBG("_teec_initialize_context the name is tzdd\n");
teec_context =
(TEEC_Context *) osa_kmem_alloc(sizeof(TEEC_Context));
if (!teec_context) {
TZDD_DBG("Fail to malloc TEEC_Context\n");
return TEEC_ERROR_OUT_OF_MEMORY;
}
result = TEEC_InitializeContext(name, teec_context);
if (result != TEEC_SUCCESS) {
TZDD_DBG
("%s(%d), Error in TEEC_InitializeContext,\
result = 0x%x\n",
__func__, __LINE__, result);
*tee_ctx_ntw = NULL;
osa_kmem_free(teec_context);
return result;
}
*tee_ctx_ntw = (tee_impl) (&(teec_context->imp));
_teec_mrvl_context = (_TEEC_MRVL_Context *)(teec_context->imp);
tzdd_ctx_node = osa_kmem_alloc(sizeof(tzdd_ctx_node_t));
OSA_ASSERT(tzdd_ctx_node != NULL);
osa_wait_for_sem(tzdd_dev->pid_mutex, INFINITE);
_tzdd_ctx_list_add(teec_context, tzdd_ctx_node);
osa_release_sem(tzdd_dev->pid_mutex);
_teec_mrvl_context->private_data = tzdd_ctx_node;
} else {
return TEEC_ERROR_BAD_PARAMETERS;
}
return TEEC_SUCCESS;
}
TEEC_Result _teec_final_context(tee_impl tee_ctx_ntw)
{
TEEC_Context *teec_context;
TEEC_MRVL_Context *teec_mrvl_context;
tzdd_ctx_node_t *tzdd_ctx_node;
_TEEC_MRVL_Context *_teec_mrvl_context;
/* Find the struct according to the member */
teec_mrvl_context = (TEEC_MRVL_Context *) tee_ctx_ntw;
teec_context = container_of(teec_mrvl_context, TEEC_Context, imp);
_teec_mrvl_context = (_TEEC_MRVL_Context *)(teec_context->imp);
tzdd_ctx_node = (tzdd_ctx_node_t *)(_teec_mrvl_context->private_data);
osa_wait_for_sem(tzdd_dev->pid_mutex, INFINITE);
_tzdd_ctx_list_del(tzdd_ctx_node);
osa_release_sem(tzdd_dev->pid_mutex);
osa_kmem_free(tzdd_ctx_node);
TEEC_FinalizeContext(teec_context);
osa_kmem_free(teec_context);
return TEEC_SUCCESS;
}
TEEC_Result _teec_map_shared_mem(teec_map_shared_mem_args teec_map_shared_mem,
tee_impl *tee_shm_ntw)
{
/* only call TEEC_RegisterSharedMemory */
TEEC_Context *teec_context;
TEEC_MRVL_Context *teec_mrvl_context;
TEEC_SharedMemory *teec_shared_memory;
TEEC_Result result;
tzdd_shm_node_t *tzdd_shm_node;
_TEEC_MRVL_SharedMemory *_teec_mrvl_sharedMem;
teec_mrvl_context =
(TEEC_MRVL_Context *) (teec_map_shared_mem.tee_ctx_ntw);
teec_context = container_of(teec_mrvl_context, TEEC_Context, imp);
teec_shared_memory =
(TEEC_SharedMemory *) osa_kmem_alloc(sizeof(TEEC_SharedMemory));
if (!teec_shared_memory) {
TZDD_DBG("Fail to malloc TEEC_SharedMemory\n");
return TEEC_ERROR_OUT_OF_MEMORY;
}
teec_shared_memory->buffer = teec_map_shared_mem.buffer;
teec_shared_memory->size = teec_map_shared_mem.size;
teec_shared_memory->flags = teec_map_shared_mem.flags;
result = TEEC_RegisterSharedMemory(teec_context, teec_shared_memory);
if (result != TEEC_SUCCESS) {
TZDD_DBG
("%s(%d), Error in TEEC_RegisterSharedMemory, result = 0x%x\n",
__func__, __LINE__, result);
*tee_shm_ntw = NULL;
osa_kmem_free(teec_shared_memory);
return result;
}
*tee_shm_ntw = (tee_impl) (&(teec_shared_memory->imp));
_teec_mrvl_sharedMem =
(_TEEC_MRVL_SharedMemory *)(teec_shared_memory->imp);
tzdd_shm_node = osa_kmem_alloc(sizeof(tzdd_shm_node_t));
OSA_ASSERT(tzdd_shm_node != NULL);
osa_wait_for_sem(tzdd_dev->pid_mutex, INFINITE);
_tzdd_shm_list_add(teec_context, teec_shared_memory, tzdd_shm_node);
osa_release_sem(tzdd_dev->pid_mutex);
_teec_mrvl_sharedMem->private_data = tzdd_shm_node;
return TEEC_SUCCESS;
}
TEEC_Result _teec_unmap_shared_mem(teec_unmap_shared_mem_args
teec_unmap_shared_mem, tee_impl tee_shm_ntw)
{
TEEC_SharedMemory *teec_shared_memory;
TEEC_MRVL_SharedMemory *teec_mrvl_shared_mem;
_TEEC_MRVL_SharedMemory *_teec_mrvl_sharedMem;
tzdd_shm_node_t *tzdd_shm_node;
teec_mrvl_shared_mem = (TEEC_MRVL_SharedMemory *) tee_shm_ntw;
teec_shared_memory =
container_of(teec_mrvl_shared_mem, TEEC_SharedMemory, imp);
_teec_mrvl_sharedMem = (_TEEC_MRVL_SharedMemory *)(teec_shared_memory->imp);
tzdd_shm_node = (tzdd_shm_node_t *)(_teec_mrvl_sharedMem->private_data);
osa_wait_for_sem(tzdd_dev->pid_mutex, INFINITE);
_tzdd_shm_list_del(tzdd_shm_node);
osa_release_sem(tzdd_dev->pid_mutex);
osa_kmem_free(tzdd_shm_node);
TEEC_ReleaseSharedMemory(teec_shared_memory);
osa_kmem_free(teec_shared_memory);
return TEEC_SUCCESS;
}
TEEC_Result _teec_open_session(tee_impl tee_ctx_ntw,
tee_impl *tee_ss_ntw,
const TEEC_UUID *destination,
uint32_t connectionMethod,
const void *connectionData,
uint32_t flags,
uint32_t paramTypes,
TEEC_Parameter(*params)[4],
tee_impl *tee_op_ntw,
tee_impl tee_op_ntw_for_cancel,
uint32_t *returnOrigin,
unsigned long arg,
teec_open_ss_args open_ss_args)
{
TEEC_Context *teec_context;
TEEC_MRVL_Context *teec_mrvl_context;
TEEC_Session *teec_session;
TEEC_Operation *teec_operation = NULL;
TEEC_Result result;
uint32_t i;
uint32_t tmp_for_cancel;
tzdd_ss_node_t *tzdd_ss_node;
_TEEC_MRVL_Session *_teec_mrvl_session;
teec_mrvl_context = (TEEC_MRVL_Context *) (tee_ctx_ntw);
teec_context = container_of(teec_mrvl_context, TEEC_Context, imp);
teec_session = (TEEC_Session *) osa_kmem_alloc(sizeof(TEEC_Session));
if (!teec_session) {
TZDD_DBG("Fail to malloc TEEC_Session\n");
return TEEC_ERROR_OUT_OF_MEMORY;
}
*tee_ss_ntw = (tee_impl) (&(teec_session->imp));
if (flags == OPERATION_EXIST) {
if (copy_from_user
(&tmp_for_cancel, (void __user *)(tee_op_ntw_for_cancel),
4)) {
osa_kmem_free(teec_session);
return -EFAULT;
}
teec_operation =
(TEEC_Operation *) osa_kmem_alloc(sizeof(TEEC_Operation));
if (!teec_operation) {
TZDD_DBG("Fail to malloc TEEC_Operation\n");
osa_kmem_free(teec_session);
return TEEC_ERROR_OUT_OF_MEMORY;
}
teec_operation->started = 0;
teec_operation->paramTypes = paramTypes;
for (i = 0; i < 4; i++)
teec_operation->params[i] = (*params)[i];
*tee_op_ntw = (tee_impl) (&(teec_operation->imp));
tmp_for_cancel = (uint32_t) (&(teec_operation->imp));
/* Add copy_to_user here, for cancellation */
if (copy_to_user
((void __user *)(tee_op_ntw_for_cancel), &tmp_for_cancel,
4)) {
osa_kmem_free(teec_operation);
osa_kmem_free(teec_session);
return -EFAULT;
}
} else {
*tee_op_ntw = NULL;
}
result = TEEC_OpenSession(teec_context,
teec_session,
destination,
connectionMethod,
connectionData, teec_operation, returnOrigin);
if (result != TEEC_SUCCESS) {
TZDD_DBG("%s(%d), Error in TEEC_OpenSession, result = 0x%x\n",
__func__, __LINE__, result);
*tee_ss_ntw = NULL;
osa_kmem_free(teec_session);
if (flags == OPERATION_EXIST) {
for (i = 0; i < 4; i++)
(*params)[i] = teec_operation->params[i];
*tee_op_ntw = NULL;
osa_kmem_free(teec_operation);
}
return result;
}
/* Copy param in order to return to CA */
if (flags == OPERATION_EXIST) {
for (i = 0; i < 4; i++)
(*params)[i] = teec_operation->params[i];
osa_kmem_free(teec_operation);
}
_teec_mrvl_session =
(_TEEC_MRVL_Session*)(teec_session->imp);
tzdd_ss_node = osa_kmem_alloc(sizeof(tzdd_ss_node_t));
OSA_ASSERT(tzdd_ss_node != NULL);
osa_wait_for_sem(tzdd_dev->pid_mutex, INFINITE);
_tzdd_ss_list_add(teec_context, teec_session, tzdd_ss_node);
osa_release_sem(tzdd_dev->pid_mutex);
_teec_mrvl_session->private_data = tzdd_ss_node;
return TEEC_SUCCESS;
}
TEEC_Result _teec_close_session(tee_impl tee_ss_ntw)
{
TEEC_Session *teec_session;
TEEC_MRVL_Session *teec_mrvl_session;
tzdd_ss_node_t *tzdd_ss_node;
_TEEC_MRVL_Session *_teec_mrvl_session;
teec_mrvl_session = (TEEC_MRVL_Session *) (tee_ss_ntw);
teec_session = container_of(teec_mrvl_session, TEEC_Session, imp);
_teec_mrvl_session = (_TEEC_MRVL_Session *)(teec_session->imp);
tzdd_ss_node = (tzdd_ss_node_t *)(_teec_mrvl_session->private_data);
osa_wait_for_sem(tzdd_dev->pid_mutex, INFINITE);
_tzdd_ss_list_del(tzdd_ss_node);
osa_release_sem(tzdd_dev->pid_mutex);
osa_kmem_free(tzdd_ss_node);
TEEC_CloseSession(teec_session);
osa_kmem_free(teec_session);
return TEEC_SUCCESS;
}
TEEC_Result _teec_invoke_command(tee_impl tee_ss_ntw,
uint32_t cmd_ID,
uint32_t started,
uint32_t flags,
uint32_t paramTypes,
TEEC_Parameter(*params)[4],
tee_impl *tee_op_ntw,
tee_impl tee_op_ntw_for_cancel,
uint32_t *returnOrigin,
unsigned long arg,
teec_invoke_cmd_args invoke_cmd_args)
{
TEEC_Session *teec_session;
TEEC_MRVL_Session *teec_mrvl_session;
TEEC_Operation *teec_operation = NULL;
TEEC_Result result;
uint32_t i;
uint32_t tmp_for_cancel;
teec_mrvl_session = (TEEC_MRVL_Session *) (tee_ss_ntw);
teec_session = container_of(teec_mrvl_session, TEEC_Session, imp);
if (flags == OPERATION_EXIST) {
if (copy_from_user
(&tmp_for_cancel, (void __user *)(tee_op_ntw_for_cancel),
4)) {
return -EFAULT;
}
teec_operation =
(TEEC_Operation *) osa_kmem_alloc(sizeof(TEEC_Operation));
if (!teec_operation) {
TZDD_DBG("Fail to malloc TEEC_Operation\n");
return TEEC_ERROR_OUT_OF_MEMORY;
}
teec_operation->started = 0;
teec_operation->paramTypes = paramTypes;
for (i = 0; i < 4; i++)
teec_operation->params[i] = (*params)[i];
*tee_op_ntw = (tee_impl) (&(teec_operation->imp));
tmp_for_cancel = (uint32_t) (&(teec_operation->imp));
/* Add copy_to_user here, for cancellation */
if (copy_to_user
((void __user *)(tee_op_ntw_for_cancel), &tmp_for_cancel,
4)) {
osa_kmem_free(teec_operation);
return -EFAULT;
}
} else {
*tee_op_ntw = NULL;
}
result = TEEC_InvokeCommand(teec_session,
cmd_ID, teec_operation, returnOrigin);
if (result != TEEC_SUCCESS) {
TZDD_DBG("%s(%d), Error in TEEC_InvokeCommand, result = 0x%x\n",
__func__, __LINE__, result);
if (flags == OPERATION_EXIST) {
for (i = 0; i < 4; i++)
(*params)[i] = teec_operation->params[i];
*tee_op_ntw = NULL;
osa_kmem_free(teec_operation);
}
return result;
}
/* Copy param in order to return to CA */
if (flags == OPERATION_EXIST) {
for (i = 0; i < 4; i++)
(*params)[i] = teec_operation->params[i];
osa_kmem_free(teec_operation);
}
return TEEC_SUCCESS;
}
TEEC_Result _teec_request_cancellation(tee_impl tee_op_ntw)
{
TEEC_Operation *teec_operation;
TEEC_MRVL_Operation *teec_mrvl_operation;
teec_mrvl_operation = (TEEC_MRVL_Operation *) tee_op_ntw;
teec_operation = container_of(teec_mrvl_operation, TEEC_Operation, imp);
TEEC_RequestCancellation(teec_operation);
return TEEC_SUCCESS;
}
/*
* Name: tzdd_get_first_req
*
* Description: get first node from request list
*
* Params:
* node - node pointer
*
* Returns:
* true - have request
* false - have no request
*
* Notes: none
*
*/
bool tzdd_get_first_req(tee_msg_head_t **tee_msg_head)
{
struct osa_list *first;
*tee_msg_head = NULL;
osa_wait_for_mutex(tzdd_dev->req_mutex, INFINITE);
if (osa_list_empty(&tzdd_dev->req_list)) {
osa_release_mutex(tzdd_dev->req_mutex);
return false;
} else {
first = (tzdd_dev->req_list).next;
OSA_LIST_ENTRY(first, tee_msg_head_t, node, *tee_msg_head);
}
osa_release_mutex(tzdd_dev->req_mutex);
return true;
}
/*
* Name: tzdd_add_node_to_req_list
*
* Description: add node to request list
*
* Params:
* list - list pointer
*
* Returns: none
*
* Notes: none
*
*/
void tzdd_add_node_to_req_list(osa_list_t *list)
{
osa_wait_for_mutex(tzdd_dev->req_mutex, INFINITE);
osa_list_add_tail(list, &tzdd_dev->req_list);
osa_release_mutex(tzdd_dev->req_mutex);
return;
}
/*
* Name: tzdd_chk_node_on_req_list
*
* Description: check node to request list
*
* Params:
* list - list pointer
*
* Returns:
* true - node is on the list
* false - node is not exist
*
* Notes: none
*
*/
bool tzdd_chk_node_on_req_list(osa_list_t *list)
{
struct osa_list *entry;
osa_wait_for_mutex(tzdd_dev->req_mutex, INFINITE);
osa_list_iterate(&tzdd_dev->req_list, entry) {
if (entry == list) {
osa_release_mutex(tzdd_dev->req_mutex);
return true;
}
}
osa_release_mutex(tzdd_dev->req_mutex);
return false;
}
/*
* Name: tzdd_del_node_from_req_list
*
* Description: delete node from request list
*
* Params:
* list - list pointer
*
* Returns:
* true - node has deleted from the list
* false - node is not exist
*
* Notes: none
*
*/
bool tzdd_del_node_from_req_list(osa_list_t *list)
{
struct osa_list *entry, *next;
osa_wait_for_mutex(tzdd_dev->req_mutex, INFINITE);
osa_list_iterate_safe(&tzdd_dev->req_list, entry, next) {
if (entry == list) {
osa_list_del(entry);
osa_release_mutex(tzdd_dev->req_mutex);
return true;
}
}
osa_release_mutex(tzdd_dev->req_mutex);
return false;
}
/*
* Name: tzdd_have_req
*
* Description: check there have some request in the run list
* and the request list or not
*
* Params: none
*
* Returns:
* true - have request
* false - have no request
*
* Notes: none
*
*/
bool tzdd_have_req(void)
{
osa_wait_for_mutex(tzdd_dev->req_mutex, INFINITE);
if (!osa_list_empty(&tzdd_dev->req_list)) {
osa_release_mutex(tzdd_dev->req_mutex);
return true;
}
osa_release_mutex(tzdd_dev->req_mutex);
return false;
}
uint32_t tzdd_get_req_num_in_list(void)
{
struct osa_list *entry;
uint32_t n = 0;
osa_wait_for_mutex(tzdd_dev->req_mutex, INFINITE);
osa_list_iterate(&tzdd_dev->req_list, entry) {
n++;
}
osa_release_mutex(tzdd_dev->req_mutex);
return n;
}
#ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG
extern void tee_dbg_proc_fs_init(void);
extern void tee_dbg_proc_fs_cleanup(void);
#endif
int32_t tzdd_init_core(tzdd_dev_t *dev)
{
int32_t ret;
osa_list_init_head(&dev->req_list);
dev->req_mutex = osa_create_mutex();
ret = tee_cm_init();
if (ret) {
TZDD_DBG("%s: failed to init cm\n", __func__);
goto _failure_in_cm_init;
}
#ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG
tee_dbg_proc_fs_init();
#endif
ret = tzdd_proxy_thread_init(dev);
if (ret) {
TZDD_DBG("%s: failed to init proxy threads\n", __func__);
goto _failure_in_proxy_thread_init;
}
ret = (int32_t)teec_cb_module_init();
if (ret) {
TZDD_DBG("%s: failed to init callback module\n", __FUNCTION__);
goto _failure_in_cb_init;
}
ret = (int32_t)teec_reg_time_cb();
if (ret) {
TZDD_DBG("%s: failed to reg time cb\n", __FUNCTION__);
goto _failure_in_reg_time_cb;
}
return 0;
_failure_in_reg_time_cb:
teec_cb_module_cleanup();
/* _failure_in_kd_init: */
_failure_in_cb_init:
tzdd_proxy_thread_cleanup(dev);
_failure_in_proxy_thread_init:
_failure_in_cm_init:
tee_cm_cleanup();
return ret;
}
void tzdd_cleanup_core(tzdd_dev_t *dev)
{
teec_unreg_time_cb();
teec_cb_module_cleanup();
tzdd_proxy_thread_cleanup(dev);
#ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG
tee_dbg_proc_fs_cleanup();
#endif
tee_cm_cleanup();
osa_destroy_mutex(dev->req_mutex);
return;
}