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.

823 lines
23 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2019. All rights reserved.
* Description: mpi_rm.c
* Author: sm_rm
* Create: 2012-12-01
*/
#include <sys/ioctl.h>
#include "securec.h"
#include "soc_errno.h"
#include "mpi_rm_ext.h"
#include "drv_ioctl_rm.h"
#include "mpi_rm_define.h"
#include "mpi_rm.h"
/********************************************************************************/
/* Global */
/********************************************************************************/
static td_s32 g_rm_dev_fd = -1;
static td_u32 g_rm_dev_init_cnt = 0;
static td_bool g_rm_check_open = TD_FALSE;
#define SOC_DEV_RM_NAME "soc_rm"
static const td_char g_rm_dev_name[] = "/dev/" SOC_DEV_RM_NAME;
static ext_rm_ctx g_rm_ctx;
static pthread_mutex_t g_rm_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_rm_cb_inst_mutex = PTHREAD_MUTEX_INITIALIZER;
static ext_rm_cb_instance g_rm_cb_instance[MAX_CALLBACK_NUM];
/********************************************************************************/
/* Define */
/********************************************************************************/
#define ext_rm_lock() (td_void)pthread_mutex_lock(&g_rm_mutex)
#define ext_rm_unlock() (td_void)pthread_mutex_unlock(&g_rm_mutex)
#define ext_rm_list_lock() (td_void)pthread_mutex_lock(&g_rm_cb_inst_mutex)
#define ext_rm_list_unlock() (td_void)pthread_mutex_unlock(&g_rm_cb_inst_mutex)
/********************************************************************************/
/* Array */
/********************************************************************************/
td_char *g_pen_rm_event[EXT_RM_EVENT_MAX + 1] = {
"undefine",
"LACK",
"CREATED",
"undefine",
"DESTROYED",
"BUTT"
};
/* Private API */
static td_s32 rm_mpi_convert_event_drv_to_iapi(ext_drv_rm_win_event drv_rm_event, ext_rm_event *pen_iapi_rm_event)
{
if (pen_iapi_rm_event == NULL) {
soc_log_err("rm_mpi_convert_event_drv_to_iapi pen_iapi_rm_event is null pointer.\n");
return SOC_ERR_RM_NULL_PTR;
}
switch (drv_rm_event) {
case EXT_DRV_RM_EVENT_WIN_LACK:
*pen_iapi_rm_event = EXT_RM_EVENT_WIN_LACK;
break;
case EXT_DRV_RM_EVENT_WIN_CREATED:
*pen_iapi_rm_event = EXT_RM_EVENT_WIN_CREATED;
break;
case EXT_DRV_RM_EVENT_WIN_DESTROYED:
*pen_iapi_rm_event = EXT_RM_EVENT_WIN_DESTROYED;
break;
default:
*pen_iapi_rm_event = EXT_RM_EVENT_MAX;
}
return TD_SUCCESS;
}
static td_s32 rm_mpi_create_event_path(td_u32 pid)
{
td_s32 ret;
rm_create create;
create.rm_handle = TD_INVALID_HANDLE;
create.pid = pid;
ret = ioctl(g_rm_dev_fd, CMD_RM_CREATE, &create);
if (ret != TD_SUCCESS) {
soc_log_err("call RM ioctl CMD:CMD_RM_CREATE failed, ret: [0x%08X].\n", ret);
return ret;
}
if (create.rm_handle == TD_INVALID_HANDLE) {
soc_log_err("create.rm_handle is invalid.\n");
return SOC_ERR_RM_INVALID_HANDLE;
}
g_rm_ctx.rm_handle = create.rm_handle;
return TD_SUCCESS;
}
static td_s32 rm_mpi_destroy_event_path(td_void)
{
td_s32 ret;
if (g_rm_ctx.rm_handle == TD_INVALID_HANDLE) {
soc_log_err("rm handle is invalid.\n");
return SOC_ERR_RM_INVALID_HANDLE;
}
ret = ioctl(g_rm_dev_fd, CMD_RM_DESTROY, &g_rm_ctx.rm_handle);
if (ret != TD_SUCCESS) {
soc_log_err("call RM ioctl CMD:CMD_RM_DESTROY failed, ret: [0x%08X].\n", ret);
return ret;
}
return TD_SUCCESS;
}
static td_s32 rm_mpi_enable_event_path(td_void)
{
td_s32 ret;
if (g_rm_ctx.rm_handle == TD_INVALID_HANDLE) {
soc_log_err("rm handle is invalid.\n");
return SOC_ERR_RM_INVALID_HANDLE;
}
ret = ioctl(g_rm_dev_fd, CMD_RM_ENABLE, &g_rm_ctx.rm_handle);
if (ret != TD_SUCCESS) {
soc_log_err("call RM ioctl CMD:CMD_RM_ENABLE failed, ret: [0x%08X].\n", ret);
return ret;
}
return TD_SUCCESS;
}
static td_s32 rm_mpi_disable_event_path(td_void)
{
td_s32 ret;
if (g_rm_ctx.rm_handle == TD_INVALID_HANDLE) {
soc_log_err("rm handle is invalid.\n");
return SOC_ERR_RM_INVALID_HANDLE;
}
ret = ioctl(g_rm_dev_fd, CMD_RM_DISABLE, &g_rm_ctx.rm_handle);
if (ret != TD_SUCCESS) {
soc_log_err("call RM ioctl CMD:CMD_RM_DISABLE failed, ret: [0x%08X].\n", ret);
return ret;
}
return TD_SUCCESS;
}
static td_s32 rm_mpi_query_event(ext_rm_event *pen_iapi_rm_event)
{
td_s32 ret;
rm_event rm_query;
ext_drv_rm_win_event drv_rm_event;
g_rm_ctx.event_querying = TD_TRUE;
if (g_rm_ctx.rm_handle == TD_INVALID_HANDLE) {
soc_log_err("rm handle is invalid.\n");
return SOC_ERR_RM_INVALID_HANDLE;
}
memset_s(&rm_query, sizeof(rm_query), 0x0, sizeof(rm_event));
rm_query.rm_handle = g_rm_ctx.rm_handle;
ret = ioctl(g_rm_dev_fd, CMD_RM_QUERY, &rm_query);
if (ret != TD_SUCCESS) {
soc_func_trace_low_freq_cnt_begin(LOW_FREQ_CNT);
soc_log_dbg("query event is failed.\n");
soc_func_trace_low_freq_cnt_end();
g_rm_ctx.event_querying = TD_FALSE;
return ret;
}
drv_rm_event = rm_query.rm_event.win_event;
ret = rm_mpi_convert_event_drv_to_iapi(drv_rm_event, pen_iapi_rm_event);
if (ret != TD_SUCCESS) {
soc_log_err("rm_mpi_convert_event_drv_to_iapi error, %d!\n", ret);
}
g_rm_ctx.event_querying = TD_FALSE;
return TD_SUCCESS;
}
static td_void rm_mpi_event_call_back(ext_rm_event iapi_rm_event)
{
td_u32 i;
td_s32 ret;
td_u32 event = 0;
ext_rm_cb_instance rm_cb_instance[MAX_CALLBACK_NUM];
soc_dbg_func_enter();
ext_rm_list_lock();
g_rm_ctx.instance_copying = TD_TRUE;
for (i = 0; i < MAX_CALLBACK_NUM; i++) {
rm_cb_instance[i].client = g_rm_cb_instance[i].client;
rm_cb_instance[i].event = g_rm_cb_instance[i].event;
rm_cb_instance[i].pid = g_rm_cb_instance[i].pid;
rm_cb_instance[i].pfn_rm_event_callback = g_rm_cb_instance[i].pfn_rm_event_callback;
}
g_rm_ctx.instance_copying = TD_FALSE;
ext_rm_list_unlock();
soc_dbg_func_enter();
for (i = 0; i < MAX_CALLBACK_NUM; i++) {
event = rm_cb_instance[i].event;
if ((rm_cb_instance[i].pfn_rm_event_callback == TD_NULL) ||
(iapi_rm_event == EXT_RM_EVENT_MAX)) {
soc_log_err("rm_event_callback is NULL or iapi_rm_event(%d) invalid.\n", iapi_rm_event);
continue;
}
if (((event & (td_u32)EXT_RM_EVENT_WIN_LACK) == iapi_rm_event) ||
((event & (td_u32)EXT_RM_EVENT_WIN_CREATED) == iapi_rm_event) ||
((event & (td_u32)EXT_RM_EVENT_WIN_DESTROYED) == iapi_rm_event)) {
soc_log_info("***not a bug,only for debug.***\n");
soc_info_print_u32(g_rm_ctx.pid);
soc_notice_print_u32(rm_cb_instance[i].pid);
soc_notice_print_str(g_pen_rm_event[iapi_rm_event]);
g_rm_ctx.call_backing = TD_TRUE;
ret = rm_cb_instance[i].pfn_rm_event_callback(rm_cb_instance[i].client, iapi_rm_event, 0);
if (ret != TD_SUCCESS) {
soc_log_err("call_back function execute error!\n");
}
g_rm_ctx.call_backing = TD_FALSE;
}
}
soc_dbg_func_exit();
return;
}
static td_void *rm_mpi_event_process_thread(td_void *arg)
{
td_s32 ret;
td_u32 cnt = 0;
td_u32 pid = 0;
ext_rm_event rm_event = EXT_RM_EVENT_MAX;
TD_UNUSED(arg);
TD_UNUSED(pid);
while (g_rm_ctx.thread_run) {
if (g_rm_ctx.task_start == TD_TRUE) {
ret = rm_mpi_query_event(&rm_event);
if (ret != TD_SUCCESS) {
ext_usleep(THREAT_SLEEP_TIME);
} else {
rm_mpi_event_call_back(rm_event);
}
cnt++;
if (cnt >= 500) { /* 500 uesd to reduce print freq */
pid = (td_u32)getpid();
soc_dbg_print_u32(pid);
soc_dbg_print_str(g_pen_rm_event[rm_event]);
cnt = 0;
}
g_rm_ctx.task_status = EXT_RM_TASK_STATUS_RUNNING;
} else {
g_rm_ctx.task_status = EXT_RM_TASK_STATUS_PAUSED;
ext_usleep(THREAT_SLEEP_TIME);
continue;
}
}
return TD_NULL;
}
static td_s32 rm_mpi_create_query_thread(td_void)
{
td_s32 ret;
g_rm_ctx.thread_run = TD_TRUE;
(td_void)pthread_attr_init(&g_rm_ctx.rm_query_thread_attr);
(td_void)pthread_attr_setschedpolicy(&g_rm_ctx.rm_query_thread_attr, SCHED_OTHER);
/* create rm event query process thread */
ret = pthread_create(&g_rm_ctx.rm_query_thd_inst, &g_rm_ctx.rm_query_thread_attr,
rm_mpi_event_process_thread, TD_NULL);
if (ret != TD_SUCCESS) {
pthread_attr_destroy(&g_rm_ctx.rm_query_thread_attr);
soc_err_print_call_fun_err(pthread_create, ret);
return TD_FAILURE;
}
return TD_SUCCESS;
}
static td_void rm_mpi_destroy_query_thread(td_void)
{
td_s32 ret;
g_rm_ctx.thread_run = TD_FALSE;
ret = pthread_join(g_rm_ctx.rm_query_thd_inst, TD_NULL);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(pthread_join, ret);
}
ret = pthread_attr_destroy(&g_rm_ctx.rm_query_thread_attr);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(pthread_attr_destroy, ret);
}
g_rm_ctx.rm_query_thd_inst = 0;
}
static td_void rm_mpi_task_suspend(td_void)
{
td_u32 suspend_time = 0;
if (g_rm_ctx.thread_run == TD_TRUE) {
g_rm_ctx.task_start = TD_FALSE;
while (g_rm_ctx.task_status != EXT_RM_TASK_STATUS_PAUSED) {
ext_usleep(THREAT_SLEEP_TIME); /* wait task paused */
suspend_time += THREAT_SLEEP_TIME;
/* THREAT_SLEEP_TIME * 1000 means dead lock */
if (suspend_time > (THREAT_SLEEP_TIME * 1000)) {
soc_func_trace_low_freq_cnt_begin(LOW_FREQ_CNT);
soc_log_err("dead lock, prohibit calling other RM interfaces in callback function!!!\n");
soc_err_print_bool(g_rm_ctx.call_backing);
soc_err_print_bool(g_rm_ctx.instance_copying);
soc_err_print_bool(g_rm_ctx.event_querying);
soc_err_print_bool(g_rm_ctx.task_start);
soc_err_print_u32(g_rm_ctx.pid);
soc_func_trace_low_freq_cnt_end();
}
continue;
}
}
soc_log_dbg("suspend_time = %u(us)\n", suspend_time);
return;
}
static td_void rm_mpi_task_resume(td_void)
{
if (g_rm_ctx.thread_run == TD_TRUE && g_rm_ctx.query_path_exist == TD_TRUE) {
g_rm_ctx.task_start = TD_TRUE;
soc_info_print_bool(g_rm_ctx.task_start);
}
soc_log_dbg("task resume ok\n");
return;
}
static td_void rm_mpi_init_instance(td_void)
{
td_u32 i;
ext_rm_list_lock();
for (i = 0; i < MAX_CALLBACK_NUM; i++) {
g_rm_cb_instance[i].client = TD_NULL;
g_rm_cb_instance[i].pfn_rm_event_callback = TD_NULL;
g_rm_cb_instance[i].event = 0;
g_rm_cb_instance[i].pid = 0;
}
ext_rm_list_unlock();
return;
}
static td_void rm_mpi_init_ctx(td_void)
{
g_rm_ctx.rm_handle = TD_INVALID_HANDLE;
g_rm_ctx.task_start = TD_FALSE;
g_rm_ctx.thread_run = TD_FALSE;
g_rm_ctx.task_status = EXT_RM_TASK_STATUS_PAUSED;
g_rm_ctx.query_path_exist = TD_FALSE;
g_rm_ctx.rm_query_thd_inst = 0;
g_rm_ctx.pid = 0;
g_rm_ctx.call_backing = TD_FALSE;
return;
}
static td_s32 rm_mpi_create_query_path(td_void)
{
td_s32 ret;
td_u32 pid;
pid = (td_u32)getpid();
g_rm_ctx.pid = pid;
ret = rm_mpi_create_event_path(pid);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(rm_mpi_create_event_path, ret);
return TD_FAILURE;
}
ret = rm_mpi_create_query_thread();
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(rm_mpi_create_query_thread, ret);
goto DESTROY_PATH;
}
ret = rm_mpi_enable_event_path();
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(rm_mpi_enable_event_path, ret);
goto DESTROY_THREAD;
}
return TD_SUCCESS;
DESTROY_THREAD:
rm_mpi_destroy_query_thread();
DESTROY_PATH:
ret = rm_mpi_destroy_event_path();
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(rm_mpi_destroy_event_path, ret);
}
return TD_FAILURE;
}
static td_s32 rm_mpi_destroy_query_path(td_void)
{
td_s32 ret;
rm_mpi_destroy_query_thread();
ret = rm_mpi_disable_event_path();
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(rm_mpi_disable_event_path, ret);
}
ret = rm_mpi_destroy_event_path();
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(rm_mpi_destroy_event_path, ret);
return TD_FAILURE;
}
rm_mpi_init_instance();
g_rm_ctx.query_path_exist = TD_FALSE;
return TD_SUCCESS;
}
static td_s32 rm_mpi_get_free_instance(td_u32 *instance_id_p)
{
td_u32 i;
ext_rm_list_lock();
for (i = 0; i < MAX_CALLBACK_NUM; i++) {
if (g_rm_cb_instance[i].pfn_rm_event_callback == TD_NULL) {
*instance_id_p = i;
break;
}
}
ext_rm_list_unlock();
if (i == MAX_CALLBACK_NUM) {
return TD_FAILURE;
}
return TD_SUCCESS;
}
static td_bool rm_mpi_find_instance_by_client(const td_void *client, td_u32 *instance_id_p)
{
td_u32 i;
ext_rm_list_lock();
for (i = 0; i < MAX_CALLBACK_NUM; i++) {
if (client == g_rm_cb_instance[i].client) {
*instance_id_p = i;
break;
}
}
ext_rm_list_unlock();
if (i == MAX_CALLBACK_NUM) {
return TD_FALSE;
}
return TD_TRUE;
}
static td_bool rm_mpi_need_destroy_path(td_void)
{
td_u32 i;
ext_rm_list_lock();
for (i = 0; i < MAX_CALLBACK_NUM; i++) {
if (g_rm_cb_instance[i].pfn_rm_event_callback != TD_NULL) {
break;
}
}
ext_rm_list_unlock();
if (i == MAX_CALLBACK_NUM) {
return TD_TRUE;
}
return TD_FALSE;
}
static td_s32 rm_mpi_check_and_open(td_void)
{
td_char path[PATH_MAX] = {0};
if (g_rm_dev_fd < 0) {
soc_log_info("current RM not open, open it\n");
if (realpath(g_rm_dev_name, path) == TD_NULL) {
soc_log_err("get realpath error!\n");
return TD_FAILURE;
}
g_rm_dev_fd = open(path, O_RDWR | O_NONBLOCK, 0);
if (g_rm_dev_fd < 0) {
soc_log_err("open RM err.\n");
return SOC_ERR_RM_DEV_OPEN_ERR;
}
g_rm_check_open = TD_TRUE;
}
return TD_SUCCESS;
}
static td_s32 rm_mpi_reg_callback(const td_void *client, ext_rm_event_cb_fn fn, td_u32 event)
{
td_s32 ret = TD_SUCCESS;
td_u32 instance = 0;
td_bool instance_exist;
if (g_rm_ctx.query_path_exist == TD_FALSE) {
ret = rm_mpi_create_query_path();
if (ret == TD_FAILURE) {
soc_err_print_call_fun_err(rm_mpi_create_query_path, ret);
rm_mpi_task_resume();
return SOC_ERR_RM_CREATE_ERR;
}
ret = rm_mpi_get_free_instance(&instance);
if (ret == TD_FAILURE) {
soc_err_print_call_fun_err(rm_mpi_get_free_instance, ret);
ret = rm_mpi_destroy_query_path();
if (ret == TD_FAILURE) {
soc_err_print_call_fun_err(rm_mpi_destroy_query_path, ret);
} else {
g_rm_ctx.query_path_exist = TD_FALSE;
}
rm_mpi_task_resume();
return SOC_ERR_RM_NOT_FREE_CB_INST;
}
g_rm_ctx.query_path_exist = TD_TRUE;
soc_log_dbg("register callback succeed\n");
} else {
instance_exist = rm_mpi_find_instance_by_client(client, &instance);
if (instance_exist != TD_TRUE) {
ret = rm_mpi_get_free_instance(&instance);
if (ret == TD_FAILURE) {
soc_err_print_call_fun_err(rm_mpi_get_free_instance, ret);
rm_mpi_task_resume();
return SOC_ERR_RM_NOT_FREE_CB_INST;
}
}
soc_log_dbg("repeat register succeed.\n");
}
soc_log_notice("g_rm_ctx.pid = %u, event = %d \n", g_rm_ctx.pid, event);
ext_rm_list_lock();
g_rm_cb_instance[instance].pfn_rm_event_callback = fn;
g_rm_cb_instance[instance].client = (td_void *)client;
g_rm_cb_instance[instance].event = event;
g_rm_cb_instance[instance].pid = (td_u32)getpid();
ext_rm_list_unlock();
return ret;
}
static td_s32 rm_mpi_unregister_callback_pre_check(const td_void *client, ext_rm_event_cb_fn fn)
{
if (client == NULL) {
soc_log_err("ext_mpi_rm_un_register_callback client_p is null pointer.\n");
return SOC_ERR_RM_NULL_PTR;
}
if (fn == NULL) {
soc_log_err("ext_mpi_rm_un_register_callback fn is null pointer.\n");
return SOC_ERR_RM_NULL_PTR;
}
return TD_SUCCESS;
}
static td_void rm_mpi_reset_callback_instance(td_u32 cb_index)
{
g_rm_cb_instance[cb_index].event = 0;
g_rm_cb_instance[cb_index].pid = 0;
g_rm_cb_instance[cb_index].client = TD_NULL;
g_rm_cb_instance[cb_index].pfn_rm_event_callback = TD_NULL;
return;
}
/* Public API */
td_s32 ext_mpi_rm_init(td_void)
{
td_char path[PATH_MAX] = {0};
soc_info_func_enter();
ext_rm_lock();
if (g_rm_dev_fd > 0) {
g_rm_dev_init_cnt++;
soc_log_warn("RM be inited, query path be exist.\n");
soc_info_print_u32(g_rm_dev_init_cnt);
soc_info_func_exit();
ext_rm_unlock();
return TD_SUCCESS;
}
if (realpath(g_rm_dev_name, path) == TD_NULL) {
soc_log_err("get realpath error!\n");
ext_rm_unlock();
return TD_FAILURE;
}
g_rm_dev_fd = open(path, O_RDWR | O_NONBLOCK, 0);
if (g_rm_dev_fd < 0) {
soc_log_err("open RM err.\n");
ext_rm_unlock();
return SOC_ERR_RM_DEV_OPEN_ERR;
}
rm_mpi_init_ctx();
rm_mpi_init_instance();
g_rm_dev_init_cnt++;
soc_info_print_u32(g_rm_dev_init_cnt);
ext_rm_unlock();
soc_info_func_exit();
return TD_SUCCESS;
}
td_s32 ext_mpi_rm_deinit(td_void)
{
td_s32 ret;
soc_info_func_enter();
if (g_rm_ctx.call_backing == TD_TRUE) {
soc_log_warn("the callback function is not finished\n");
}
ext_rm_lock();
rm_mpi_task_suspend();
if (g_rm_dev_init_cnt > 1) {
soc_log_warn("RM reference count not zero.\n");
soc_info_func_exit();
g_rm_dev_init_cnt--;
soc_info_print_u32(g_rm_dev_init_cnt);
ext_rm_unlock();
return TD_SUCCESS;
}
if ((g_rm_dev_fd < 0) || (g_rm_dev_init_cnt == 0)) {
ext_rm_unlock();
soc_log_warn("RM be de_inited.\n");
soc_info_func_exit();
return TD_SUCCESS;
}
if (g_rm_ctx.query_path_exist == TD_TRUE) {
soc_log_warn("query path is exist,destroy it.\n");
ret = rm_mpi_destroy_query_path();
if (ret != TD_SUCCESS) {
ext_rm_unlock();
soc_err_print_call_fun_err(rm_mpi_destroy_query_path, ret);
return TD_FAILURE;
}
} else {
rm_mpi_init_instance();
}
close(g_rm_dev_fd);
g_rm_dev_fd = -1;
g_rm_dev_init_cnt--;
soc_info_print_u32(g_rm_dev_init_cnt);
rm_mpi_init_ctx();
ext_rm_unlock();
soc_info_func_exit();
return TD_SUCCESS;
}
td_s32 ext_mpi_rm_register_callback(const td_void *client, ext_rm_event_cb_fn fn, td_u32 event_mask)
{
td_s32 ret;
soc_info_func_enter();
if (client == NULL) {
soc_log_err("ext_mpi_rm_register_callback client_p is null pointer.\n");
return SOC_ERR_RM_NULL_PTR;
}
if (fn == NULL) {
soc_log_err("ext_mpi_rm_register_callback fn is null pointer.\n");
return SOC_ERR_RM_NULL_PTR;
}
if ((event_mask &
(td_u32)(EXT_RM_EVENT_WIN_LACK | EXT_RM_EVENT_WIN_CREATED | EXT_RM_EVENT_WIN_DESTROYED)) == 0) {
soc_log_err("event:%d is invalid.\n", event_mask);
return SOC_ERR_RM_INVALID_PARA;
}
if (g_rm_ctx.call_backing == TD_TRUE) {
soc_log_warn("the callback function is not finished\n");
}
ext_rm_lock();
rm_mpi_task_suspend();
if (g_rm_dev_fd < 0) {
rm_mpi_task_resume();
ext_rm_unlock();
soc_log_err("please init firstly.\n");
return SOC_ERR_RM_DEV_NOT_INIT;
}
ret = rm_mpi_reg_callback(client, fn, event_mask);
if (ret != TD_SUCCESS) {
ext_rm_unlock();
soc_err_print_call_fun_err(rm_mpi_reg_callback, ret);
return ret;
}
rm_mpi_task_resume();
ext_rm_unlock();
soc_info_func_exit();
return TD_SUCCESS;
}
td_s32 ext_mpi_rm_unregister_callback(const td_void *client, ext_rm_event_cb_fn fn)
{
td_s32 ret;
td_u32 cb_index;
td_bool need_destroy_path;
td_bool instance_exist;
soc_info_func_enter();
ret = rm_mpi_unregister_callback_pre_check(client, fn);
if (ret != TD_SUCCESS) {
return ret;
}
ext_rm_lock();
rm_mpi_task_suspend();
if (g_rm_dev_fd < 0) {
rm_mpi_task_resume();
ext_rm_unlock();
soc_log_err("please init firstly.\n");
return SOC_ERR_RM_DEV_NO_INIT;
}
instance_exist = rm_mpi_find_instance_by_client(client, &cb_index);
if (instance_exist == TD_FALSE) {
soc_log_err("find instance by client_p error!\n");
rm_mpi_task_resume();
ext_rm_unlock();
return SOC_ERR_RM_INVALID_PARA;
}
soc_log_info("try to un_register callback.\n");
soc_dbg_print_u32(g_rm_ctx.pid);
soc_dbg_print_void(client);
ext_rm_list_lock();
rm_mpi_reset_callback_instance(cb_index);
ext_rm_list_unlock();
need_destroy_path = rm_mpi_need_destroy_path();
if (need_destroy_path == TD_TRUE) {
ret = rm_mpi_destroy_query_path();
if (ret != TD_SUCCESS) {
rm_mpi_task_resume();
ext_rm_unlock();
soc_err_print_call_fun_err(rm_mpi_destroy_query_path, ret);
return SOC_ERR_RM_DESTROY_ERR;
}
}
rm_mpi_task_resume();
ext_rm_unlock();
soc_log_info("un_register callback OK.\n");
soc_info_func_exit();
return TD_SUCCESS;
}
td_s32 ext_mpi_rm_acquire_window_handle(td_void)
{
td_s32 ret;
rm_win_info rm_win_info = {TD_INVALID_HANDLE, 0};
soc_info_func_enter();
ext_rm_lock();
ret = rm_mpi_check_and_open();
if (ret != TD_SUCCESS) {
ext_rm_unlock();
soc_log_err("this instance is not init,please init firstly.\n");
return SOC_ERR_RM_DEV_NOT_INIT;
}
ext_rm_unlock();
rm_win_info.win_handle = TD_INVALID_HANDLE;
rm_win_info.pid = (td_u32)getpid();
soc_log_notice("try to acquire window resource, current acquire window PID:%u\n", rm_win_info.pid);
ret = ioctl(g_rm_dev_fd, CMD_RM_ACQUIREWIN, &rm_win_info);
if (ret != TD_SUCCESS) {
soc_log_err("call RM ioctl CMD:CMD_RM_ACQUIREWIN failed, ret: [0x%08X].\n", ret);
return ret;
}
soc_log_notice("current process check_open:%s\n", g_rm_check_open == TD_TRUE ? "true" : "false");
soc_info_func_exit();
return TD_SUCCESS;
}