You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

729 lines
23 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2019. All rights reserved.
* Description: drv_rm
* Author: sdk_video
* Create: 2012-11-25
*/
#include "drv_rm.h"
#include "osal_ext.h"
#include "soc_errno.h"
#include "drv_rm_ext.h"
#include "drv_win_ext.h"
#include "drv_rm_define.h"
#include "drv_rm_proc.h"
#include "drv_rm_comm.h"
static rm_drv_golbal_ctx g_st_rm_drv_golbal_ctx;
static rm_drv_path_ctx g_st_rm_drv_path_ctx[RM_DRV_CHN_MAX_NUM + 1];
static td_u32 g_u32_reserve;
osal_semaphore g_rm_drv_mutex;
/* 初始化上下文 */
static td_void rm_drv_comm_de_init_path_ctx(td_u32 rm_path_id)
{
osal_wait_destroy(&g_st_rm_drv_path_ctx[rm_path_id].wait_queue);
return;
}
static td_void rm_drv_comm_de_init_golbal_ctx(td_void)
{
osal_wait_destroy(&g_st_rm_drv_golbal_ctx.wait_queue);
return;
}
static td_void rm_drv_comm_init_path_ctx(td_u32 rm_path_id)
{
errno_t err;
err = memset_s(&g_st_rm_drv_path_ctx[rm_path_id], sizeof(g_st_rm_drv_path_ctx), 0, sizeof(rm_drv_path_ctx));
if (err != EOK) {
soc_log_err("rm_drv_comm_init_path_ctx memset_s fail!\n");
return;
}
g_st_rm_drv_path_ctx[rm_path_id].rm_handle = TD_INVALID_HANDLE;
osal_wait_init(&g_st_rm_drv_path_ctx[rm_path_id].wait_queue);
return;
}
static td_void rm_drv_comm_init_golbal_ctx(td_void)
{
td_s32 i;
memset_s(&g_st_rm_drv_golbal_ctx, sizeof(g_st_rm_drv_golbal_ctx), 0, sizeof(rm_drv_golbal_ctx));
g_st_rm_drv_golbal_ctx.wake_up_cnt = 0;
g_st_rm_drv_golbal_ctx.path_recycle_cnt = 0;
g_st_rm_drv_golbal_ctx.normal_cnt = 0;
g_st_rm_drv_golbal_ctx.rm_path_count = 0;
g_st_rm_drv_golbal_ctx.rm_available_win_count = RM_DRV_WIN_MAX_COUNT;
g_st_rm_drv_golbal_ctx.wake_up_flags = TD_FALSE;
g_st_rm_drv_golbal_ctx.waiting_event = TD_FALSE;
g_st_rm_drv_golbal_ctx.wind_owner = EXT_DRV_WIN_OWNER_BUTT;
g_st_rm_drv_golbal_ctx.win_owner_id = 0;
for (i = 0; i < RM_DRV_CHN_MAX_NUM; i++) {
g_st_rm_drv_golbal_ctx.chn_create_cnt[i] = 0;
g_st_rm_drv_golbal_ctx.chn_destroy_cnt[i] = 0;
}
g_u32_reserve = 0;
osal_wait_init(&g_st_rm_drv_golbal_ctx.wait_queue);
return;
}
/* 获取上下文 */
td_void rm_drv_comm_get_path_ctx(td_u32 rm_path_id, rm_drv_path_ctx **rm_drv_path_ctx_p)
{
if (rm_drv_path_ctx_p == TD_NULL) {
soc_log_err("rm_drv_path_ctx_p is null!\n");
return;
}
*rm_drv_path_ctx_p = &g_st_rm_drv_path_ctx[rm_path_id];
return;
}
/* 获取上下文 */
td_void rm_drv_comm_get_golbal_ctx(rm_drv_golbal_ctx **rm_drv_golbal_ctx_p)
{
if (rm_drv_golbal_ctx_p == TD_NULL) {
soc_log_err("rm_drv_golbal_ctx_p is null!\n");
return;
}
*rm_drv_golbal_ctx_p = &g_st_rm_drv_golbal_ctx;
return;
}
/* get current time */
td_void rm_drv_comm_get_cur_time(td_u32 *cur_time_us_p)
{
osal_timeval time;
osal_gettimeofday(&time);
if (cur_time_us_p == TD_NULL) {
soc_log_err("cur_time_us_p is null!\n");
return;
}
if ((time.tv_sec * 1000000ULL + time.tv_usec) < 0xffffffff) {
*cur_time_us_p = time.tv_sec * 1000000 + time.tv_usec; /* 1000000 uesed convert second to microsecond */
} else {
*cur_time_us_p = 0;
}
return;
}
static td_s32 rm_drv_ctrl_put_win_event_to_list(ext_drv_rm_win_event win_event)
{
td_s32 ret;
td_s32 result = TD_SUCCESS;
td_u32 rm_path_id;
rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL;
ext_drv_rm_event rm_event;
for (rm_path_id = 0; rm_path_id < RM_DRV_CHN_MAX_NUM; rm_path_id++) {
rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p);
if (rm_drv_path_ctx_p->rm_handle != TD_INVALID_HANDLE) {
rm_event.win_event = win_event;
ret = rm_drv_comm_put_event(rm_drv_path_ctx_p->rm_handle, rm_drv_path_ctx_p->event_handle_p, &rm_event);
if (ret != TD_SUCCESS) {
soc_log_dbg("put event in list failed!\n");
soc_dbg_print_u32(win_event);
soc_dbg_print_u32(rm_path_id);
result = TD_FAILURE;
}
rm_drv_path_ctx_p->list_empty = TD_FALSE;
}
}
return result;
}
/* 获取空闲RM path id */
static td_s32 rm_drv_ctrl_get_free_path_id(td_u32 *rm_path_id_p)
{
td_u32 rm_path_id;
rm_drv_path_ctx *rm_path_ctx_p = TD_NULL;
for (rm_path_id = 0; rm_path_id < RM_DRV_CHN_MAX_NUM; rm_path_id++) {
rm_path_ctx_p = &g_st_rm_drv_path_ctx[rm_path_id];
if (rm_path_ctx_p->rm_handle == TD_INVALID_HANDLE) {
*rm_path_id_p = rm_path_id;
return TD_SUCCESS;
}
}
return SOC_ERR_RM_NOT_FREE_INST;
}
static td_s32 rm_drv_ctrl_wake_up_waiting_event(td_void)
{
rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL;
rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p);
check_rm_null_ptr(rm_drv_golbal_ctx_p);
rm_drv_golbal_ctx_p->wake_up_flags = TD_TRUE;
osal_wait_wakeup(&rm_drv_golbal_ctx_p->wait_queue);
return TD_SUCCESS;
}
static td_s32 rm_drv_ctrl_disable(td_handle rm_handle)
{
td_u32 rm_path_id = 0;
rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL;
if (rm_handle == TD_INVALID_HANDLE) {
soc_log_err("rm handle is invalid.\n");
return SOC_ERR_RM_INVALID_HANDLE;
}
if (((rm_path_id) = (rm_handle) & 0xff) >= RM_DRV_CHN_MAX_NUM) {
soc_log_err("rm path id is over range.rm_id = 0x%08X\n", rm_path_id);
return SOC_ERR_RM_INST_OVER_RANGE;
}
rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p);
check_rm_null_ptr(rm_drv_path_ctx_p);
if (rm_handle != rm_drv_path_ctx_p->rm_handle) {
soc_log_err("src_rm_handle is not equal dest_rm_handle.\n");
soc_err_print_h32(rm_handle);
soc_err_print_h32(rm_drv_path_ctx_p->rm_handle);
return SOC_ERR_RM_INVALID_HANDLE;
}
if (rm_drv_path_ctx_p->chn_enable != TD_FALSE) {
rm_drv_path_ctx_p->chn_enable = TD_FALSE;
} else {
soc_log_err("path is already disable!\n");
soc_err_print_u32(rm_path_id);
return SOC_ERR_RM_DISABLE_ERR;
}
return TD_SUCCESS;
}
static td_s32 rm_drv_ctrl_destroy(td_handle rm_handle)
{
td_s32 ret;
td_u32 rm_path_id = 0;
rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL;
rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL;
td_handle tmp_rm_handle;
if (rm_handle == TD_INVALID_HANDLE) {
soc_log_err("rm handle is invalid.\n");
return SOC_ERR_RM_INVALID_HANDLE;
}
if (((rm_path_id) = (rm_handle) & 0xff) >= RM_DRV_CHN_MAX_NUM) {
soc_log_err("rm path id is over range.rm_id = 0x%08X\n", rm_path_id);
return SOC_ERR_RM_INST_OVER_RANGE;
}
rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p);
check_rm_null_ptr(rm_drv_path_ctx_p);
if (rm_handle != rm_drv_path_ctx_p->rm_handle) {
soc_log_err("src_rm_handle is not equal dest_rm_handle.\n");
soc_err_print_h32(rm_handle);
soc_err_print_h32(rm_drv_path_ctx_p->rm_handle);
return SOC_ERR_RM_INVALID_HANDLE;
}
tmp_rm_handle = rm_drv_path_ctx_p->rm_handle;
rm_drv_path_ctx_p->rm_handle = TD_INVALID_HANDLE;
ret = rm_drv_comm_de_init_event_list(rm_drv_path_ctx_p->event_handle_p);
if (ret != TD_SUCCESS) {
soc_log_err("de_init event list failed.\n");
rm_drv_path_ctx_p->rm_handle = tmp_rm_handle;
return SOC_ERR_RM_DESTROY_ERR;
}
rm_drv_path_ctx_p->chn_enable = TD_FALSE;
rm_drv_path_ctx_p->event_handle_p = TD_NULL;
rm_drv_path_ctx_p->queue_cnt = 1;
rm_drv_path_ctx_p->try_queue_cnt = 0;
rm_drv_path_ctx_p->cur_pid = 0;
rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p);
check_rm_null_ptr(rm_drv_golbal_ctx_p);
rm_drv_golbal_ctx_p->rm_path_count--;
rm_drv_golbal_ctx_p->chn_destroy_cnt[rm_path_id]++;
return TD_SUCCESS;
}
/* avoid service crash cause path resource leak */
static td_void rm_drv_ctrl_recycle_path_resource(td_void)
{
td_s32 ret1;
td_s32 ret2;
td_u32 rm_path_id;
td_u32 available_rm_path;
rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL;
rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL;
rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p);
if (rm_drv_golbal_ctx_p == TD_NULL) {
soc_log_err("rm_drv_golbal_ctx_p is null ptr.\n");
return;
}
available_rm_path = RM_DRV_CHN_MAX_NUM - rm_drv_golbal_ctx_p->rm_path_count;
if (available_rm_path > 1) {
return;
}
soc_log_err("available rm path less than two!\n");
for (rm_path_id = 0; rm_path_id < RM_DRV_CHN_MAX_NUM; rm_path_id++) {
rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p);
if (rm_drv_path_ctx_p->rm_handle == TD_INVALID_HANDLE) {
continue;
}
if (rm_drv_path_ctx_p->used_node == RM_DRV_LIST_NODE_NUM && rm_drv_path_ctx_p->free_node == 0) {
soc_log_err("path resource leak! recycle it \n");
soc_err_print_u32(rm_path_id);
soc_err_print_u32(rm_drv_path_ctx_p->cur_pid);
ret1 = rm_drv_ctrl_disable(rm_drv_path_ctx_p->rm_handle);
ret2 = rm_drv_ctrl_destroy(rm_drv_path_ctx_p->rm_handle);
if (ret1 != TD_SUCCESS || ret2 != TD_SUCCESS) {
soc_log_err("path resource leak! recycle failed\n");
soc_err_print_u32(rm_path_id);
} else {
rm_drv_path_ctx_p->rm_handle = TD_INVALID_HANDLE;
rm_drv_path_ctx_p->event_handle_p = TD_NULL;
rm_drv_path_ctx_p->chn_enable = TD_FALSE; /* default colse the channel */
rm_drv_path_ctx_p->queue_cnt = 1;
rm_drv_path_ctx_p->try_queue_cnt = 0;
rm_drv_path_ctx_p->free_node = RM_DRV_LIST_NODE_NUM;
rm_drv_path_ctx_p->used_node = 0;
rm_drv_path_ctx_p->cur_index = 0;
rm_drv_path_ctx_p->cur_pid = 0;
rm_drv_golbal_ctx_p->path_recycle_cnt++;
soc_log_dbg("path resource leak! recycle succeed!\n");
soc_dbg_print_u32(rm_path_id);
}
}
}
return;
}
/* check path is idle */
static td_void rm_drv_ctrl_check_idle_path(td_void)
{
td_u32 rm_path_id;
td_u32 cur_sys_time = 0;
td_u32 time_diff;
rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL;
rm_drv_comm_get_cur_time(&cur_sys_time);
for (rm_path_id = 0; rm_path_id < RM_DRV_CHN_MAX_NUM; rm_path_id++) {
rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p);
if (rm_drv_path_ctx_p->rm_handle != TD_INVALID_HANDLE) {
time_diff = cur_sys_time - rm_drv_path_ctx_p->lst_query_time;
rm_drv_path_ctx_p->cur_query_time = cur_sys_time;
if (rm_drv_path_ctx_p->idle == TD_TRUE) {
continue;
}
if (time_diff > RM_DRV_IDLE_MAX_TIME_US && rm_drv_path_ctx_p->used_node >= RM_DRV_IDLE_MAX_USED_NODE) {
rm_drv_path_ctx_p->idle = TD_TRUE;
soc_warn_print_u32(rm_drv_path_ctx_p->cur_pid);
soc_warn_print_bool(rm_drv_path_ctx_p->idle);
}
}
}
return;
}
/* avoid service crash cause path resource leak */
static td_void rm_drv_ctrl_recycle_idle_path(td_void)
{
td_s32 ret;
td_u32 rm_path_id;
rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL;
rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL;
rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p);
for (rm_path_id = 0; rm_path_id < RM_DRV_CHN_MAX_NUM; rm_path_id++) {
rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p);
if (rm_drv_path_ctx_p->rm_handle == TD_INVALID_HANDLE) {
continue;
}
if (rm_drv_path_ctx_p->idle == TD_TRUE) {
soc_log_err("path is idle! recycle it\n");
soc_err_print_u32(rm_path_id);
soc_err_print_u32(rm_drv_path_ctx_p->cur_pid);
ret = rm_drv_ctrl_disable(rm_drv_path_ctx_p->rm_handle);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(rm_drv_ctrl_disable, ret);
soc_err_print_u32(rm_path_id);
}
ret = rm_drv_ctrl_destroy(rm_drv_path_ctx_p->rm_handle);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(rm_drv_ctrl_destroy, ret);
soc_err_print_u32(rm_path_id);
} else {
rm_drv_path_ctx_p->rm_handle = TD_INVALID_HANDLE;
rm_drv_path_ctx_p->event_handle_p = TD_NULL;
rm_drv_path_ctx_p->chn_enable = TD_FALSE; /* default colse the channel */
rm_drv_path_ctx_p->queue_cnt = 1;
rm_drv_path_ctx_p->try_queue_cnt = 0;
rm_drv_path_ctx_p->free_node = RM_DRV_LIST_NODE_NUM;
rm_drv_path_ctx_p->used_node = 0;
rm_drv_path_ctx_p->cur_index = 0;
rm_drv_path_ctx_p->cur_pid = 0;
rm_drv_golbal_ctx_p->path_recycle_cnt++;
soc_log_dbg("path resource leak! recycle succeed!\n");
soc_dbg_print_u32(rm_path_id);
}
}
}
return;
}
td_s32 rm_drv_ctrl_query_event(td_handle rm_handle, ext_drv_rm_event *rm_event_p)
{
td_s32 ret = TD_FAILURE;
td_u32 rm_path_id = 0;
rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL;
ext_drv_rm_event rm_event;
if (rm_handle == TD_INVALID_HANDLE) {
soc_log_err("rm handle is invalid.\n");
return SOC_ERR_RM_INVALID_HANDLE;
}
if (((rm_path_id) = (rm_handle) & 0xff) >= RM_DRV_CHN_MAX_NUM) {
soc_log_err("rm path id is over range.rm_id = 0x%08X\n", rm_path_id);
return SOC_ERR_RM_INST_OVER_RANGE;
}
rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p);
check_rm_null_ptr(rm_drv_path_ctx_p);
if (rm_handle != rm_drv_path_ctx_p->rm_handle) {
soc_log_err("src_rm_handle[%d] is not equal dest_rm_handle[%d].\n", rm_handle, rm_drv_path_ctx_p->rm_handle);
soc_err_print_h32(rm_handle);
soc_err_print_h32(rm_drv_path_ctx_p->rm_handle);
return SOC_ERR_RM_INVALID_HANDLE;
}
rm_drv_path_ctx_p->try_queue_cnt++;
rm_drv_path_ctx_p->lst_query_time = rm_drv_path_ctx_p->cur_query_time;
rm_drv_comm_get_cur_time(&rm_drv_path_ctx_p->cur_query_time);
rm_drv_path_ctx_p->query_time_diff = rm_drv_path_ctx_p->cur_query_time - rm_drv_path_ctx_p->lst_query_time;
rm_drv_path_ctx_p->idle = TD_FALSE;
if ((rm_drv_path_ctx_p->list_empty == TD_FALSE) && (rm_drv_path_ctx_p->chn_enable == TD_TRUE)) {
ret = rm_drv_comm_get_event(rm_drv_path_ctx_p->rm_handle, rm_drv_path_ctx_p->event_handle_p, &rm_event);
if (ret == TD_SUCCESS) {
rm_drv_path_ctx_p->queue_cnt++;
ret = memcpy_s(rm_event_p, sizeof(ext_drv_rm_event), &rm_event, sizeof(rm_event));
if (ret != TD_SUCCESS) {
soc_log_err("call memcpy_s err!\n");
return ret;
}
soc_log_info("RM event:%d!\n", rm_event_p->win_event);
}
}
return ret;
}
td_s32 ext_drv_rm_init(td_void)
{
td_u32 i;
soc_info_func_enter();
/* 初始化上下文 */
for (i = 0; i < RM_DRV_CHN_MAX_NUM; i++) {
rm_drv_comm_init_path_ctx(i);
}
rm_drv_comm_init_golbal_ctx();
(td_void)rm_drv_proc_add();
osal_sem_init(&g_rm_drv_mutex, 1);
soc_info_func_exit();
return TD_SUCCESS;
}
td_void ext_drv_rm_de_init(td_void)
{
td_u32 i;
soc_info_func_enter();
/* 初始化上下文 */
for (i = 0; i < RM_DRV_CHN_MAX_NUM; i++) {
rm_drv_comm_de_init_path_ctx(i);
}
rm_drv_comm_de_init_golbal_ctx();
(td_void)rm_drv_proc_del();
osal_sem_destroy(&g_rm_drv_mutex);
soc_info_func_exit();
return;
}
td_s32 ext_drv_rm_create(td_handle *rm_handle, td_u32 pid)
{
td_s32 ret;
td_u32 rm_path_id = 0;
td_void *list_handle_p = TD_NULL;
rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL;
rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL;
rm_drv_list_attr list_attr;
soc_info_func_enter();
check_rm_null_ptr(rm_handle);
osal_sem_down(&g_rm_drv_mutex);
ret = rm_drv_ctrl_get_free_path_id(&rm_path_id); /* 检查是否满足创建条件 */
if (ret != TD_SUCCESS) {
soc_log_err("get free rm id failed\n");
osal_sem_up(&g_rm_drv_mutex);
return SOC_ERR_RM_NOT_FREE_INST;
}
list_attr.list_node_num = RM_DRV_LIST_NODE_NUM;
ret = rm_drv_comm_init_event_list(&list_attr, &list_handle_p);
if (ret == TD_SUCCESS) { /* 返回生成的handle号 */
*rm_handle = ((SOC_ID_RM << 8) | rm_path_id); /* 8 means letf sheft 8 bit */
rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p);
check_rm_null_ptr(rm_drv_path_ctx_p);
rm_drv_path_ctx_p->rm_handle = *rm_handle;
rm_drv_path_ctx_p->event_handle_p = list_handle_p;
rm_drv_path_ctx_p->chn_enable = TD_FALSE; /* default colse the channel */
rm_drv_path_ctx_p->queue_cnt = 1;
rm_drv_path_ctx_p->try_queue_cnt = 0;
rm_drv_path_ctx_p->free_node = RM_DRV_LIST_NODE_NUM;
rm_drv_path_ctx_p->used_node = 0;
rm_drv_path_ctx_p->cur_index = 0;
rm_drv_path_ctx_p->cur_pid = pid;
rm_drv_path_ctx_p->list_empty = TD_TRUE;
rm_drv_path_ctx_p->idle = TD_FALSE;
rm_drv_path_ctx_p->cur_query_time = 0;
rm_drv_path_ctx_p->lst_query_time = 0;
rm_drv_path_ctx_p->query_time_diff = 0;
rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p);
check_rm_null_ptr(rm_drv_golbal_ctx_p);
rm_drv_golbal_ctx_p->rm_path_count++;
rm_drv_golbal_ctx_p->chn_create_cnt[rm_path_id]++;
}
osal_sem_up(&g_rm_drv_mutex);
soc_info_func_exit();
return ret;
}
td_s32 ext_drv_rm_destroy(td_handle rm_handle)
{
td_s32 ret;
soc_info_func_enter();
osal_sem_down(&g_rm_drv_mutex);
ret = rm_drv_ctrl_destroy(rm_handle);
osal_sem_up(&g_rm_drv_mutex);
soc_info_func_exit();
return ret;
}
td_s32 ext_drv_rm_enable(td_handle rm_handle)
{
td_u32 rm_path_id = 0;
td_s32 ret = TD_SUCCESS;
rm_drv_path_ctx *rm_drv_path_ctx_p = TD_NULL;
soc_info_func_enter();
if (rm_handle == TD_INVALID_HANDLE) {
soc_log_err("rm handle is invalid.\n");
return SOC_ERR_RM_INVALID_HANDLE;
}
if (((rm_path_id) = (rm_handle) & 0xff) >= RM_DRV_CHN_MAX_NUM) {
soc_log_err("rm path id is over range.rm_id = 0x%08X\n", rm_path_id);
return SOC_ERR_RM_INST_OVER_RANGE;
}
rm_drv_comm_get_path_ctx(rm_path_id, &rm_drv_path_ctx_p);
check_rm_null_ptr(rm_drv_path_ctx_p);
if (rm_handle != rm_drv_path_ctx_p->rm_handle) {
soc_log_err("src_rm_handle[%d] is not equal dest_rm_handle[%d].\n", rm_handle, rm_drv_path_ctx_p->rm_handle);
soc_err_print_h32(rm_handle);
soc_err_print_h32(rm_drv_path_ctx_p->rm_handle);
return SOC_ERR_RM_INVALID_HANDLE;
}
osal_sem_down(&g_rm_drv_mutex);
if (rm_drv_path_ctx_p->chn_enable != TD_TRUE) {
rm_drv_path_ctx_p->chn_enable = TD_TRUE;
} else {
soc_log_err("path is already enable!\n");
soc_err_print_u32(rm_path_id);
ret = SOC_ERR_RM_ENABLE_ERR;
}
osal_sem_up(&g_rm_drv_mutex);
soc_info_func_exit();
return ret;
}
td_s32 ext_drv_rm_disable(td_handle rm_handle)
{
td_s32 ret;
soc_info_func_enter();
osal_sem_down(&g_rm_drv_mutex);
ret = rm_drv_ctrl_disable(rm_handle);
osal_sem_up(&g_rm_drv_mutex);
soc_info_func_exit();
return ret;
}
td_s32 ext_drv_rm_query_event(td_handle rm_handle, ext_drv_rm_event *rm_event_p)
{
td_s32 ret;
check_rm_null_ptr(rm_event_p);
osal_sem_down(&g_rm_drv_mutex);
ret = rm_drv_ctrl_query_event(rm_handle, rm_event_p);
osal_sem_up(&g_rm_drv_mutex);
return ret;
}
static td_s32 rm_wait_condition(const void *data)
{
if (*(td_bool *)data == TD_TRUE) {
return 1;
}
return 0;
}
td_s32 ext_drv_rm_acquire_window_handle(td_u32 pid)
{
td_s32 remain_time = 10;
td_s32 ret;
rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL;
soc_info_func_enter();
rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p);
check_rm_null_ptr(rm_drv_golbal_ctx_p);
rm_drv_ctrl_check_idle_path();
osal_sem_down(&g_rm_drv_mutex);
rm_drv_ctrl_recycle_idle_path();
osal_sem_up(&g_rm_drv_mutex);
if (rm_drv_golbal_ctx_p->rm_available_win_count > 0) {
rm_drv_golbal_ctx_p->normal_cnt++;
rm_drv_golbal_ctx_p->win_owner_id = pid;
soc_info_func_exit();
return TD_SUCCESS;
} else {
/* set waiting event flag true */
osal_sem_down(&g_rm_drv_mutex);
rm_drv_golbal_ctx_p->waiting_event = TD_TRUE;
ret = rm_drv_ctrl_put_win_event_to_list(EXT_DRV_RM_EVENT_WIN_LACK);
if (ret != TD_SUCCESS) {
soc_log_dbg("put event to list error!\n");
rm_drv_ctrl_recycle_path_resource();
}
osal_sem_up(&g_rm_drv_mutex);
remain_time = osal_wait_timeout_interruptible(&rm_drv_golbal_ctx_p->wait_queue, rm_wait_condition,
&rm_drv_golbal_ctx_p->wake_up_flags, (HZ * 5)); /* (HZ * 5) means the max sleep time */
if (remain_time > 0) { /* 大于零表示非timeout */
rm_drv_golbal_ctx_p->wake_up_cnt++;
rm_drv_golbal_ctx_p->wake_up_time = remain_time;
rm_drv_golbal_ctx_p->wake_up_flags = TD_FALSE;
rm_drv_golbal_ctx_p->waiting_event = TD_FALSE;
rm_drv_golbal_ctx_p->win_owner_id = pid;
soc_info_func_exit();
return TD_SUCCESS;
}
}
soc_log_err("acquire window resource failed,waiting time out.\n");
soc_err_print_u32(remain_time);
soc_info_func_exit();
return SOC_ERR_RM_NOT_RESOURCE;
}
td_s32 ext_drv_rm_notify_wind_created(td_handle win_handle)
{
td_s32 ret;
rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL;
soc_info_func_enter();
osal_sem_down(&g_rm_drv_mutex);
rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p);
check_rm_null_ptr(rm_drv_golbal_ctx_p);
rm_drv_golbal_ctx_p->rm_available_win_count--;
soc_info_print_s32(rm_drv_golbal_ctx_p->rm_available_win_count);
ret = rm_drv_ctrl_put_win_event_to_list(EXT_DRV_RM_EVENT_WIN_CREATED);
if (ret != TD_SUCCESS) {
soc_log_dbg("put event to list error!\n");
rm_drv_ctrl_recycle_path_resource();
}
osal_sem_up(&g_rm_drv_mutex);
soc_info_func_exit();
return ret;
}
td_s32 ext_drv_rm_notify_wind_destroyed(td_handle win_handle)
{
td_s32 ret;
rm_drv_golbal_ctx *rm_drv_golbal_ctx_p = TD_NULL;
soc_info_func_enter();
osal_sem_down(&g_rm_drv_mutex);
rm_drv_comm_get_golbal_ctx(&rm_drv_golbal_ctx_p);
check_rm_null_ptr(rm_drv_golbal_ctx_p);
rm_drv_golbal_ctx_p->rm_available_win_count++;
soc_info_print_s32(rm_drv_golbal_ctx_p->rm_available_win_count);
rm_drv_golbal_ctx_p->wake_up_flags = TD_FALSE;
if (rm_drv_golbal_ctx_p->waiting_event) {
rm_drv_ctrl_wake_up_waiting_event();
}
ret = rm_drv_ctrl_put_win_event_to_list(EXT_DRV_RM_EVENT_WIN_DESTROYED);
if (ret != TD_SUCCESS) {
soc_log_dbg("put event to list error!\n");
rm_drv_ctrl_recycle_path_resource();
}
osal_sem_up(&g_rm_drv_mutex);
soc_info_func_exit();
return ret;
}