* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as 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.
*/
#include "ka_dfx_pub.h"
#include "ka_system_pub.h"
#include "ka_list_pub.h"
#include "ka_memory_pub.h"
#include "ka_errno_pub.h"
#include "ka_task_pub.h"
#include "ka_base_pub.h"
#include "ka_fs_pub.h"
#include "ka_kernel_def_pub.h"
#include "ka_common_pub.h"
#include "dms_kernel_version_adapt.h"
#include "pbl_mem_alloc_interface.h"
#include "fms_define.h"
#include "fms_kernel_interface.h"
#include "dms_sensor_discrete.h"
#include "dms_sensor_general.h"
#include "dms_sensor_statis.h"
#include "dms_sensor_type.h"
#include "dms_sensor_notify.h"
#include "dms_event_converge.h"
#include "kernel_version_adapt.h"
#include "dms_sensor.h"
#define print_sysfs (void)ka_dfx_printk
#define CLOCK_ID_STRLEN 9
#define CMDLINE_BUFFER_SIZE 1000
#define CLOCK_VIRTUAL 100
#define CLOCK_REAL 0
#define DECIMAL 10
#define CMDLINE_FILE_PATH "/proc/cmdline"
static int g_dms_mgnt_clock_id = CLOCK_VIRTUAL;
#define FAULT_SENSOR_OFFSET (9U)
#define FAULT_EVENT_CODE_HOST (0x1U << 30)
#define FAULT_EVENT_CODE_DEVICE (0x2U << 30)
#define FAULT_EVENT_NODETYPE_TO_CODE(nodetype) (((nodetype) & 0x7ff) << 17)
struct dms_eventinfo_from_config g_event_configs = {
.event_configs = {{0}},
.config_cnt = 0
};
KA_EXPORT_SYMBOL(g_event_configs);
static ka_atomic_t g_dms_sensor_alarm_serial = KA_BASE_ATOMIC_INIT(0);
DMS_EVENT_LIST_ITEM g_event_list_cb[DMS_MAX_EVENT_NUM];
ka_mutex_t g_sensor_event_list_mutex;
static void sensor_init_event_list_cb(void)
{
(void)memset_s(&g_event_list_cb, sizeof(DMS_EVENT_LIST_ITEM) * DMS_MAX_EVENT_NUM,\
0, sizeof(DMS_EVENT_LIST_ITEM) * DMS_MAX_EVENT_NUM);
ka_task_mutex_init(&g_sensor_event_list_mutex);
}
static void sensor_exit_event_list_cb(void)
{
ka_task_mutex_destroy(&g_sensor_event_list_mutex);
}
unsigned long dms_get_time_change(ka_ktime_t start, ka_ktime_t end)
{
unsigned long time_use;
time_use = (unsigned long)(ka_system_ktime_to_ns(end) - ka_system_ktime_to_ns(start)) / KA_NSEC_PER_USEC;
return time_use;
}
unsigned long dms_get_time_change_ms(ka_ktime_t start, ka_ktime_t end)
{
unsigned long time_use;
time_use = (unsigned long)(ka_system_ktime_to_ns(end) - ka_system_ktime_to_ns(start)) / KA_NSEC_PER_MSEC;
return time_use;
}
static void dms_start_record_sensor_scan_time(struct dms_dev_sensor_cb *pdev_sen_cb)
{
pdev_sen_cb->scan_time_recorder.sensor_start_time = ka_system_ktime_get();
}
static void dms_stop_record_sensor_scan_time(struct dms_dev_sensor_cb *pdev_sen_cb,
struct dms_sensor_object_cb *psensor_obj_cb)
{
ka_ktime_t current_time;
unsigned long all_time_use;
int ret;
struct dms_sensor_scan_time_recorder *ptime_recorder;
ptime_recorder = &pdev_sen_cb->scan_time_recorder;
current_time = ka_system_ktime_get();
all_time_use = dms_get_time_change(ptime_recorder->sensor_start_time, current_time);
if (all_time_use > DMS_SENSOR_SCAN_OUT_TIME) {
if (ptime_recorder->sensor_record_index >= DMS_MAX_TIME_RECORD_COUNT) {
ptime_recorder->sensor_record_index = 0;
}
ptime_recorder->sensor_scan_time_record[ptime_recorder->sensor_record_index].exec_time = all_time_use;
ret = strcpy_s(ptime_recorder->sensor_scan_time_record[ptime_recorder->sensor_record_index].sensor_name,
DMS_SENSOR_DESCRIPT_LENGTH, psensor_obj_cb->sensor_object_cfg.sensor_name);
if (ret != 0) {
dms_err("strcpy_s error. (ret=%d)\n", ret);
}
if (all_time_use > ptime_recorder->max_sensor_scan_record.exec_time) {
ptime_recorder->max_sensor_scan_record.exec_time = all_time_use;
ret = strcpy_s(ptime_recorder->max_sensor_scan_record.sensor_name, DMS_SENSOR_DESCRIPT_LENGTH,
psensor_obj_cb->sensor_object_cfg.sensor_name);
if (ret != 0) {
dms_err("strcpy_s error. (ret=%d)\n", ret);
}
}
ptime_recorder->sensor_out_time_count++;
ptime_recorder->sensor_record_index++;
}
}
static void dms_start_record_dev_scan_time(struct dms_dev_sensor_cb *pdev_sen_cb)
{
pdev_sen_cb->scan_time_recorder.dev_start_time = ka_system_ktime_get();
}
static void dms_stop_record_dev_scan_time(struct dms_dev_sensor_cb *pdev_sen_cb)
{
ka_ktime_t current_time;
unsigned long all_time_use;
struct dms_sensor_scan_time_recorder *ptime_recorder;
ptime_recorder = &pdev_sen_cb->scan_time_recorder;
current_time = ka_system_ktime_get();
all_time_use = dms_get_time_change(ptime_recorder->dev_start_time, current_time);
if (all_time_use > DMS_DEV_SENSOR_SCAN_OUT_TIME) {
if (ptime_recorder->dev_record_index >= DMS_MAX_TIME_RECORD_COUNT) {
ptime_recorder->dev_record_index = 0;
}
ptime_recorder->dev_scan_time_record[ptime_recorder->dev_record_index] = all_time_use;
if (all_time_use > ptime_recorder->max_dev_scan_record) {
ptime_recorder->max_dev_scan_record = all_time_use;
}
ptime_recorder->dev_out_time_count++;
ptime_recorder->dev_record_index++;
}
}
static void dms_init_sensor_time_recorder(struct dms_dev_sensor_cb *pdev_sen_cb)
{
struct dms_sensor_scan_time_recorder *ptime_recorder;
ptime_recorder = &pdev_sen_cb->scan_time_recorder;
(void)memset_s((void *)ptime_recorder, sizeof(struct dms_sensor_scan_time_recorder), 0,
sizeof(struct dms_sensor_scan_time_recorder));
ptime_recorder->record_scan_time_flag = 1;
ptime_recorder->start_sensor_scan_record = dms_start_record_sensor_scan_time;
ptime_recorder->stop_sensor_scan_record = dms_stop_record_sensor_scan_time;
ptime_recorder->start_dev_scan_record = dms_start_record_dev_scan_time;
ptime_recorder->stop_dev_scan_record = dms_stop_record_dev_scan_time;
}
static struct dms_dev_sensor_cb *dms_get_sensor_cb(struct dms_node *owner_node)
{
struct dms_dev_ctrl_block *temp_dev_cb = NULL;
temp_dev_cb = dms_get_dev_cb(owner_node->owner_devid);
if (temp_dev_cb == NULL) {
return NULL;
}
return (&temp_dev_cb->dev_sensor_cb);
}
STATIC int dms_get_node_sensor_cb_by_nodeid(struct dms_dev_sensor_cb *dev_sensor_cb, unsigned int node_type,
unsigned int node_id, struct dms_node_sensor_cb **node_sensor_cb)
{
int result;
struct dms_node_sensor_cb *pnode_ctrl = NULL;
struct dms_node_sensor_cb *tmp_ctl = NULL;
result = dms_check_node_type(node_type);
if (result != DRV_ERROR_NONE) {
dms_err("Invalid node type. (node_type=0x%x, node_id=%u)\n", node_type, node_id);
return DRV_ERROR_PARA_ERROR;
}
*node_sensor_cb = NULL;
ka_list_for_each_entry_safe(pnode_ctrl, tmp_ctl, &(dev_sensor_cb->dms_node_sensor_cb_list), list)
{
if ((pnode_ctrl->node_id == node_id) && (pnode_ctrl->node_type == node_type)) {
*node_sensor_cb = pnode_ctrl;
break;
}
}
return DRV_ERROR_NONE;
}
static struct dms_node_sensor_cb *dms_get_or_create_node_sensor_cb(struct dms_dev_sensor_cb *dev_sensor_cb,
struct dms_node *owner_node, int env_type)
{
int result;
int pid;
struct dms_node_sensor_cb *node_sensor_cb = NULL;
result = dms_get_node_sensor_cb_by_nodeid(dev_sensor_cb, owner_node->node_type,
owner_node->node_id, &node_sensor_cb);
if (result != DRV_ERROR_NONE) {
dms_err("get node sensor cb failed!\n");
return NULL;
}
pid = (env_type == DMS_SENSOR_ENV_USER_SPACE) ? (ka_task_get_current_tgid()) : (-1);
if (node_sensor_cb != NULL) {
if (node_sensor_cb->env_type != env_type) {
* node */
dms_err("env is not match\n");
return NULL;
}
if (node_sensor_cb->pid != pid) {
* process */
dms_err("pid is not match. (node_type=0x%x, node_id=%d, owner_pid=%d, current_pid=%d\n",
owner_node->node_type, owner_node->node_id, node_sensor_cb->pid, pid);
return NULL;
}
return node_sensor_cb;
}
node_sensor_cb = (struct dms_node_sensor_cb *)dbl_kzalloc(sizeof(struct dms_node_sensor_cb),
KA_GFP_KERNEL | __KA_GFP_ACCOUNT);
if (node_sensor_cb == NULL) {
dms_err("Malloc memory failed!\n");
return NULL;
}
(void)memset_s((void *)node_sensor_cb, sizeof(struct dms_node_sensor_cb), 0, sizeof(struct dms_node_sensor_cb));
node_sensor_cb->env_type = env_type;
node_sensor_cb->pid = pid;
node_sensor_cb->sensor_object_num = 0;
node_sensor_cb->node_id = owner_node->node_id;
node_sensor_cb->node_type = owner_node->node_type;
node_sensor_cb->owner_node = owner_node;
node_sensor_cb->version = 0;
node_sensor_cb->health = 0;
KA_INIT_LIST_HEAD(&node_sensor_cb->sensor_object_table);
ka_list_add(&node_sensor_cb->list, &dev_sensor_cb->dms_node_sensor_cb_list);
dev_sensor_cb->node_cb_num++;
return node_sensor_cb;
}
static unsigned int dms_sensor_class_init(unsigned short sensor_class, struct dms_sensor_object_cb *psensor_obj)
{
if (sensor_class == DMS_STATICSTIC_SENSOR_CLASS) {
return dms_sensor_class_init_statis(psensor_obj);
} else if (sensor_class == DMS_GENERAL_THRESHOLD_SENSOR_CLASS) {
return dms_sensor_class_init_general(psensor_obj);
} else if (sensor_class == DMS_DISCRETE_SENSOR_CLASS) {
return dms_sensor_class_init_discrete(psensor_obj);
} else {
return DRV_ERROR_PARA_ERROR;
}
}
STATIC unsigned int dms_add_sensor_object_table(struct dms_node_sensor_cb *node_sensor_cb,
struct dms_sensor_object_cfg *psensor_cfg)
{
struct dms_sensor_object_cb *temp_sensor = NULL;
if (node_sensor_cb->sensor_object_num >= DMS_MAX_NODE_SENSOR_COUNT) {
dms_err("Sensor object too many. (object_num=%u, max_num=%u)\n",
node_sensor_cb->sensor_object_num, DMS_MAX_NODE_SENSOR_COUNT);
return DRV_ERROR_NO_RESOURCES;
}
temp_sensor = (struct dms_sensor_object_cb *)dbl_kzalloc(sizeof(struct dms_sensor_object_cb),
KA_GFP_KERNEL | __KA_GFP_ACCOUNT);
if (temp_sensor == NULL) {
dms_err("Malloc memory failed!\n");
return DRV_ERROR_MEMORY_OPT_FAIL;
}
(void)memset_s((void *)temp_sensor, sizeof(struct dms_sensor_object_cb), 0, sizeof(struct dms_sensor_object_cb));
temp_sensor->sensor_object_cfg = *psensor_cfg;
temp_sensor->orig_obj_cfg = *psensor_cfg;
temp_sensor->object_index = node_sensor_cb->sensor_object_num + 1;
temp_sensor->sensor_num = (psensor_cfg->sensor_type << DMS_MASK_16_BIT) + temp_sensor->object_index;
temp_sensor->owner_node_id = node_sensor_cb->node_id;
temp_sensor->owner_node_type = node_sensor_cb->node_type;
temp_sensor->p_owner_cb = node_sensor_cb;
temp_sensor->event_status = DMS_SENSOR_STATUS_GOOD;
temp_sensor->fault_status = DMS_SENSOR_STATUS_GOOD;
temp_sensor->current_value = 0;
temp_sensor->remain_time = psensor_cfg->scan_interval;
temp_sensor->p_event_list = NULL;
(void)dms_sensor_class_init(psensor_cfg->sensor_class, temp_sensor);
ka_list_add(&temp_sensor->list, &node_sensor_cb->sensor_object_table);
node_sensor_cb->sensor_object_num++;
return DRV_ERROR_NONE;
}
static unsigned int dms_sensor_class_check(unsigned short sensor_class, struct dms_sensor_object_cfg *psensor_obj_cfg)
{
if (sensor_class == DMS_STATICSTIC_SENSOR_CLASS) {
return dms_sensor_class_check_statis(psensor_obj_cfg);
} else if (sensor_class == DMS_GENERAL_THRESHOLD_SENSOR_CLASS) {
return dms_sensor_class_check_general(psensor_obj_cfg);
} else if (sensor_class == DMS_DISCRETE_SENSOR_CLASS) {
return dms_sensor_class_check_discrete(psensor_obj_cfg);
} else {
return DRV_ERROR_PARA_ERROR;
}
}
STATIC int dms_check_sensor_type(unsigned char sensor_type)
{
int i, count;
struct tag_dms_sensor_type *dms_sensor_type;
if (sensor_type == DMS_SENSOR_RESERVED_FOR_PRODUCT) {
dms_err("sensor type is reserved. (sensor_type=0x%x)\n", sensor_type);
return DRV_ERROR_PARA_ERROR;
}
count = dms_get_sensor_type_count();
dms_sensor_type = dms_get_sensor_type();
for (i = 0; i < count; i++) {
if (dms_sensor_type[i].sensor_type == sensor_type) {
return DRV_ERROR_NONE;
}
}
dms_err("sensor type error. (sensor_type=0x%x)\n", sensor_type);
return DRV_ERROR_PARA_ERROR;
}
bool dms_sensor_check_mask_enable(unsigned int mask, unsigned int offset)
{
if ((mask & (1 << offset)) != 0) {
return true;
} else {
return false;
}
}
static unsigned int dms_sensor_cfg_check(struct dms_sensor_object_cfg *psensor_obj_cfg)
{
unsigned int result;
unsigned short sensor_class;
if ((psensor_obj_cfg->enable_flag != DMS_SENSOR_ENABLE_FALG) &&
(psensor_obj_cfg->enable_flag != DMS_SENSOR_DISABLE_FALG)) {
dms_err("Invalid parameter ulEnable. (enable_flag=0x%x)\n", psensor_obj_cfg->enable_flag);
return DRV_ERROR_PARA_ERROR;
}
if ((psensor_obj_cfg->scan_interval < DMS_SENSOR_CHECK_TIMER_LEN) &&
(psensor_obj_cfg->scan_module == DMS_SERSOR_SCAN_PERIOD)) {
dms_err("Invalid parameter scan_interval. (scan_interval=%ums; scan_module=%u)\n",
psensor_obj_cfg->scan_interval, psensor_obj_cfg->scan_module);
return DRV_ERROR_PARA_ERROR;
}
sensor_class = psensor_obj_cfg->sensor_class;
if ((sensor_class != DMS_STATICSTIC_SENSOR_CLASS) && (sensor_class != DMS_GENERAL_THRESHOLD_SENSOR_CLASS) &&
(sensor_class != DMS_DISCRETE_SENSOR_CLASS) && (sensor_class != DMS_PER_SENSOR_CLASS)) {
dms_err("Sensor Table Check Failed(sensor_class=%u)\n", sensor_class);
return DRV_ERROR_PARA_ERROR;
}
if (dms_check_sensor_type(psensor_obj_cfg->sensor_type) != DRV_ERROR_NONE) {
dms_err("sensor type is not support\n");
return DRV_ERROR_PARA_ERROR;
}
if ((psensor_obj_cfg->proc_flag != DMS_SENSOR_PROC_ENABLE_FLAG) &&
(psensor_obj_cfg->proc_flag != DMS_SENSOR_PROC_DISABLE_FLAG)) {
dms_err("Invalid Sensor Table Process Flag. (proc_flag=0x%x)\n", psensor_obj_cfg->proc_flag);
return DRV_ERROR_PARA_ERROR;
}
if (psensor_obj_cfg->pf_scan_func == NULL) {
dms_err("Invalid Sensor Table Scan Function - NULL Pointer\n");
return DRV_ERROR_PARA_ERROR;
}
result = dms_sensor_class_check(psensor_obj_cfg->sensor_class, psensor_obj_cfg);
if (result != DRV_ERROR_NONE) {
dms_err("Sensor Table Check Failed!\n");
return DRV_ERROR_PARA_ERROR;
}
return DRV_ERROR_NONE;
}
static bool dms_compare_sensor_object(struct dms_sensor_object_cfg *psensor_obj_cfg1,
struct dms_sensor_object_cfg *psensor_obj_cfg2)
{
if ((psensor_obj_cfg1->sensor_type == psensor_obj_cfg2->sensor_type) &&
(psensor_obj_cfg1->pf_scan_func == psensor_obj_cfg2->pf_scan_func) &&
(ka_base_strcmp(psensor_obj_cfg1->sensor_name, psensor_obj_cfg2->sensor_name) == 0)) {
return true;
} else {
return false;
}
}
static unsigned int dms_is_sensor_object_repeat(struct dms_dev_sensor_cb *pdev_sen_cb, int node_type, int nodeid,
struct dms_sensor_object_cfg *psensor_obj_cfg, unsigned int *repeat)
{
struct dms_sensor_object_cb *sensor_type_item = NULL;
struct dms_sensor_object_cb *tmp_sensor_ctl = NULL;
struct dms_node_sensor_cb *pnode_sen_cb = NULL;
int rec;
*repeat = DMS_SENSOR_TABLE_NOT_REPEAT;
rec = dms_get_node_sensor_cb_by_nodeid(pdev_sen_cb, node_type, nodeid, &pnode_sen_cb);
if (rec != DRV_ERROR_NONE) {
dms_err("get node sensor cb fail. (nodeid=%d)\n", nodeid);
return rec;
}
* event that needs to be reported, then report the event */
if (pnode_sen_cb != NULL) {
ka_list_for_each_entry_safe(sensor_type_item, tmp_sensor_ctl, &(pnode_sen_cb->sensor_object_table), list)
{
if (dms_compare_sensor_object(&sensor_type_item->sensor_object_cfg, psensor_obj_cfg) == true) {
*repeat = DMS_SENSOR_TABLE_REPEAT;
dms_err("add repeat sensor, (new sensor type:0x%x; name:%.*s;"
"old sensor type:0x%x;name:%.*s\n", psensor_obj_cfg->sensor_type,
DMS_SENSOR_DESCRIPT_LENGTH, psensor_obj_cfg->sensor_name,
sensor_type_item->sensor_object_cfg.sensor_type,
DMS_SENSOR_DESCRIPT_LENGTH, sensor_type_item->sensor_object_cfg.sensor_name);
return DRV_ERROR_NONE;
}
}
}
return DRV_ERROR_NONE;
}
static unsigned int dms_sensor_add_obj_node(struct dms_node *owner_node, struct dms_dev_sensor_cb *dev_sensor_cb,
struct dms_sensor_object_cfg *psensor_obj_cfg, int env_type)
{
unsigned int result;
struct dms_node_sensor_cb *node_sensor_cb = NULL;
unsigned int repeat = DMS_SENSOR_TABLE_NOT_REPEAT;
result = dms_is_sensor_object_repeat(dev_sensor_cb, owner_node->node_type,
owner_node->node_id, psensor_obj_cfg, &repeat);
if (result != DRV_ERROR_NONE) {
dms_err("Judge whether Sensor Table is repeated failed. (nodeid=%d)\n", owner_node->node_id);
return DRV_ERROR_PARA_ERROR;
}
if (repeat == DMS_SENSOR_TABLE_REPEAT) {
dms_err("Repeated sensor object. (nodeid=%d)\n", owner_node->node_id);
return DRV_ERROR_PARA_ERROR;
}
node_sensor_cb = dms_get_or_create_node_sensor_cb(dev_sensor_cb, owner_node, env_type);
if (node_sensor_cb == NULL) {
dms_err("add or get sensor cb fail. (node_type=0x%x, node_id=%d)\n",
owner_node->node_type, owner_node->node_id);
return DRV_ERROR_PARA_ERROR;
}
result = dms_add_sensor_object_table(node_sensor_cb, psensor_obj_cfg);
if (result != DRV_ERROR_NONE) {
dms_err("add sensor type fail. (node_type=0x%x, node_id=%d)\n", owner_node->node_type, owner_node->node_id);
if (node_sensor_cb->sensor_object_num == 0) {
ka_list_del(&node_sensor_cb->list);
dbl_kfree(node_sensor_cb);
node_sensor_cb = NULL;
dev_sensor_cb->node_cb_num--;
}
return DRV_ERROR_PARA_ERROR;
}
return DRV_ERROR_NONE;
}
static unsigned int dms_sensor_register_all(struct dms_node *owner_node, struct dms_sensor_object_cfg *psensor_obj_cfg,
int env_type)
{
unsigned int result;
struct dms_dev_sensor_cb *dev_sensor_cb = NULL;
if ((psensor_obj_cfg == NULL) || (owner_node == NULL)) {
dms_err("Invalid parameter\n");
return DRV_ERROR_PARA_ERROR;
}
if ((env_type != DMS_SENSOR_ENV_KERNEL_SPACE) && (env_type != DMS_SENSOR_ENV_USER_SPACE)) {
dms_err("env Invalid parameter\n");
return DRV_ERROR_PARA_ERROR;
}
result = dms_sensor_cfg_check(psensor_obj_cfg);
if (result != DRV_ERROR_NONE) {
dms_err("Invalid sensor format. (node_id=%d)\n", owner_node->node_id);
return DRV_ERROR_PARA_ERROR;
}
dev_sensor_cb = dms_get_sensor_cb(owner_node);
if (dev_sensor_cb == NULL) {
dms_err("dms get sensor cb fail. (nodeid=%d)\n", owner_node->node_id);
return DRV_ERROR_PARA_ERROR;
}
ka_task_mutex_lock(&dev_sensor_cb->dms_sensor_mutex);
result = dms_sensor_add_obj_node(owner_node, dev_sensor_cb, psensor_obj_cfg, env_type);
if (result != DRV_ERROR_NONE) {
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
dms_err("add sensor type fail. (nodeid=%d)\n", owner_node->node_id);
return DRV_ERROR_PARA_ERROR;
}
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
return DRV_ERROR_NONE;
}
unsigned int dms_fill_event_data(const struct dms_sensor_object_cb *psensor_obj_cb,
DMS_EVENT_LIST_ITEM *event_item, unsigned char assertion, struct dms_event_obj *p_event_obj)
{
struct dms_node *owner_node = NULL;
int ret;
unsigned int severity = DMS_EVENT_OK;
(void)memset_s((void *)p_event_obj, sizeof(struct dms_event_obj), 0, sizeof(struct dms_event_obj));
ret = dms_get_event_severity(psensor_obj_cb->owner_node_type, psensor_obj_cb->sensor_object_cfg.sensor_type,
event_item->event_data, &severity);
if (ret != 0) {
dms_warn("get event severity. (ret=%d)\n", ret);
}
if ((psensor_obj_cb->p_owner_cb == NULL) || (psensor_obj_cb->p_owner_cb->owner_node == NULL)) {
return DRV_ERROR_INVALID_HANDLE;
}
owner_node = psensor_obj_cb->p_owner_cb->owner_node;
p_event_obj->pid = psensor_obj_cb->p_owner_cb->pid;
p_event_obj->event_type = DMS_ET_SENSOR;
p_event_obj->deviceid = psensor_obj_cb->p_owner_cb->owner_node->owner_devid;
if (owner_node->owner_device == NULL) {
p_event_obj->node_type = psensor_obj_cb->owner_node_type;
p_event_obj->node_id = psensor_obj_cb->owner_node_id;
p_event_obj->sub_node_type = 0;
p_event_obj->sub_node_id = 0;
} else {
p_event_obj->node_type = owner_node->owner_device->node_type;
p_event_obj->node_id = owner_node->owner_device->node_id;
p_event_obj->sub_node_type = psensor_obj_cb->owner_node_type;
* Need to use the node ID in the current owner_device, that is inner_node_id.
* For example, if there are 10 AICs, each AIC has an SMMU. The @node_id is
* globally unique for AIC_SMMU. However, for a single AIC, sub_node_id is the
* ID of the current AIC and the value is 0. */
p_event_obj->sub_node_id = owner_node->inner_node_id;
}
p_event_obj->severity = severity;
p_event_obj->event.sensor_event.sensor_num = psensor_obj_cb->sensor_num;
p_event_obj->event.sensor_event.sensor_type = psensor_obj_cb->sensor_object_cfg.sensor_type;
p_event_obj->event.sensor_event.assertion = assertion;
p_event_obj->event.sensor_event.event_state = event_item->event_data;
p_event_obj->time_stamp = event_item->timestamp;
p_event_obj->alarm_serial_num = event_item->alarm_serial_num;
ka_dfx_pr_debug("[dms_module][dms_fill_event_data] node type(0x%x) event type(0x%x)"
"serial num(%u) sensor name:%.*s\n", psensor_obj_cb->owner_node_type, event_item->event_data,
event_item->alarm_serial_num, DMS_SENSOR_DESCRIPT_LENGTH, event_item->sensor_name);
ret = strcpy_s(p_event_obj->event.sensor_event.sensor_name, DMS_SENSOR_DESCRIPT_LENGTH, event_item->sensor_name);
if (ret != 0) {
dms_err("Strcpy_s fail. (ret=%d)\n", ret);
return ret;
}
if ((event_item->para_len) > 0 && (event_item->event_paras != NULL)) {
p_event_obj->event.sensor_event.param_len = event_item->para_len;
ret = memcpy_s((void *)p_event_obj->event.sensor_event.param_buffer, DMS_MAX_EVENT_DATA_LENGTH,
(const void *)(event_item->event_paras), event_item->para_len);
if (ret != 0) {
dms_err("memcpy_s fail. (ret=%d)\n", ret);
return ret;
}
}
ret = memcpy_s(p_event_obj->event.sensor_event.event_info, sizeof(p_event_obj->event.sensor_event.event_info),
event_item->event_info, sizeof(event_item->event_info));
if (ret != 0) {
dms_err("memcpy_s fail. (ret=%d)\n", ret);
return ret;
}
return 0;
}
static unsigned int dms_sensor_report_event(struct dms_sensor_object_cb *psensor_obj_cb,
DMS_EVENT_LIST_ITEM *event_item, unsigned char assertion)
{
unsigned int result;
struct dms_event_obj sensor_event;
u32 event_code = 0;
(void)dms_fill_event_data(psensor_obj_cb, event_item, assertion, &sensor_event);
result = dms_event_report(&sensor_event);
if (result != DRV_ERROR_NONE) {
dms_err("Event Process Failed. (Node Type=%#x; Sensor num=%#x; name=\"%.*s\"; "
"Sensor Type=%#x; Sensor Object=%#x; assertion:%u, severity:%u)\n",
psensor_obj_cb->owner_node_type, psensor_obj_cb->sensor_num,
DMS_SENSOR_DESCRIPT_LENGTH, psensor_obj_cb->sensor_object_cfg.sensor_name,
psensor_obj_cb->sensor_object_cfg.sensor_type, psensor_obj_cb->object_index,
assertion, sensor_event.severity);
return DRV_ERROR_INNER_ERR;
}
result = dms_event_obj_to_error_code(sensor_event, &event_code);
if (result != 0) {
dms_err("Get event code failed. (result=%d)\n", result);
}
dms_event("Event Process Success. (Event id=0x%x; Node Type=%#x; Sensor num=%#x; name=\"%.*s\"; "
"Sensor Type=%#x; Sensor Object=%#x; assertion=%u; severity=%u; event_state=0x%x; private_data=0x%llx)\n",
event_code, psensor_obj_cb->owner_node_type, psensor_obj_cb->sensor_num,
DMS_SENSOR_DESCRIPT_LENGTH, psensor_obj_cb->sensor_object_cfg.sensor_name,
psensor_obj_cb->sensor_object_cfg.sensor_type, psensor_obj_cb->object_index,
assertion, sensor_event.severity, sensor_event.event.sensor_event.event_state,
psensor_obj_cb->sensor_object_cfg.private_data);
return DRV_ERROR_NONE;
}
static int dms_generated_alarm_serial(unsigned int *alarm_serial_no)
{
*alarm_serial_no = ka_base_atomic_inc_return(&g_dms_sensor_alarm_serial);
return DRV_ERROR_NONE;
}
int dms_mgnt_clockid_init(void)
{
int ret = 0;
char *buffer = NULL;
ka_file_t *fp = NULL;
char *ptr = NULL;
long read_num;
loff_t pos = 0;
buffer = (char *)dbl_kzalloc(CMDLINE_BUFFER_SIZE, KA_GFP_KERNEL | __KA_GFP_ACCOUNT);
if (buffer == NULL) {
dms_err("Failed to malloc for cmdline.\n");
return -ENOMEM;
}
fp = ka_fs_filp_open(CMDLINE_FILE_PATH, KA_O_RDONLY, 0);
if (KA_IS_ERR_OR_NULL(fp)) {
dms_err("Open file failed. (file=%s; errno=%ld)\n", CMDLINE_FILE_PATH, KA_PTR_ERR(fp));
ret = -EINVAL;
goto buff_free_exit;
}
read_num = ka_fs_kernel_read(fp, buffer, CMDLINE_BUFFER_SIZE - 1, &pos);
if ((read_num <= 0) || (read_num >= CMDLINE_BUFFER_SIZE)) {
dms_err("Read len error. (read_num=%ld; valid_range=[%d, %d])\n", read_num, 0, CMDLINE_BUFFER_SIZE - 1);
ret = -EINVAL;
goto file_close_exit;
}
buffer[read_num] = '\0';
ptr = ka_base_strstr(buffer, "dpclk=100");
if ((ptr != NULL) && ((*(ptr + CLOCK_ID_STRLEN) == '\0') || (*(ptr + CLOCK_ID_STRLEN) == ' '))) {
g_dms_mgnt_clock_id = CLOCK_REAL;
}
dms_info("Parse clock config. (clock_id=%d)\n", g_dms_mgnt_clock_id);
file_close_exit:
(void)ka_fs_filp_close(fp, NULL);
fp = NULL;
buff_free_exit:
dbl_kfree(buffer);
buffer = NULL;
return ret;
}
static int dms_sensor_get_timestamp(unsigned long long *timestamp)
{
#ifdef CFG_FEATURE_CLOCKID_CONFIG
ka_timespec64_t ts;
ka_timeval_t sys_time = {0};
if (timestamp == NULL) {
return DRV_ERROR_PARA_ERROR;
}
if (g_dms_mgnt_clock_id == CLOCK_VIRTUAL) {
ka_system_ktime_get_virtual_ts64(&ts);
} else {
ka_system_ktime_get_real_ts64(&ts);
}
sys_time.tv_sec = ts.tv_sec;
sys_time.tv_usec = ts.tv_nsec / KA_NSEC_PER_USEC;
*timestamp = (sys_time.tv_sec * KA_MSEC_PER_SEC) + (sys_time.tv_usec / KA_USEC_PER_MSEC);
#else
ka_ktime_t sys_time = 0;
if (timestamp == NULL) {
return DRV_ERROR_PARA_ERROR;
}
sys_time = ka_system_ktime_get();
*timestamp = (unsigned long long)ka_system_ktime_to_ns(sys_time) / KA_NSEC_PER_MSEC;
#endif
return DRV_ERROR_NONE;
}
static DMS_EVENT_LIST_ITEM *sensor_alloc_event_list_cb(void)
{
int i;
which will cause an alarm exception */
ka_task_mutex_lock(&g_sensor_event_list_mutex);
for (i = 0; i < DMS_MAX_EVENT_NUM; i++) {
if (!g_event_list_cb[i].in_use) {
g_event_list_cb[i].in_use = 1;
ka_task_mutex_unlock(&g_sensor_event_list_mutex);
return &g_event_list_cb[i];
}
}
ka_task_mutex_unlock(&g_sensor_event_list_mutex);
dms_err("No enough sensor event space! (event_num_limit=%d)\n", DMS_MAX_EVENT_NUM);
return 0;
}
static int sensor_delete_event_list(DMS_EVENT_LIST_ITEM *p_list)
{
if (p_list == NULL) {
return DRV_ERROR_NONE;
}
if (p_list->p_next != NULL) {
(void)sensor_delete_event_list(p_list->p_next);
}
ka_task_mutex_lock(&g_sensor_event_list_mutex);
p_list->in_use = 0;
p_list->p_next = NULL;
if (p_list->event_paras != NULL) {
dbl_kfree(p_list->event_paras);
p_list->event_paras = NULL;
p_list->para_len = 0;
}
ka_task_mutex_unlock(&g_sensor_event_list_mutex);
return DRV_ERROR_NONE;
}
STATIC int sensor_init_event_node(struct dms_sensor_event_data_item *pevent_data,
struct dms_sensor_object_cb *psensor_obj_cb, DMS_EVENT_LIST_ITEM *p_list)
{
int ret;
p_list->p_next = 0;
p_list->is_report = false;
p_list->event_data = (unsigned char)pevent_data->current_value;
p_list->sensor_num = psensor_obj_cb->sensor_num;
(void)dms_sensor_get_timestamp(&p_list->timestamp);
(void)dms_generated_alarm_serial(&p_list->alarm_serial_num);
p_list->continued_count = 1;
ret = strcpy_s(p_list->sensor_name, DMS_SENSOR_DESCRIPT_LENGTH, psensor_obj_cb->sensor_object_cfg.sensor_name);
if (ret != 0) {
dms_err("Copy sensor name failed. (ret=%d)\n", ret);
return ret;
}
ret = memcpy_s(p_list->event_info, sizeof(p_list->event_info),
pevent_data->event_info, sizeof(pevent_data->event_info));
if (ret != 0) {
dms_err("Copy event para failed. (ret=%d)\n", ret);
return ret;
}
if ((pevent_data->data_size > 0) && (pevent_data->data_size <= DMS_MAX_EVENT_DATA_LENGTH)) {
p_list->event_paras = (unsigned char *)dbl_kmalloc(pevent_data->data_size, KA_GFP_KERNEL | __KA_GFP_ACCOUNT);
if (p_list->event_paras == NULL) {
p_list->para_len = 0;
dms_err("sensor_add_event_to_list malloc failed. (sensor_num=%u; para_len=%u)\n",
psensor_obj_cb->sensor_num, pevent_data->data_size);
return -ENOMEM;
}
ret = memcpy_s((void *)p_list->event_paras, pevent_data->data_size,
pevent_data->event_data, pevent_data->data_size);
if (ret != 0) {
dms_err("Copy event para failed. (ret=%d)\n", ret);
dbl_kfree(p_list->event_paras);
p_list->event_paras = NULL;
p_list->para_len = 0;
return ret;
}
p_list->para_len = pevent_data->data_size;
}
return DRV_ERROR_NONE;
}
DMS_EVENT_LIST_ITEM *sensor_add_event_to_list(DMS_EVENT_LIST_ITEM **pp_event_list,
struct dms_sensor_event_data_item *pevent_data, struct dms_sensor_object_cb *psensor_obj_cb)
{
int ret;
DMS_EVENT_LIST_ITEM *p_list = NULL;
DMS_EVENT_LIST_ITEM *p_tail = NULL;
if (pp_event_list == NULL) {
dms_err("sensor_add_event_to_list para error\n");
return NULL;
}
if ((*pp_event_list) == NULL) {
p_list = sensor_alloc_event_list_cb();
if (p_list == NULL) {
return NULL;
}
*pp_event_list = p_list;
} else {
p_list = (*pp_event_list);
p_tail = p_list;
while (p_list != NULL) {
if ((p_list->event_data == (unsigned char)pevent_data->current_value) &&
(p_list->sensor_num == psensor_obj_cb->sensor_num)) {
return NULL;
}
p_tail = p_list;
p_list = p_list->p_next;
}
p_list = p_tail;
p_list->p_next = sensor_alloc_event_list_cb();
if (p_list->p_next == NULL) {
return NULL;
}
p_list = p_list->p_next;
}
ret = sensor_init_event_node(pevent_data, psensor_obj_cb, p_list);
if (ret != 0) {
dms_err("Sensor init event failed. (ret=%d)\n", ret);
return NULL;
}
return p_list;
}
static void sensor_proc_diff_list(struct dms_sensor_object_cb *p_sensor_obj_cb, DMS_EVENT_LIST_ITEM *p_new_list)
{
bool matched = false;
DMS_EVENT_LIST_ITEM *p_work_list = NULL;
DMS_EVENT_LIST_ITEM *p_old_list = NULL;
p_old_list = p_sensor_obj_cb->p_event_list;
p_work_list = p_new_list;
while (p_old_list != NULL) {
matched = false;
while (p_work_list != NULL) {
if (p_work_list->event_data == p_old_list->event_data) {
p_work_list->is_report = p_old_list->is_report;
p_work_list->timestamp = p_old_list->timestamp;
p_work_list->alarm_serial_num = p_old_list->alarm_serial_num;
matched = true;
p_work_list->continued_count = p_old_list->continued_count + 1;
break;
}
p_work_list = p_work_list->p_next;
}
* recovery event */
if ((false == matched) && dms_sensor_check_mask_enable(p_sensor_obj_cb->sensor_object_cfg.deassert_event_mask,
p_old_list->event_data)) {
if (p_old_list->is_report == true) {
(void)dms_sensor_report_event(p_sensor_obj_cb, p_old_list, DMS_EVENT_TYPE_RESUME);
}
}
p_old_list = p_old_list->p_next;
p_work_list = p_new_list;
}
}
static inline unsigned char sensor_event_state_convert_assertion(struct dms_sensor_object_cb *p_sensor_obj_cb,
unsigned char event_state)
{
struct dms_sensor_object_cfg *obj_cfg = &p_sensor_obj_cb->sensor_object_cfg;
if ((obj_cfg->assert_event_mask & (1 << event_state)) &&
!(obj_cfg->deassert_event_mask & (1 << event_state))) {
return DMS_EVENT_TYPE_ONE_TIME;
}
return DMS_EVENT_TYPE_OCCUR;
}
static bool sensor_need_report_event(struct dms_sensor_object_cb *p_sensor_obj_cb,
DMS_EVENT_LIST_ITEM *event, unsigned char assertion)
{
unsigned int debounce_time;
if (assertion == DMS_EVENT_TYPE_ONE_TIME) {
return true;
}
if (p_sensor_obj_cb->sensor_object_cfg.sensor_class != DMS_DISCRETE_SENSOR_CLASS) {
return !event->is_report;
}
debounce_time = p_sensor_obj_cb->sensor_object_cfg.sensor_class_cfg.discrete_sensor.debounce_time;
if ((assertion == DMS_EVENT_TYPE_OCCUR) && (event->is_report == false) &&
(event->continued_count >= debounce_time)) {
return true;
}
return false;
}
static void sensor_report_diff_event_list(struct dms_sensor_object_cb *p_sensor_obj_cb,
DMS_EVENT_LIST_ITEM *p_new_list)
{
unsigned char assertion;
unsigned int severity;
unsigned int fault_status = DMS_GEN_SEN_STATUS_GOOD;
sensor_proc_diff_list(p_sensor_obj_cb, p_new_list);
while (p_new_list != NULL) {
int ret;
severity = DMS_GEN_SEN_STATUS_GOOD;
ret = dms_get_event_severity(p_sensor_obj_cb->owner_node_type, p_sensor_obj_cb->sensor_object_cfg.sensor_type,
p_new_list->event_data, &severity);
if (ret != DRV_ERROR_NONE) {
dms_err("Get event severity fail. (sensor type=0x%x; offset=%u)\n",
p_sensor_obj_cb->sensor_object_cfg.sensor_type, p_new_list->event_data);
}
assertion = sensor_event_state_convert_assertion(p_sensor_obj_cb, p_new_list->event_data);
if (sensor_need_report_event(p_sensor_obj_cb, p_new_list, assertion)) {
(void)dms_sensor_report_event(p_sensor_obj_cb, p_new_list, assertion);
(void)dms_sensor_get_timestamp(&p_new_list->timestamp);
p_new_list->is_report = true;
p_sensor_obj_cb->event_status = severity;
}
if ((p_new_list->is_report) != 0) {
fault_status = fault_status > severity ? fault_status : severity;
}
p_new_list = p_new_list->p_next;
}
p_sensor_obj_cb->fault_status = fault_status;
}
int dms_add_one_sensor_event(struct dms_sensor_object_cb *psensor_obj_cb,
struct dms_sensor_event_data_item *pevent_data)
{
int rec;
DMS_EVENT_LIST_ITEM *p_event = NULL;
p_event = sensor_add_event_to_list(&psensor_obj_cb->p_event_list, pevent_data, psensor_obj_cb);
if (p_event == NULL) {
dms_warn("dms_add_one_sensor_event is not add event to list\n");
return DRV_ERROR_NONE;
}
rec = dms_sensor_report_event(psensor_obj_cb, p_event, DMS_EVENT_TYPE_OCCUR);
if (rec != DRV_ERROR_NONE) {
dms_err("add one sensor event report event fail\n");
return rec;
}
p_event->is_report = true;
psensor_obj_cb->event_status = psensor_obj_cb->fault_status;
return DRV_ERROR_NONE;
}
int dms_update_sensor_list(struct dms_sensor_object_cb *p_sensor_obj_cb, DMS_EVENT_LIST_ITEM *p_new_list)
{
DMS_EVENT_LIST_ITEM *p_old_event_list;
p_old_event_list = p_sensor_obj_cb->p_event_list;
sensor_report_diff_event_list(p_sensor_obj_cb, p_new_list);
p_sensor_obj_cb->p_event_list = p_new_list;
(void)sensor_delete_event_list(p_old_event_list);
return DRV_ERROR_NONE;
}
int dms_resume_all_sensor_event(struct dms_sensor_object_cb *psensor_obj_cb)
{
int result;
DMS_EVENT_LIST_ITEM *p_empty_list = NULL;
sensor_report_diff_event_list(psensor_obj_cb, p_empty_list);
result = sensor_delete_event_list(psensor_obj_cb->p_event_list);
if (result != DRV_ERROR_NONE) {
dms_err("delete event list fail. (result=%d)\n", result);
return result;
}
psensor_obj_cb->p_event_list = NULL;
return DRV_ERROR_NONE;
}
STATIC int dms_proc_sensor_data(struct dms_dev_sensor_cb *dev_sensor_cb, struct dms_node_sensor_cb *node_sensor_cb,
struct dms_sensor_object_cb *psensor_obj_cb, struct dms_sensor_event_data *pevent_data)
{
unsigned short sensor_class;
unsigned int result = DRV_ERROR_NONE;
sensor_class = psensor_obj_cb->sensor_object_cfg.sensor_class;
if (psensor_obj_cb->sensor_object_cfg.enable_flag == DMS_SENSOR_OBJECT_DISABLE_FLAG) {
* state to normal and report the recovery event */
if (psensor_obj_cb->fault_status != DMS_SENSOR_STATUS_INVALID) {
result = dms_resume_all_sensor_event(psensor_obj_cb);
if (result != DRV_ERROR_NONE) {
dms_err("resume all sensor event fail (result=%u)\n", result);
return result;
}
psensor_obj_cb->fault_status = DMS_SENSOR_STATUS_GOOD;
psensor_obj_cb->event_status = DMS_SENSOR_STATUS_GOOD;
}
return result;
}
switch (sensor_class) {
case DMS_STATICSTIC_SENSOR_CLASS:
result = dms_process_statis_result_report(node_sensor_cb, psensor_obj_cb, pevent_data);
if (result != DRV_ERROR_NONE) {
dms_err("Process Statistic Sensor Check Result Failed.\n");
dev_sensor_cb->sensor_scan_fail_record.sensor_process_fail++;
return result;
}
break;
case DMS_GENERAL_THRESHOLD_SENSOR_CLASS:
result = dms_process_general_result_report(node_sensor_cb, psensor_obj_cb, pevent_data);
if (result != DRV_ERROR_NONE) {
dms_err("Process General Sensor Check Result Failed\n");
dev_sensor_cb->sensor_scan_fail_record.sensor_process_fail++;
return result;
}
break;
case DMS_DISCRETE_SENSOR_CLASS:
result = dms_process_discrete_result_report(node_sensor_cb, psensor_obj_cb, pevent_data);
if (result != DRV_ERROR_NONE) {
dms_err("Process Discrete Sensor Check Result Failed\n");
dev_sensor_cb->sensor_scan_fail_record.sensor_process_fail++;
return result;
}
break;
default:
dms_err("Sensor Class NOT Support. (sensor_class=%u)\n", sensor_class);
return DRV_ERROR_PARA_ERROR;
}
return result;
}
static int dms_check_sensor_event_offset(unsigned char sensor_type, unsigned char event_offset)
{
int i;
int count = dms_get_sensor_type_count();
struct tag_dms_sensor_type *dms_sensor_type = NULL;
dms_sensor_type = dms_get_sensor_type();
for (i = 0; i < count; i++) {
if (dms_sensor_type[i].sensor_type == sensor_type) {
if (dms_sensor_type[i].sensor_event_count > event_offset) {
return DRV_ERROR_NONE;
} else {
dms_err("event offset error. (event—count=%u,sensor_type=0x%x; event_offset=%u)\n",
dms_sensor_type[i].sensor_event_count, sensor_type, event_offset);
return DRV_ERROR_PARA_ERROR;
}
}
}
return DRV_ERROR_PARA_ERROR;
}
int dms_check_sensor_data(struct dms_sensor_object_cb *sensor_obj_cb, unsigned char event_data)
{
return dms_check_sensor_event_offset((unsigned char)sensor_obj_cb->sensor_object_cfg.sensor_type, event_data);
}
STATIC void dms_printf_sensor_class_info(int class_val, const union dms_sensor_union *psensor_class)
{
switch (class_val) {
case DMS_STATICSTIC_SENSOR_CLASS:
print_sysfs(" occur_thres_type: %d\n", psensor_class->statistic_sensor.occur_thres_type);
print_sysfs(" resume_thres_type: %d\n", psensor_class->statistic_sensor.resume_thres_type);
print_sysfs(" max_stat_time: %u\n", psensor_class->statistic_sensor.max_stat_time);
print_sysfs(" min_stat_time: %u\n", psensor_class->statistic_sensor.min_stat_time);
print_sysfs(" occur_stat_time: %u\n", psensor_class->statistic_sensor.occur_stat_time);
print_sysfs(" attribute: %u\n", psensor_class->statistic_sensor.attribute);
print_sysfs(" max_occur_thres: %u\n", psensor_class->statistic_sensor.max_occur_thres);
print_sysfs(" min_occur_thres: %u\n", psensor_class->statistic_sensor.min_occur_thres);
print_sysfs(" max_resume_thres: %u\n", psensor_class->statistic_sensor.max_resume_thres);
print_sysfs(" min_resume_thres: %u\n", psensor_class->statistic_sensor.min_resume_thres);
print_sysfs(" occur_thres: %u\n", psensor_class->statistic_sensor.occur_thres);
print_sysfs(" resume_thres: %u\n", psensor_class->statistic_sensor.resume_thres);
break;
case DMS_GENERAL_THRESHOLD_SENSOR_CLASS:
print_sysfs(" attribute: %u\n", psensor_class->general_sensor.attribute);
print_sysfs(" thresSeries: %u\n", psensor_class->general_sensor.thres_series);
print_sysfs(" low_critical: %d\n", psensor_class->general_sensor.low_critical);
print_sysfs(" low_major: %d\n", psensor_class->general_sensor.low_major);
print_sysfs(" low_minor: %d\n", psensor_class->general_sensor.low_minor);
print_sysfs(" up_critical: %d\n", psensor_class->general_sensor.up_critical);
print_sysfs(" up_major: %d\n", psensor_class->general_sensor.up_major);
print_sysfs(" up_minor: %d\n", psensor_class->general_sensor.up_minor);
print_sysfs(" pos_thd_hysteresis: %d\n", psensor_class->general_sensor.pos_thd_hysteresis);
print_sysfs(" neg_thd_hysteresis: %d\n", psensor_class->general_sensor.neg_thd_hysteresis);
print_sysfs(" max_thres: %d\n", psensor_class->general_sensor.max_thres);
print_sysfs(" min_thres: %d\n", psensor_class->general_sensor.min_thres);
break;
case DMS_DISCRETE_SENSOR_CLASS:
print_sysfs(" attribute: %u\n", psensor_class->discrete_sensor.attribute);
print_sysfs(" debounce_time: %u\n", psensor_class->discrete_sensor.debounce_time);
break;
default:
dms_err("Sensor Class NOT Support. (class_val=0x%x!)\n", (unsigned int)class_val);
return;
}
return;
}
static void dms_printf_sensor_object_info(struct dms_sensor_object_cfg *pobj_cfg)
{
print_sysfs(" sensor_type: 0x%x\n", pobj_cfg->sensor_type);
print_sysfs(" sensor_name: %s\n", pobj_cfg->sensor_name);
print_sysfs(" sensor_class: %d\n", pobj_cfg->sensor_class);
dms_printf_sensor_class_info(pobj_cfg->sensor_class, &pobj_cfg->sensor_class_cfg);
print_sysfs(" scan_interval: %u\n", pobj_cfg->scan_interval);
print_sysfs(" proc_flag: %u\n", pobj_cfg->proc_flag);
print_sysfs(" enable_flag: %u\n", pobj_cfg->enable_flag);
print_sysfs(" pf_scan_func: %d\n", pobj_cfg->pf_scan_func != NULL);
print_sysfs(" assert_event_mask: 0x%x\n", pobj_cfg->assert_event_mask);
print_sysfs(" deassert_event_mask: 0x%x\n", pobj_cfg->deassert_event_mask);
}
static void dms_exit_sensor_object_cb(struct dms_sensor_object_cb *p_object_cb)
{
DMS_EVENT_LIST_ITEM *p_event_list = NULL;
p_event_list = p_object_cb->p_event_list;
while (p_event_list != NULL) {
(void)dms_sensor_report_event(p_object_cb, p_event_list, DMS_EVENT_TYPE_RESUME);
p_event_list = p_event_list->p_next;
}
if (p_object_cb->p_event_list != NULL) {
(void)sensor_delete_event_list(p_object_cb->p_event_list);
p_object_cb->p_event_list = NULL;
}
}
static void dms_exit_node_sensor_cb(struct dms_node_sensor_cb *node_sensor_cb)
{
struct dms_sensor_object_cb *pobject_cb = NULL;
struct dms_sensor_object_cb *tmp_ctl = NULL;
ka_list_for_each_entry_safe(pobject_cb, tmp_ctl, &(node_sensor_cb->sensor_object_table), list)
{
ka_list_del(&pobject_cb->list);
dms_exit_sensor_object_cb(pobject_cb);
dbl_kfree(pobject_cb);
pobject_cb = NULL;
}
}
STATIC int dms_check_sensor_type_table(void)
{
int i;
int count = dms_get_sensor_type_count();
struct tag_dms_sensor_type *dms_sensor_type = NULL;
dms_sensor_type = dms_get_sensor_type();
for (i = 0; i < count; i++) {
if (dms_sensor_type[i].sensor_type == DMS_SENSOR_RESERVED_FOR_PRODUCT) {
dms_err("The sensor type has be reserved for product.(sensor_type=0x%x)\n",
dms_sensor_type[i].sensor_type);
return DRV_ERROR_PARA_ERROR;
}
if (ka_base_strlen(dms_sensor_type[i].type_name) > DMS_MAX_SENSOR_TYPE_NAME_SIZE) {
dms_err("type name too long. (sensor_type=0x%x)\n",
dms_sensor_type[i].sensor_type);
return DRV_ERROR_PARA_ERROR;
}
}
return DRV_ERROR_NONE;
}
Function: dms_printf_sensor_obj_info
Description: printf
Calls: dms_printf_sensor_object_info
************************************************************************ */
STATIC void dms_printf_sensor_obj_info(struct dms_dev_sensor_cb *dev_sensor_cb)
{
unsigned int i;
struct dms_node_sensor_cb *node_sensor_cb = NULL;
struct dms_node_sensor_cb *tmp_ctl = NULL;
struct dms_sensor_object_cb *sensor_type_item = NULL;
struct dms_sensor_object_cb *tmp_sensor_ctl = NULL;
ka_task_mutex_lock(&dev_sensor_cb->dms_sensor_mutex);
dms_info("node_sensor_cb info. device id: %u\n", dev_sensor_cb->deviceid);
ka_list_for_each_entry_safe(node_sensor_cb, tmp_ctl, &(dev_sensor_cb->dms_node_sensor_cb_list), list)
{
print_sysfs("==================================\n");
print_sysfs("node_id: %u\n", node_sensor_cb->node_id);
print_sysfs("node_type: 0x%x\n", node_sensor_cb->node_type);
if (node_sensor_cb->owner_node != NULL) {
print_sysfs("node_name: %s\n", node_sensor_cb->owner_node->node_name);
}
print_sysfs("pid: %d\n", node_sensor_cb->pid);
print_sysfs("env_type: %u\n", node_sensor_cb->env_type);
print_sysfs("version: %u\n", node_sensor_cb->version);
print_sysfs("sensor_object_num: %u\n", node_sensor_cb->sensor_object_num);
* an event that needs to be reported, then report the event */
ka_list_for_each_entry_safe(sensor_type_item, tmp_sensor_ctl, &(node_sensor_cb->sensor_object_table), list)
{
print_sysfs(" - object_index: %u\n", sensor_type_item->object_index);
print_sysfs(" owner_node_id: %u\n", sensor_type_item->owner_node_id);
dms_printf_sensor_object_info(&sensor_type_item->sensor_object_cfg);
print_sysfs(" current_status: %d\n", sensor_type_item->current_value);
print_sysfs(" remain_time: %u\n", sensor_type_item->remain_time);
print_sysfs(" event_status: %u\n", sensor_type_item->event_status);
print_sysfs(" fault_status: %u\n", sensor_type_item->fault_status);
print_sysfs(" event_paras: ");
for (i = 0; i < sensor_type_item->paras_len; i++) {
print_sysfs(" %x", sensor_type_item->event_paras[i]);
}
if (sensor_type_item->sensor_object_cfg.sensor_class != DMS_STATICSTIC_SENSOR_CLASS) {
continue;
}
print_sysfs("\n");
print_sysfs(" object_op_state_ch_time: Y:%u M:%u\n",
sensor_type_item->class_cb.statistic_cb.object_op_state_ch_time.year,
sensor_type_item->class_cb.statistic_cb.object_op_state_ch_time.month);
print_sysfs(" object_op_state_chg_cause: %u\n",
sensor_type_item->class_cb.statistic_cb.object_op_state_chg_cause);
print_sysfs(" alarm_clear_times: %u\n", sensor_type_item->class_cb.statistic_cb.alarm_clear_times);
print_sysfs(" status_counter: %u\n", sensor_type_item->class_cb.statistic_cb.status_counter);
print_sysfs(" stat_time_counter: %u\n", sensor_type_item->class_cb.statistic_cb.stat_time_counter);
print_sysfs(" current_bit_count: %u\n", sensor_type_item->class_cb.statistic_cb.current_bit_count);
print_sysfs(" stat_event_paras:");
for (i = 0; i < sensor_type_item->paras_len; i++) {
print_sysfs(" %x", sensor_type_item->class_cb.statistic_cb.stat_event_paras[i]);
}
print_sysfs("\n");
}
}
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
}
Function: dms_printf_sensor_time_recorder
Description: printf sensor time
************************************************************************ */
void dms_printf_sensor_time_recorder(struct dms_dev_sensor_cb *pdev_sen_cb)
{
unsigned int i;
struct dms_sensor_scan_time_recorder *ptime_recorder;
ptime_recorder = &pdev_sen_cb->scan_time_recorder;
dms_info("\n sensor_time_recorder deviceid: %d", pdev_sen_cb->deviceid);
dms_info("\n record_scan_time_flag: %u", ptime_recorder->record_scan_time_flag);
dms_info("\n sensor_out_time_count: %u", ptime_recorder->sensor_out_time_count);
dms_info("\n sensor_record_index: %u", ptime_recorder->sensor_record_index);
dms_info("\n sensor_max_exec_time: %lu", ptime_recorder->max_sensor_scan_record.exec_time);
dms_info("\n sensor_max_exec_sensor: %.*s", DMS_SENSOR_DESCRIPT_LENGTH,
ptime_recorder->max_sensor_scan_record.sensor_name);
for (i = 0; i < ptime_recorder->sensor_record_index; i++) {
dms_info("\n sensor: name: %.*s", DMS_SENSOR_DESCRIPT_LENGTH,
ptime_recorder->sensor_scan_time_record[i].sensor_name);
dms_info("\n sensor:exec_time: %lu", ptime_recorder->sensor_scan_time_record[i].exec_time);
}
dms_info("\n dev:dev_out_time_count: %u", ptime_recorder->dev_out_time_count);
dms_info("\n dev:max_dev_scan_record: %lu", ptime_recorder->max_dev_scan_record);
dms_info("\n dev:dev_record_index: %u", ptime_recorder->dev_record_index);
for (i = 0; i < ptime_recorder->dev_record_index; i++) {
dms_info("\n dev:dev_scan_time_record: %lu", ptime_recorder->dev_scan_time_record[i]);
}
}
ssize_t dms_sensor_print_sensor_list(char *buf)
{
struct dms_dev_ctrl_block *dev_cb = NULL;
ssize_t buf_ret = 0;
if (buf == NULL) {
buf_ret += strcpy_s(buf, KA_MM_PAGE_SIZE, "buffer is null\n");
goto _out;
}
dev_cb = dms_get_dev_cb(0);
if (dev_cb == NULL) {
buf_ret += strcpy_s(buf, KA_MM_PAGE_SIZE, "device cb is null\n");
goto _out;
}
ka_task_mutex_lock(&dev_cb->node_lock);
dms_printf_sensor_obj_info(&dev_cb->dev_sensor_cb);
ka_task_mutex_unlock(&dev_cb->node_lock);
buf_ret += strcpy_s(buf, KA_MM_PAGE_SIZE,
"the sensor info has saved to the kernel log.\n");
_out:
return buf_ret;
}
KA_EXPORT_SYMBOL(dms_sensor_print_sensor_list);
static int dms_get_event_def_severity(unsigned char sensor_type, unsigned char event_offset, unsigned int *severity)
{
int i;
int count = dms_get_sensor_type_count();
struct tag_dms_sensor_type *dms_sensor_type = NULL;
dms_sensor_type = dms_get_sensor_type();
for (i = 0; i < count; i++) {
if (dms_sensor_type[i].sensor_type == sensor_type) {
if (dms_sensor_type[i].sensor_event_count > event_offset) {
*severity = (unsigned int)dms_sensor_type[i].sensor_event[event_offset].severity;
return DRV_ERROR_NONE;
} else {
dms_err("event offset error. (sensor_type=0x%x; offset=%u)\n", sensor_type,
event_offset);
return DRV_ERROR_PARA_ERROR;
}
} else if (sensor_type < dms_sensor_type[i].sensor_type) {
dms_err("sensor type error. (sensor_type=0x%x; offset=%u)", sensor_type, event_offset);
return DRV_ERROR_PARA_ERROR;
}
}
return DRV_ERROR_PARA_ERROR;
}
static u32 dms_gen_event_id(u32 node_type, u8 sensor_type, u8 error_type)
{
u32 fault_id = 0;
#ifdef CFG_EDGE_HOST
fault_id |= FAULT_EVENT_CODE_HOST;
#else
fault_id |= FAULT_EVENT_CODE_DEVICE;
#endif
fault_id |= FAULT_EVENT_NODETYPE_TO_CODE(node_type);
fault_id |= (sensor_type << FAULT_SENSOR_OFFSET);
fault_id |= (u32)error_type;
return fault_id;
}
STATIC int get_event_severity_from_config(u32 event_code, unsigned int *severity)
{
int left = 0;
int right = g_event_configs.config_cnt - 1;
while (left <= right) {
int mid = (right + left) / 2;
if (g_event_configs.event_configs[mid].event_code == event_code) {
*severity = g_event_configs.event_configs[mid].severity;
return 0;
} else if (g_event_configs.event_configs[mid].event_code < event_code) {
left = mid + 1;
} else if (g_event_configs.event_configs[mid].event_code > event_code) {
right = mid - 1;
}
}
#ifndef CFG_FEATURE_DEFAULT_SEVERITY
*severity = DMS_EVENT_MINOR;
return 0;
#else
return EEXIST;
#endif
}
int dms_get_event_severity(unsigned int node_type, unsigned char sensor_type, unsigned char event_offset,
unsigned int *severity)
{
int ret;
u32 event_code;
event_code = dms_gen_event_id(node_type, (u8)sensor_type, (u8)event_offset);
ret = get_event_severity_from_config(event_code, severity);
if (ret == 0) {
dms_debug("get_event_severity_from_config success. (event_code=0x%x; *severity=%u)\n", event_code, *severity);
return 0;
}
return dms_get_event_def_severity(sensor_type, event_offset, severity);
}
EXPORT_SYMBOL_ADAPT(dms_get_event_severity);
Function: int dms_get_event_string
Description: Print all sensor information
Calls: dms_get_sensor_type_count
************************************************************************ */
int dms_get_event_string(unsigned char sensor_type, unsigned char event_offset, char *event_str, int inbuf_size)
{
int i, ret;
int count = dms_get_sensor_type_count();
struct tag_dms_sensor_type *dms_sensor_type = NULL;
dms_sensor_type = dms_get_sensor_type();
for (i = 0; i < count; i++) {
if (dms_sensor_type[i].sensor_type == sensor_type) {
if (dms_sensor_type[i].sensor_event_count > event_offset) {
break;
} else {
dms_err("event offset error. (sensor_type=0x%x; offset=%u)\n", sensor_type,
event_offset);
return DRV_ERROR_PARA_ERROR;
}
} else if (sensor_type < dms_sensor_type[i].sensor_type) {
dms_err("sensor type error. (sensor_type=0x%x; offset=%u)\n", sensor_type, event_offset);
return DRV_ERROR_PARA_ERROR;
}
}
if (i != count) {
ret = strcpy_s(event_str, inbuf_size, dms_sensor_type[i].sensor_event[event_offset].eventstring);
if (ret != 0) {
dms_err("strcpy_s error. (ret=%d)\n", ret);
return DRV_ERROR_PARA_ERROR;
}
return DRV_ERROR_NONE;
}
return DRV_ERROR_PARA_ERROR;
}
Function: int dms_get_event_string
Description: Print all sensor
************************************************************************ */
int dms_get_sensor_type_name(unsigned char sensor_type, char *type_name, int inbuf_size)
{
int i, ret;
int count = dms_get_sensor_type_count();
struct tag_dms_sensor_type *dms_sensor_type = NULL;
dms_sensor_type = dms_get_sensor_type();
for (i = 0; i < count; i++) {
if (dms_sensor_type[i].sensor_type == sensor_type) {
ret = strcpy_s(type_name, inbuf_size, dms_sensor_type[i].type_name);
if (ret != 0) {
dms_err("strcpy_s error. (ret=%d)\n", ret);
return DRV_ERROR_PARA_ERROR;
}
return DRV_ERROR_NONE;
} else if (sensor_type < dms_sensor_type[i].sensor_type) {
dms_err("sensor type error. (sensor_type=0x%x)\n", sensor_type);
return DRV_ERROR_PARA_ERROR;
}
}
dms_err("sensor type error. (sensor type=0x%x)\n", sensor_type);
return DRV_ERROR_PARA_ERROR;
}
int dms_sensor_scan_one_node_object(struct dms_dev_sensor_cb *dev_sensor_cb,
struct dms_node_sensor_cb *node_sensor_cb, struct dms_sensor_object_cb *psensor_obj_cb,
struct dms_sensor_scan_time_recorder *ptime_recorder)
{
int result;
struct dms_sensor_event_data event_data = {0};
dev_sensor_cb->sensor_scan_fail_record.current_scan_func =
(void *)psensor_obj_cb->sensor_object_cfg.pf_scan_func;
dev_sensor_cb->sensor_scan_fail_record.node_id = node_sensor_cb->node_id;
dev_sensor_cb->sensor_scan_fail_record.node_type = node_sensor_cb->node_type;
if (psensor_obj_cb->sensor_object_cfg.enable_flag == DMS_SENSOR_DISABLE_FALG) {
return 0;
}
if (psensor_obj_cb->remain_time > DMS_SENSOR_CHECK_INTERVAL_TIME) {
psensor_obj_cb->remain_time -= DMS_SENSOR_CHECK_INTERVAL_TIME;
return 0;
}
psensor_obj_cb->remain_time = psensor_obj_cb->sensor_object_cfg.scan_interval;
if (ptime_recorder->record_scan_time_flag == DMS_SENSOR_CHECK_RECORD) {
ptime_recorder->start_sensor_scan_record(dev_sensor_cb);
}
result =
psensor_obj_cb->sensor_object_cfg.pf_scan_func(psensor_obj_cb->sensor_object_cfg.private_data, &event_data);
if (result != DRV_ERROR_NONE) {
dms_err_ratelimited("call function fail. (node_type=0x%x; node_id=%u; ret=%d)\n",
node_sensor_cb->node_type, node_sensor_cb->node_id, result);
if (ptime_recorder->record_scan_time_flag == DMS_SENSOR_CHECK_RECORD) {
ptime_recorder->stop_sensor_scan_record(dev_sensor_cb, psensor_obj_cb);
}
dev_sensor_cb->sensor_scan_fail_record.call_scan_func_fail++;
return result;
}
if (ptime_recorder->record_scan_time_flag == DMS_SENSOR_CHECK_RECORD) {
ptime_recorder->stop_sensor_scan_record(dev_sensor_cb, psensor_obj_cb);
}
if (event_data.event_count > DMS_MAX_SENSOR_EVENT_COUNT) {
dms_err_ratelimited("pf_scan_func return error. (sensor_name=%.*s; status=%d)\n",
DMS_SENSOR_DESCRIPT_LENGTH, psensor_obj_cb->sensor_object_cfg.sensor_name, event_data.event_count);
dev_sensor_cb->sensor_scan_fail_record.scan_func_date_error++;
return -EINVAL;
}
if (psensor_obj_cb->sensor_object_cfg.proc_flag != DMS_SENSOR_PROC_ENABLE_FLAG) {
return 0;
}
if (dms_proc_sensor_data(dev_sensor_cb, node_sensor_cb, psensor_obj_cb, &event_data) != DRV_ERROR_NONE) {
dms_err_ratelimited("proc sensor data return error. (sensor_name=%.*s)\n",
DMS_SENSOR_DESCRIPT_LENGTH, psensor_obj_cb->sensor_object_cfg.sensor_name);
return -EINVAL;
}
return 0;
}
static void dms_sensor_scan_node_sensor(struct dms_dev_sensor_cb *dev_sensor_cb,
struct dms_node_sensor_cb *node_sensor_cb)
{
struct dms_sensor_object_cb *psensor_obj_cb = NULL;
struct dms_sensor_object_cb *tmp_sensor_ctl = NULL;
unsigned short node_health = 0;
int result;
struct dms_sensor_scan_time_recorder *ptime_recorder;
ptime_recorder = &dev_sensor_cb->scan_time_recorder;
ka_list_for_each_entry_safe(psensor_obj_cb, tmp_sensor_ctl, &(node_sensor_cb->sensor_object_table), list) {
dms_sensor_notify_event_proc(DMS_SERSOR_SCAN_PERIOD);
if (psensor_obj_cb->sensor_object_cfg.pf_scan_func == NULL) {
dev_sensor_cb->sensor_scan_fail_record.null_scan_func_fail++;
dms_err_ratelimited("scan func Pointer is NULL\n");
continue;
}
result = dms_sensor_scan_one_node_object(dev_sensor_cb, node_sensor_cb,
psensor_obj_cb, ptime_recorder);
if (result != 0) {
dms_err_ratelimited("Scan one node object failed.(ret=%d)\n", result);
}
node_health = node_health > psensor_obj_cb->fault_status ? node_health : psensor_obj_cb->fault_status;
}
node_sensor_cb->health = node_health;
#if (defined(CFG_FEATURE_DEVICE_STATE_TABLE)) && (!defined(DRV_SOC_MISC_UT))
node_sensor_cb->owner_node->state = node_sensor_cb->health;
#endif
}
Function: void dms_sensor_scan_proc(struct dms_dev_sensor_cb *dev_sensor_cb)
Description: Sensor timing detection, processing the sensors of all nodes under each device
************************************************************************ */
void dms_sensor_scan_proc(struct dms_dev_sensor_cb *dev_sensor_cb)
{
struct dms_node_sensor_cb *node_sensor_cb = NULL;
struct dms_node_sensor_cb *tmp_ctl = NULL;
struct dms_sensor_scan_time_recorder *ptime_recorder;
unsigned short dev_health;
ptime_recorder = &dev_sensor_cb->scan_time_recorder;
if (ptime_recorder->record_scan_time_flag == DMS_SENSOR_CHECK_RECORD) {
ptime_recorder->start_dev_scan_record(dev_sensor_cb);
}
ka_task_mutex_lock(&dev_sensor_cb->dms_sensor_mutex);
dev_health = 0;
ka_list_for_each_entry_safe(node_sensor_cb, tmp_ctl, &(dev_sensor_cb->dms_node_sensor_cb_list), list)
{
if (node_sensor_cb->sensor_object_num == 0) {
dms_warn("dms_sensor_scan_task: not sensor type and obj! (nodetype=0x%x, nodeid = 0x%x)",
node_sensor_cb->node_type, node_sensor_cb->node_id);
dev_sensor_cb->sensor_scan_fail_record.get_data_from_node_fail++;
continue;
}
if ((node_sensor_cb->env_type == DMS_SENSOR_ENV_USER_SPACE) && (node_sensor_cb->pid <= 0)) {
dms_err_ratelimited("env error. (nodeid=0x%x; pid=%d)\n", node_sensor_cb->env_type,
node_sensor_cb->pid);
dev_sensor_cb->sensor_scan_fail_record.get_data_from_node_fail++;
continue;
}
* an event that needs to be reported, then report the event */
dms_sensor_scan_node_sensor(dev_sensor_cb, node_sensor_cb);
dev_health = dev_health > node_sensor_cb->health ? dev_health : node_sensor_cb->health;
}
dev_sensor_cb->health = dev_health;
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
if (ptime_recorder->record_scan_time_flag == DMS_SENSOR_CHECK_RECORD) {
ptime_recorder->stop_dev_scan_record(dev_sensor_cb);
}
}
STATIC int dms_sensor_get_one_node_health_events(struct dms_node_sensor_cb *node_sensor_cb,
struct dms_event_obj *event_buff, unsigned int input_count, unsigned int *output_count)
{
unsigned int temp_out_count = *output_count;
unsigned int assert_mask, deassert_mask;
struct dms_sensor_object_cb *psensor_obj_cb = NULL;
struct dms_sensor_object_cb *tmp_sensor_ctl = NULL;
DMS_EVENT_LIST_ITEM *p_temp_event_list = NULL;
if (node_sensor_cb->sensor_object_num == 0) {
dms_warn("dms_sensor_scan_task: not sensor type and obj! nodeid = %u", node_sensor_cb->node_id);
return 0;
}
if ((node_sensor_cb->env_type == DMS_SENSOR_ENV_USER_SPACE) && (node_sensor_cb->pid <= 0)) {
dms_warn("env warn! (nodeid = %u, pid:%d)\n", node_sensor_cb->env_type, node_sensor_cb->pid);
return 0;
}
* an event that needs to be reported, then report the event */
ka_list_for_each_entry_safe(psensor_obj_cb, tmp_sensor_ctl, &(node_sensor_cb->sensor_object_table), list) {
p_temp_event_list = psensor_obj_cb->p_event_list;
if (p_temp_event_list == NULL) {
continue;
}
while (p_temp_event_list != NULL) {
if (temp_out_count >= input_count) {
return -EINVAL;
}
assert_mask = psensor_obj_cb->sensor_object_cfg.assert_event_mask;
deassert_mask = psensor_obj_cb->sensor_object_cfg.deassert_event_mask;
if (dms_sensor_check_mask_enable(assert_mask, p_temp_event_list->event_data) &&
dms_sensor_check_mask_enable(deassert_mask, p_temp_event_list->event_data)) {
(void)dms_fill_event_data(psensor_obj_cb, p_temp_event_list,
DMS_EVENT_TYPE_OCCUR, &event_buff[temp_out_count]);
temp_out_count++;
}
p_temp_event_list = p_temp_event_list->p_next;
}
}
*output_count = temp_out_count;
return 0;
}
Function: int dms_sensor_get_health_events
Description: Get all events of the sensor events
************************************************************************ */
int dms_sensor_get_health_events(struct dms_dev_sensor_cb *dev_sensor_cb, struct dms_event_obj *event_buff,
unsigned int input_count, unsigned int *output_count)
{
int ret;
unsigned int temp_out_count = 0;
struct dms_node_sensor_cb *node_sensor_cb = NULL;
struct dms_node_sensor_cb *tmp_ctl = NULL;
if ((dev_sensor_cb == NULL) || (event_buff == NULL) || (output_count == NULL)) {
return DRV_ERROR_PARA_ERROR;
}
ka_task_mutex_lock(&dev_sensor_cb->dms_sensor_mutex);
ka_list_for_each_entry_safe(node_sensor_cb, tmp_ctl, &(dev_sensor_cb->dms_node_sensor_cb_list), list) {
ret = dms_sensor_get_one_node_health_events(node_sensor_cb, event_buff, input_count, &temp_out_count);
if (ret != 0) {
goto sensor_exit;
}
}
sensor_exit:
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
*output_count = temp_out_count;
return DRV_ERROR_NONE;
}
KA_EXPORT_SYMBOL(dms_sensor_get_health_events);
STATIC void dms_sensor_clean_report_event_list(struct dms_sensor_object_cb *psensor_obj_cb)
{
int ret;
if (psensor_obj_cb->sensor_object_cfg.pf_clear_event_func == NULL) {
dms_debug("pf_clear_event_func is NULL, report module not registered. (node_type=0x%x; node_id=%u; "
"private_data=0x%llx)\n",
psensor_obj_cb->owner_node_type,
psensor_obj_cb->owner_node_id,
psensor_obj_cb->sensor_object_cfg.private_data);
return;
}
ret = psensor_obj_cb->sensor_object_cfg.pf_clear_event_func(psensor_obj_cb->sensor_object_cfg.private_data);
if (ret != 0) {
dms_warn("clean report event list not OK. (node_type=0x%x; node_id=%u; private_data=0x%llx; ret=%d)\n",
psensor_obj_cb->owner_node_type,
psensor_obj_cb->owner_node_id,
psensor_obj_cb->sensor_object_cfg.private_data,
ret);
}
return;
}
int dms_sensor_clean_health_events(struct dms_dev_sensor_cb *dev_sensor_cb)
{
struct dms_node_sensor_cb *node_sensor_cb = NULL;
struct dms_node_sensor_cb *tmp_ctl = NULL;
struct dms_sensor_object_cb *psensor_obj_cb = NULL;
struct dms_sensor_object_cb *tmp_sensor_ctl = NULL;
if (dev_sensor_cb == NULL) {
return DRV_ERROR_PARA_ERROR;
}
ka_task_mutex_lock(&dev_sensor_cb->dms_sensor_mutex);
ka_list_for_each_entry_safe(node_sensor_cb, tmp_ctl, &(dev_sensor_cb->dms_node_sensor_cb_list), list)
{
if (node_sensor_cb->sensor_object_num == 0) {
dms_warn("dms_sensor_scan_task: not sensor type and obj! nodeid = %u", node_sensor_cb->node_id);
continue;
}
if ((node_sensor_cb->env_type == DMS_SENSOR_ENV_USER_SPACE) && (node_sensor_cb->pid <= 0)) {
dms_err("env error. (nodeid=%u; pid=%d)\n", node_sensor_cb->env_type,
node_sensor_cb->pid);
continue;
}
* an event that needs to be reported, then report the event */
ka_list_for_each_entry_safe(psensor_obj_cb, tmp_sensor_ctl, &(node_sensor_cb->sensor_object_table), list)
{
if (psensor_obj_cb->p_event_list != NULL) {
dms_sensor_clean_report_event_list(psensor_obj_cb);
(void)sensor_delete_event_list(psensor_obj_cb->p_event_list);
psensor_obj_cb->p_event_list = NULL;
psensor_obj_cb->fault_status = DMS_SENSOR_STATUS_GOOD;
}
}
node_sensor_cb->health = DMS_SENSOR_STATUS_GOOD;
#if (defined(CFG_FEATURE_DEVICE_STATE_TABLE)) && (!defined(DRV_SOC_MISC_UT))
node_sensor_cb->owner_node->state = node_sensor_cb->health;
#endif
}
dev_sensor_cb->health = DMS_SENSOR_STATUS_GOOD;
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
return DRV_ERROR_NONE;
}
int dms_sensor_mask_events(struct dms_dev_sensor_cb *dev_sensor_cb, u8 mask,
u16 node_type, u8 sensor_type, u8 event_state)
{
struct dms_node_sensor_cb *node_sensor_cb = NULL;
struct dms_node_sensor_cb *tmp_ctl = NULL;
struct dms_sensor_object_cb *psensor_obj_cb = NULL;
struct dms_sensor_object_cb *tmp_sensor_ctl = NULL;
if (dev_sensor_cb == NULL) {
return DRV_ERROR_PARA_ERROR;
}
ka_task_mutex_lock(&dev_sensor_cb->dms_sensor_mutex);
ka_list_for_each_entry_safe(node_sensor_cb, tmp_ctl, &(dev_sensor_cb->dms_node_sensor_cb_list), list) {
if ((node_sensor_cb->node_type != node_type) || (node_sensor_cb->sensor_object_num == 0)) {
continue;
}
ka_list_for_each_entry_safe(psensor_obj_cb, tmp_sensor_ctl, &(node_sensor_cb->sensor_object_table), list) {
if (psensor_obj_cb->sensor_object_cfg.sensor_type != sensor_type) {
continue;
}
psensor_obj_cb->sensor_object_cfg.deassert_event_mask &= ~(1U << event_state);
psensor_obj_cb->sensor_object_cfg.assert_event_mask &= ~(1U << event_state);
if (mask == 0) {
psensor_obj_cb->sensor_object_cfg.deassert_event_mask |=
((1U << event_state) & psensor_obj_cb->orig_obj_cfg.deassert_event_mask);
psensor_obj_cb->sensor_object_cfg.assert_event_mask |=
((1U << event_state) & psensor_obj_cb->orig_obj_cfg.assert_event_mask);
}
}
}
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
return DRV_ERROR_NONE;
}
int dms_sensor_get_dev_health(struct dms_dev_sensor_cb *dev_sensor_cb)
{
return dev_sensor_cb->health;
}
Function: unsigned int dms_sensor_register(struct dms_dev_node *owner_node, struct dms_sensor_type *psensor)
Description: Kernel registration sensor information table
Data Accessed: gpDmsSensorQueryTable
Data Updated: gpDmsSensorQueryTable
************************************************************************ */
unsigned int dms_sensor_register(struct dms_node *owner_node, struct dms_sensor_object_cfg *psensor_obj_cfg)
{
return (dms_sensor_register_all(owner_node, psensor_obj_cfg, DMS_SENSOR_ENV_KERNEL_SPACE));
}
EXPORT_SYMBOL_ADAPT(dms_sensor_register);
Function: unsigned int dms_sensor_register(struct dms_dev_node *owner_node, struct dms_sensor_type *psensor)
Description: User mode registration sensor interface
Data Accessed: gpDmsSensorQueryTable
Data Updated: gpDmsSensorQueryTable
************************************************************************ */
unsigned int dms_sensor_register_for_userspace(struct dms_node *owner_node,
struct dms_sensor_object_cfg *psensor_obj_cfg)
{
return dms_sensor_register_all(owner_node, psensor_obj_cfg, DMS_SENSOR_ENV_USER_SPACE);
}
KA_EXPORT_SYMBOL(dms_sensor_register_for_userspace);
Function: unsigned int dms_sensor_node_unregister(struct dms_node *owner_node)
Description: unregister sensor object
************************************************************************ */
unsigned int dms_sensor_object_unregister(struct dms_node *owner_node, struct dms_sensor_object_cfg *psensor_obj_cfg)
{
struct dms_dev_sensor_cb *dev_sensor_cb = NULL;
struct dms_sensor_object_cb *sensor_type_item = NULL;
struct dms_sensor_object_cb *tmp_sensor_ctl = NULL;
struct dms_node_sensor_cb *pnode_sen_cb = NULL;
int rec;
dev_sensor_cb = dms_get_sensor_cb(owner_node);
if (dev_sensor_cb == NULL) {
dms_err("dms get sensor cb fail. (nodeid=%d)\n", owner_node->node_id);
return DRV_ERROR_PARA_ERROR;
}
ka_task_mutex_lock(&dev_sensor_cb->dms_sensor_mutex);
rec = dms_get_node_sensor_cb_by_nodeid(dev_sensor_cb, owner_node->node_type, owner_node->node_id, &pnode_sen_cb);
if (rec != DRV_ERROR_NONE) {
dms_err("get node sensor cb fail. (nodeid=%d, nodetype=%d)\n", owner_node->node_type, owner_node->node_id);
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
return rec;
}
* event that needs to be reported, then report the event */
if (pnode_sen_cb != NULL) {
ka_list_for_each_entry_safe(sensor_type_item, tmp_sensor_ctl, &(pnode_sen_cb->sensor_object_table), list)
{
if (dms_compare_sensor_object(&sensor_type_item->sensor_object_cfg, psensor_obj_cfg) == true) {
ka_list_del(&sensor_type_item->list);
dms_exit_sensor_object_cb(sensor_type_item);
dbl_kfree(sensor_type_item);
sensor_type_item = NULL;
pnode_sen_cb->sensor_object_num -= (pnode_sen_cb->sensor_object_num >= 1) ? 1 : 0;
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
return DRV_ERROR_NONE;
}
}
}
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
return DRV_ERROR_NONE;
}
KA_EXPORT_SYMBOL(dms_sensor_object_unregister);
Function: unsigned int dms_sensor_node_unregister(struct dms_node *owner_node)
Description: unregister sensor node
************************************************************************ */
unsigned int dms_sensor_node_unregister(struct dms_node *owner_node)
{
struct dms_dev_sensor_cb *dev_sensor_cb = NULL;
struct dms_node_sensor_cb *pnode_sensor_cb = NULL;
struct dms_node_sensor_cb *tmp_ctl = NULL;
if (owner_node == NULL) {
dms_err("owner_node is null.\n");
return DRV_ERROR_PARA_ERROR;
}
dev_sensor_cb = dms_get_sensor_cb(owner_node);
if (dev_sensor_cb == NULL) {
dms_err("dms get sensor cb fail. (nodeid=%d)\n", owner_node->node_id);
return DRV_ERROR_PARA_ERROR;
}
ka_task_mutex_lock(&dev_sensor_cb->dms_sensor_mutex);
ka_list_for_each_entry_safe(pnode_sensor_cb, tmp_ctl, &(dev_sensor_cb->dms_node_sensor_cb_list), list)
{
if ((pnode_sensor_cb->node_id == (unsigned int)(owner_node->node_id)) &&
(pnode_sensor_cb->node_type == owner_node->node_type)) {
ka_list_del(&pnode_sensor_cb->list);
dms_exit_node_sensor_cb(pnode_sensor_cb);
dbl_kfree(pnode_sensor_cb);
pnode_sensor_cb = NULL;
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
return DRV_ERROR_NONE;
}
}
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
return DRV_ERROR_NONE;
}
EXPORT_SYMBOL_ADAPT(dms_sensor_node_unregister);
Function: unsigned int dms_init_sensor(void)
Description: sensor Processing module initialization
************************************************************************ */
unsigned int dms_init_dev_sensor_cb(int deviceid, struct dms_dev_sensor_cb *sensor_cb)
{
if (sensor_cb == NULL) {
dms_err("info input fail\n");
return DRV_ERROR_PARA_ERROR;
}
ka_task_mutex_init(&sensor_cb->dms_sensor_mutex);
KA_INIT_LIST_HEAD(&sensor_cb->dms_node_sensor_cb_list);
sensor_cb->node_cb_num = 0;
sensor_cb->deviceid = deviceid;
sensor_cb->health = 0;
(void)memset_s((void *)&(sensor_cb->sensor_scan_fail_record), sizeof(struct dms_sensor_scan_fail_record), 0,
sizeof(struct dms_sensor_scan_fail_record));
dms_init_sensor_time_recorder(sensor_cb);
return DRV_ERROR_NONE;
}
Function: unsigned int dms_init_sensor(void)
************************************************************************ */
unsigned int dms_sen_init_sensor(void)
{
u32 i;
dms_info("dms init sensor module\n");
for (i = 0; i < ASCEND_DEV_MAX_NUM; i++) {
struct dms_dev_ctrl_block* dev_cb = dms_get_dev_cb(i);
if (dev_cb == NULL) {
dms_info("the device is not initialized.(dev id=%u)\n", i);
continue;
}
(void)dms_init_dev_sensor_cb(i, &dev_cb->dev_sensor_cb);
}
sensor_init_event_list_cb();
if (dms_check_sensor_type_table() != DRV_ERROR_NONE) {
dms_err("dms_check_sensor_type_table fail\n");
return DRV_ERROR_INNER_ERR;
}
return DRV_ERROR_NONE;
}
unsigned int dms_sen_exit_sensor_event(void)
{
u32 i;
dms_info("dms exit sensor module\n");
sensor_exit_event_list_cb();
for (i = 0; i < ASCEND_DEV_MAX_NUM; i++) {
struct dms_dev_ctrl_block* dev_cb = dms_get_dev_cb(i);
if (dev_cb == NULL) {
dms_info("the device is not initialized.(dev id=%u)\n", i);
continue;
}
dms_exit_dev_sensor_cb(&dev_cb->dev_sensor_cb);
}
return DRV_ERROR_NONE;
}
Function: void dms_exit_dev_sensor_cb(struct dms_dev_sensor_cb *dev_sensor_cb)
Description: Clean up the sensor module
************************************************************************ */
void dms_exit_dev_sensor_cb(struct dms_dev_sensor_cb *dev_sensor_cb)
{
struct dms_node_sensor_cb *pnode_sensor_cb = NULL;
struct dms_node_sensor_cb *tmp_ctl = NULL;
ka_task_mutex_lock(&dev_sensor_cb->dms_sensor_mutex);
ka_list_for_each_entry_safe(pnode_sensor_cb, tmp_ctl, &(dev_sensor_cb->dms_node_sensor_cb_list), list)
{
ka_list_del(&pnode_sensor_cb->list);
dms_exit_node_sensor_cb(pnode_sensor_cb);
dbl_kfree(pnode_sensor_cb);
pnode_sensor_cb = NULL;
}
ka_task_mutex_unlock(&dev_sensor_cb->dms_sensor_mutex);
dev_sensor_cb->node_cb_num = 0;
ka_task_mutex_destroy(&dev_sensor_cb->dms_sensor_mutex);
}
void dms_sensor_release(int owner_pid)
{
int i;
struct dms_dev_ctrl_block *cb = NULL;
struct dms_node_sensor_cb *pnode_sensor_cb = NULL;
struct dms_node_sensor_cb *tmp_ctl = NULL;
for (i = 0; i < ASCEND_DEV_MAX_NUM; i++) {
cb = dms_get_dev_cb(i);
if (cb == NULL) {
continue;
}
ka_task_mutex_lock(&cb->dev_sensor_cb.dms_sensor_mutex);
ka_list_for_each_entry_safe(pnode_sensor_cb, tmp_ctl, &(cb->dev_sensor_cb.dms_node_sensor_cb_list), list)
{
if ((pnode_sensor_cb->env_type == DMS_SENSOR_ENV_USER_SPACE) && (pnode_sensor_cb->pid == owner_pid)) {
dms_info("release sensor. (node_type=0x%x; owner_pid=%d)\n", pnode_sensor_cb->node_type, owner_pid);
ka_list_del(&pnode_sensor_cb->list);
dms_exit_node_sensor_cb(pnode_sensor_cb);
dbl_kfree(pnode_sensor_cb);
pnode_sensor_cb = NULL;
}
}
ka_task_mutex_unlock(&cb->dev_sensor_cb.dms_sensor_mutex);
}
return;
}
KA_EXPORT_SYMBOL(dms_sensor_release);