* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include <sys/ioctl.h>
#include "securec.h"
#include "ascend_hal_error.h"
#include "ascend_hal.h"
#include "dms_user_common.h"
#include "dms/dms_lpm_interface.h"
#include "devdrv_user_common.h"
#include "devdrv_ioctl.h"
#include "dms_device_info.h"
#include "dms/dms_devdrv_info_comm.h"
#include "ascend_hal_external.h"
#include "devmng_user_common.h"
#include "ascend_dev_num.h"
#ifdef STATIC_SKIP
#define STATIC
#else
#define STATIC static
#endif
#define DEVDRV_DDR_TEMP_GEAR_MAX 32
STATIC int dms_lpm_parameter_check(struct dms_lpm_info_in *in, void *result)
{
if (in->dev_id >= ASCEND_DEV_MAX_NUM) {
DMS_ERR("Invalid device id. (dev_id=%u)\n", in->dev_id);
return DRV_ERROR_INVALID_DEVICE;
}
if (in->vfid >= VDAVINCI_MAX_VFID_NUM) {
DMS_ERR("Invalid parameter. (dev_id=%u; vfid=%d)\n", in->dev_id, in->vfid);
return DRV_ERROR_INVALID_VALUE;
}
if (in->core_id >= INVALID_TSENSOR_ID) {
DMS_ERR("Invalid core id. (dev_id=%u; core_id=%d)\n", in->dev_id, in->core_id);
return DRV_ERROR_INVALID_VALUE;
}
if (in->sub_cmd >= DMS_LPM_SUB_CMD_MAX) {
DMS_ERR("Invalid subcommand. (dev_id=%u; sub_cmd=%d)\n", in->dev_id, in->sub_cmd);
return DRV_ERROR_INVALID_VALUE;
}
if (result == NULL) {
DMS_ERR("Parameter result is NULL. (dev_id=%u)\n", in->dev_id);
return DRV_ERROR_INVALID_HANDLE;
}
return DRV_ERROR_NONE;
}
drvError_t DmsGetLpmInfo(struct dms_lpm_info_in *in, void *result, unsigned int result_size)
{
struct dms_ioctl_arg ioarg = {0};
int ret, user_errno;
#ifdef CFG_FEATURE_RECONSITUTION_TEMPORARY
struct dms_filter_st filter = {0};
#endif
ret = dms_lpm_parameter_check(in, result);
if (ret != 0) {
DMS_ERR("Invalid parameter. (dev_id=%u; ret=%d)\n", in->dev_id, ret);
return ret;
}
#ifdef CFG_FEATURE_SRIOV
if (in->dev_id >= ASCEND_VDEV_ID_START) {
* VF device id is start from ASCEND_VDEV_ID_START, each PF has VDAVINCI_MAX_VFID_NUM of VFs
*/
in->dev_id = (in->dev_id - ASCEND_VDEV_ID_START) / VDAVINCI_MAX_VFID_NUM;
}
#endif
ioarg.main_cmd = DMS_MAIN_CMD_LPM;
ioarg.sub_cmd = in->sub_cmd;
ioarg.filter_len = 0;
ioarg.input = (void *)in;
ioarg.input_len = sizeof(struct dms_lpm_info_in);
ioarg.output = result;
ioarg.output_len = result_size;
#ifdef CFG_FEATURE_RECONSITUTION_TEMPORARY
if (in->sub_cmd == DMS_LPM_GET_FREQUENCY && in->core_id == HBM_ID) {
filter.filter_len = (unsigned int)sprintf_s(filter.filter, sizeof(filter.filter), "frequency_of_hbm");
ioarg.filter = &filter.filter[0];
ioarg.filter_len = filter.filter_len;
}
#endif
ret = DmsIoctl(DMS_IOCTL_CMD, &ioarg);
if (ret != 0) {
user_errno = errno_to_user_errno(ret);
DMS_EX_NOTSUPPORT_ERR(user_errno, "Dms get device lpm info failed."
"(dev_id=%u; sub_cmd=%u; core_id=%u; ret=%d; user_errno=%d)\n",
in->dev_id, in->sub_cmd, in->core_id, ret, user_errno);
return user_errno;
}
DMS_DEBUG("Dms get device lpm info success. (dev_id=%u; sub_cmd=%d)\n", in->dev_id, in->sub_cmd);
return DRV_ERROR_NONE;
}
#define BUFSIZE_MIN 8
#define LP_ERRCODE_LENGTH 16
#define LP_ERRCODE_QUERY_FAIL 1
#define LP_ERRCODE_QUERY_TIMEOUT 2
#define LP_ERRCODE_QUERY_PARA_ERR 3
#define LP_ERRCODE_QUERY_NONSUPPORT 4
STATIC int dms_get_dsmi_errcode(u32 err_code)
{
int ret;
switch (err_code) {
case LP_ERRCODE_QUERY_FAIL:
DMS_ERR("[lp_errcode] LP_ERRCODE_QUERY_FAIL.\n");
ret = DRV_ERROR_INNER_ERR;
break;
case LP_ERRCODE_QUERY_TIMEOUT:
DMS_ERR("[lp_errcode] LP_ERRCODE_QUERY_TIMEOUT.\n");
ret = DRV_ERROR_WAIT_TIMEOUT;
break;
case LP_ERRCODE_QUERY_PARA_ERR:
DMS_ERR("[lp_errcode] LP_ERRCODE_QUERY_PARA_ERR.\n");
ret = DRV_ERROR_INNER_ERR;
break;
case LP_ERRCODE_QUERY_NONSUPPORT:
ret = DRV_ERROR_NOT_SUPPORT;
break;
default:
ret = 0;
break;
}
return ret;
}
STATIC int DmsCheckLpErrcode(struct ioctl_arg *arg)
{
int ret;
u32 voltage_err_code;
u32 current_err_code;
voltage_err_code = (u32)arg->data2;
current_err_code = voltage_err_code & 0x0000ffff;
voltage_err_code = voltage_err_code >> LP_ERRCODE_LENGTH;
ret = dms_get_dsmi_errcode(voltage_err_code);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "get dsmi err_code failed, voltage_err_code = %d.\n", voltage_err_code);
return ret;
}
ret = dms_get_dsmi_errcode(current_err_code);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "get dsmi err_code failed, current_err_code = %d.\n", current_err_code);
return ret;
}
return ret;
}
STATIC int dms_get_voltage_current_from_lp(unsigned int dev_id, unsigned int sub_cmd, void *out_buf,
unsigned int *buf_size)
{
int ret;
struct ioctl_arg arg = {0};
unsigned int arg_size = sizeof(struct ioctl_arg);
if ((sub_cmd >= DSMI_LP_SUB_CMD_MAX) || out_buf == NULL || buf_size == NULL) {
DMS_ERR("input para illegal, sub_cmd=%u, out_buf or buf_size is null\n", sub_cmd);
return DRV_ERROR_PARA_ERROR;
}
if (*buf_size < BUFSIZE_MIN) {
DMS_ERR("input para illegal, buf_size=%u\n", *buf_size);
return DRV_ERROR_PARA_ERROR;
}
arg.dev_id = dev_id;
arg.vfid = DMS_VF_ID_PF;
arg.type = DMS_LPM_SOC_ID;
ret = DmsGetDeviceInfo(dev_id, DMS_MAIN_CMD_LP, sub_cmd, (void *)&arg, &arg_size);
if (ret != 0) {
DMS_ERR("DmsGetDeviceInfo failed, devid(%u), sub_cmd(%u), ret(%d).\n", dev_id, sub_cmd, ret);
return ret;
}
ret = DmsCheckLpErrcode(&arg);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "check lp_errcode failed.\n");
return ret;
}
ret = memcpy_s(out_buf, sizeof(arg.data1), &arg.data1, sizeof(arg.data1));
if (ret != 0) {
DMS_ERR("memcpy_s failed, ret = %d\n", ret);
return DRV_ERROR_MEMORY_OPT_FAIL;
}
ret = memcpy_s(((char *)out_buf + sizeof(arg.data1)), sizeof(arg.data3), &arg.data3, sizeof(arg.data3));
if (ret != 0) {
DMS_ERR("memcpy_s failed, ret = %d\n", ret);
return DRV_ERROR_MEMORY_OPT_FAIL;
}
*buf_size = sizeof(arg.data1) + sizeof(arg.data3);
return DRV_ERROR_NONE;
}
STATIC int dms_get_acg_from_lp(unsigned int dev_id, unsigned int sub_cmd, void *out_buf, unsigned int *buf_size)
{
int ret;
struct ioctl_arg arg = {0};
unsigned int arg_size = sizeof(struct ioctl_arg);
if ((sub_cmd >= DSMI_LP_SUB_CMD_MAX) || out_buf == NULL || buf_size == NULL) {
DMS_ERR("input para illegal, sub_cmd=%u, out_buf or buf_size is null\n", sub_cmd);
return DRV_ERROR_PARA_ERROR;
}
if (*buf_size < sizeof(int)) {
DMS_ERR("input para illegal, buf_size=%u\n", *buf_size);
return DRV_ERROR_PARA_ERROR;
}
arg.dev_id = dev_id;
arg.vfid = DMS_VF_ID_PF;
arg.type = DMS_LPM_SOC_ID;
ret = DmsGetDeviceInfo(dev_id, DMS_MAIN_CMD_LP, sub_cmd, (void *)&arg, &arg_size);
if (ret != 0) {
DMS_ERR("DmsGetDeviceInfo failed, devid(%u), sub_cmd(%u), ret(%d).\n", dev_id, sub_cmd, ret);
return ret;
}
ret = memcpy_s(out_buf, *buf_size, &arg.data1, sizeof(arg.data1));
if (ret != 0) {
DMS_ERR("memcpy_s failed, ret = %d\n", ret);
return DRV_ERROR_MEMORY_OPT_FAIL;
}
*buf_size = sizeof(arg.data1);
return DRV_ERROR_NONE;
}
int DmsGetInfoFromLp(unsigned int dev_id, unsigned int vfid, unsigned int sub_cmd, void *out_buf,
unsigned int *buf_size)
{
int ret;
(void)vfid;
if (out_buf == NULL || buf_size == NULL) {
DMS_ERR("input para illegal, out_buf or buf_size is null pointer\n");
return DRV_ERROR_PARA_ERROR;
}
switch (sub_cmd) {
case DSMI_LP_SUB_CMD_AICORE_VOLTAGE_CURRENT:
case DSMI_LP_SUB_CMD_HYBIRD_VOLTAGE_CURRENT:
case DSMI_LP_SUB_CMD_TAISHAN_VOLTAGE_CURRENT:
case DSMI_LP_SUB_CMD_DDR_VOLTAGE_CURRENT:
ret = dms_get_voltage_current_from_lp(dev_id, sub_cmd, out_buf, buf_size);
break;
case DSMI_LP_SUB_CMD_ACG:
ret = dms_get_acg_from_lp(dev_id, sub_cmd, out_buf, buf_size);
break;
default:
DMS_ERR("dsmi sub_cmd is illegal! sub_cmd=%u\n", sub_cmd);
return DRV_ERROR_NOT_SUPPORT;
}
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "DmsGetInfoFromLp failed, ret = %d.\n", ret);
return ret;
}
return DRV_ERROR_NONE;
}
int dms_set_temperature_threshold(unsigned int dev_id, unsigned int sub_cmd, void *in_buf, unsigned int buf_size)
{
int ret;
struct ioctl_arg arg = {0};
unsigned int *temp_thold = (unsigned int *)in_buf;
unsigned int arg_size = sizeof(struct ioctl_arg);
if ((dev_id >= ASCEND_DEV_MAX_NUM) || (in_buf == NULL)) {
DMS_ERR("dms_set_temperature_threshold para err, devid %d.\n", dev_id);
return DRV_ERROR_INVALID_VALUE;
}
if ((sub_cmd != DSMI_TEMP_SUB_CMD_DDR_THOLD) && (sub_cmd != DSMI_TEMP_SUB_CMD_SOC_THOLD) &&
(sub_cmd != DSMI_TEMP_SUB_CMD_SOC_MIN_THOLD)) {
DMS_ERR("dms_set_temperature_threshold sub_cmd %d err, devid %d.\n", sub_cmd, dev_id);
return DRV_ERROR_INVALID_VALUE;
}
if (buf_size < sizeof(unsigned int)) {
DMS_ERR("size is invalid. (size=%u; expect_size=%u)\n", buf_size, sizeof(unsigned int));
return DRV_ERROR_INVALID_VALUE;
}
arg.type = DMS_LPM_SOC_ID;
arg.dev_id = dev_id;
arg.data1 = *temp_thold;
arg.data2 = (int)buf_size;
DMS_EVENT("dms_set_temperature_threshold: %d.\n", *temp_thold);
ret = DmsSetDeviceInfo(dev_id, DMS_MAIN_CMD_TEMP, sub_cmd, (void *)&arg, arg_size);
if (ret != 0) {
DMS_ERR("DmsSetDeviceInfo failed, devid(%u), sub_cmd(%u), ret(%d).\n", dev_id, sub_cmd, ret);
return ret;
}
return DRV_ERROR_NONE;
}
STATIC int DmsGetDdrTemperature(unsigned int dev_id, unsigned int sub_cmd, void *out_buf, unsigned int *buf_size)
{
int ret;
struct dms_ddr_temp_arg arg = {0};
unsigned int arg_size = sizeof(struct dms_ddr_temp_arg);
unsigned char ddr_temp[DEVDRV_DDR_TEMP_GEAR_MAX] = {0};
if (out_buf == NULL || buf_size == NULL) {
DMS_ERR("input para illegal, out_buf or buf_size is null pointer, devid(%u).\n", dev_id);
return DRV_ERROR_INVALID_VALUE;
}
arg.dev_id = dev_id;
arg.commoninfo = ddr_temp;
arg.commoninfo_len = sizeof(ddr_temp);
arg.vfid = DMS_VF_ID_PF;
arg.core_id = DMS_LPM_SOC_ID;
ret = DmsGetDeviceInfo(dev_id, DMS_MAIN_CMD_TEMP, sub_cmd, (void *)&arg, &arg_size);
if (ret != 0) {
DMS_ERR("DmsGetDeviceInfo failed, devid(%u), sub_cmd(%u), ret(%d).\n", dev_id, sub_cmd, ret);
return ret;
}
if (arg.commoninfo_len > *buf_size) {
DMS_ERR("actual data length(%u) larger than *ret_size(%u), devid(%u).\n",
arg.commoninfo_len, *buf_size, dev_id);
return DRV_ERROR_INVALID_VALUE;
}
ret = memcpy_s(out_buf, *buf_size, ddr_temp, sizeof(ddr_temp));
if (ret != 0) {
DMS_ERR("memcpy_s failed, devid(%u), ret(%d).\n", dev_id, ret);
return DRV_ERROR_INVALID_VALUE;
}
*buf_size = arg.commoninfo_len;
return DRV_ERROR_NONE;
}
STATIC int DmsGetTemperatureThreshold(unsigned int dev_id, unsigned int sub_cmd, void *out_buf, unsigned int *buf_size)
{
int ret;
unsigned int *temp_thold = (unsigned int *)out_buf;
struct ioctl_arg arg = {0};
unsigned int arg_size = sizeof(struct ioctl_arg);
if ((dev_id >= ASCEND_DEV_MAX_NUM) || (out_buf == NULL) || (buf_size == NULL)) {
DMS_ERR("DmsGetTemperatureThreshold para err, devid %d sub_cmd %d.\n", dev_id, sub_cmd);
return DRV_ERROR_INVALID_VALUE;
}
if (*buf_size != sizeof(unsigned int)) {
DMS_ERR("user len %d is not %ld\n", *buf_size, sizeof(unsigned int));
return DRV_ERROR_INVALID_VALUE;
}
if ((sub_cmd != DSMI_TEMP_SUB_CMD_DDR_THOLD) && (sub_cmd != DSMI_TEMP_SUB_CMD_SOC_THOLD)
&& (sub_cmd != DSMI_TEMP_SUB_CMD_SOC_MIN_THOLD)) {
DMS_ERR("DmsGetTemperatureThreshold sub_cmd %d err, devid %d.\n", sub_cmd, dev_id);
return DRV_ERROR_INVALID_VALUE;
}
arg.dev_id = dev_id;
arg.vfid = DMS_VF_ID_PF;
arg.type = DMS_LPM_SOC_ID;
ret = DmsGetDeviceInfo(dev_id, DMS_MAIN_CMD_TEMP, sub_cmd, (void *)&arg, &arg_size);
if (ret != 0) {
DMS_ERR("DmsGetDeviceInfo failed, devid(%u), sub_cmd(%u), ret(%d).\n", dev_id, sub_cmd, ret);
return ret;
}
*temp_thold = arg.data1;
*buf_size = (unsigned int)arg.data2;
return DRV_ERROR_NONE;
}
int DmsGetTemperature(unsigned int dev_id, unsigned int vfid, unsigned int sub_cmd, void *out_buf,
unsigned int *buf_size)
{
int ret;
(void)vfid;
switch (sub_cmd) {
case DSMI_SUB_CMD_TEMP_DDR:
ret = DmsGetDdrTemperature(dev_id, sub_cmd, out_buf, buf_size);
if (ret != 0) {
DMS_ERR("DmsGetDdrTemperature failed, devid(%u), ret(%d).\n", dev_id, ret);
return ret;
}
break;
case DSMI_TEMP_SUB_CMD_DDR_THOLD:
case DSMI_TEMP_SUB_CMD_SOC_THOLD:
case DSMI_TEMP_SUB_CMD_SOC_MIN_THOLD:
ret = DmsGetTemperatureThreshold(dev_id, sub_cmd, out_buf, buf_size);
if (ret != 0) {
DMS_ERR("DmsGetTemperatureThreshold failed, devid(%u), ret(%d).\n", dev_id, ret);
return ret;
}
break;
default:
return DRV_ERROR_NOT_SUPPORT;
}
return DRV_ERROR_NONE;
}
int DmsGetTempFromLp(unsigned int dev_id, unsigned int vfid, unsigned int sub_cmd, void *buf, unsigned int *size)
{
(void)vfid;
return DmsGetDeviceInfoEx(dev_id, DMS_MAIN_CMD_TEMP, sub_cmd, buf, size);
}
int DmsGetLowPowerInfo(unsigned int dev_id, unsigned int vfid, unsigned int sub_cmd, void *buf,
unsigned int *size)
{
(void)vfid;
int ret;
unsigned int flag = 0;
if (sub_cmd == DSMI_LP_SUB_CMD_GET_WORK_TOPS || sub_cmd == DSMI_LP_SUB_CMD_TOPS_DETAILS) {
ret = devdrv_get_host_phy_mach_flag(dev_id, &flag);
if (ret != 0) {
return DRV_ERROR_NOT_SUPPORT;
}
if (flag != DEVDRV_HOST_PHY_MACH_FLAG) {
return DRV_ERROR_NOT_SUPPORT;
}
}
return DmsGetDeviceInfoEx(dev_id, DMS_MAIN_CMD_LP, sub_cmd, buf, size);
}
int DmsSetLowPowerInfo(unsigned int dev_id, unsigned int sub_cmd, void *buf, unsigned int size)
{
return DmsSetDeviceInfoEx(dev_id, DMS_MAIN_CMD_LP, sub_cmd, buf, size);
}
#ifdef CFG_FEATURE_PASS_THROUGH_MCU_BY_IMU
int DmsLpmPassThroughMcu(unsigned char rw_flag, unsigned char *buf, unsigned char buf_len,
unsigned char *resp_buff, unsigned char *recv_len)
{
int ret;
unsigned int dev_id = 0;
struct dms_ioctl_arg ioarg = {0};
struct dms_pass_through_mcu_in in = {0};
struct dms_pass_through_mcu_out out = {0};
ret = drvGetLocalDevIDs(&dev_id, 1);
if (ret != DRV_ERROR_NONE) {
DMS_ERR("Get local device id failed. (ret=%d)\n", ret);
return ret;
}
if (buf == NULL || recv_len == NULL || resp_buff == NULL || dev_id >= ASCEND_DEV_MAX_NUM) {
DMS_ERR("Parameter is invalid. (dev_id=%u; buf_is_null=%d; resp_buff_is_null=%d; recv_len_is_null=%d)\n",
dev_id, (buf != NULL), (resp_buff != NULL), (recv_len != NULL));
return DRV_ERROR_INVALID_VALUE;
}
in.dev_id = dev_id;
in.rw_flag = rw_flag;
in.buf = buf;
in.buf_len = buf_len;
ioarg.main_cmd = DMS_MAIN_CMD_LPM;
ioarg.sub_cmd = DMS_SUBCMD_PASS_THROUGTH_MCU;
ioarg.filter_len = 0;
ioarg.input = (void *)∈
ioarg.input_len = sizeof(struct dms_pass_through_mcu_in);
ioarg.output = (void *)&out;
ioarg.output_len = sizeof(struct dms_pass_through_mcu_out);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
return ret;
}
if (!rw_flag) {
if (out.response_len > MCU_RESP_LEN) {
DMS_ERR("Response length invalid. (dev_id=%u; response_len=%d)\n", dev_id, out.response_len);
return DRV_ERROR_INVALID_HANDLE;
}
ret = memcpy_s(resp_buff, out.response_len, out.response_data, out.response_len);
if (ret != 0) {
DMS_ERR("Copy response data failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
*recv_len = 0;
return DRV_ERROR_OUT_OF_MEMORY;
}
*recv_len = (unsigned char)out.response_len;
}
return DRV_ERROR_NONE;
}
#endif
struct aicore_current_freq {
u32 dev_id;
u32 freq;
};
int dms_lpm_get_ai_core_curr_freq(unsigned int devId, void *buf, unsigned int *size)
{
int ret = 0;
struct dms_ioctl_arg ioarg = {0};
struct dms_lpm_info_in freq_in = {0};
unsigned int curr_freq = 0;
if (devId >= ASCEND_PDEV_MAX_NUM || buf == NULL || size == NULL) {
DMS_ERR("Invalid parameters. (dev_id=%u, buf%s, size%s)\n",
devId, buf == NULL ? "=NULL" : "!=NULL", size == NULL ? "=NULL" : "!=NULL");
return DRV_ERROR_INVALID_VALUE;
}
if (*size != sizeof(unsigned int)) {
DMS_ERR("Invalid parameters. (dev_id=%u, *size=%u)\n", devId, *size);
return DRV_ERROR_INVALID_VALUE;
}
#ifdef CFG_FEATURE_VDEVMNG_IN_VIRTUAL
struct aicore_current_freq freq_info = {0};
freq_info.dev_id = devId;
if (DmsGetVirtFlag() != 0) {
ret = dmanage_common_ioctl(DEVDRV_MANAGER_GET_CURRENT_AIC_FREQ, &freq_info);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Ioctl failed. (dev_id=%u; ret=%d; errno=%d)\n", devId, ret, errno);
return ret;
} else {
*(u32 *)buf = freq_info.freq;
*size = sizeof(u32);
}
return ret;
}
#endif
freq_in.dev_id = devId;
freq_in.core_id = AICORE0_ID;
ioarg.main_cmd = DMS_MAIN_CMD_LPM;
ioarg.sub_cmd = DMS_SUBCMD_GET_FREQUENCY;
ioarg.filter_len = 0;
ioarg.input = &freq_in;
ioarg.input_len = sizeof(struct dms_lpm_info_in);
ioarg.output = &curr_freq;
ioarg.output_len = sizeof(unsigned int);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "drvGetAiCoreCurrFreq failed. (dev_id=%u, ret=%d)", devId, ret);
return ret;
}
ret = memcpy_s(buf, *size, &curr_freq, sizeof(unsigned int));
if (ret != 0) {
DMS_ERR("memcpy_s failed. (dev_id=%u, ret=%d)\n", devId, ret);
return DRV_ERROR_PARA_ERROR;
}
return ret;
}