* 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 "securec.h"
#include "ascend_hal.h"
#include "dms/dms_devdrv_info_comm.h"
#include "dms_user_common.h"
#include "pbl_urd_sub_cmd_common.h"
#include "ascend_dev_num.h"
#include "udis_user.h"
#ifdef STATIC_SKIP
#define STATIC
#else
#define STATIC static
#endif
STATIC int udis_check_is_vdev(unsigned int dev_id, unsigned int *vdev_flag)
{
int ret;
unsigned int physical_id = 0;
unsigned int split_mode = 0;
unsigned int container_flag = 0;
#ifdef CFG_EDGE_HOST
(void) physical_id;
ret = halGetDeviceSplitMode(dev_id, &split_mode);
if (ret != 0) {
DMS_ERR("Get split mode failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
if ((split_mode == 0) || (split_mode == VMNG_VIRTUAL_SPLIT_MODE)) {
*vdev_flag = (split_mode == 0 ? 0 : 1);
return 0;
}
ret = dmanage_get_container_flag(&container_flag);
if (ret != 0) {
DMS_ERR("Get container flag failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
*vdev_flag = ((container_flag == 0 && dev_id < ASCEND_PDEV_MAX_NUM )? 0 : 1);
#else
(void) split_mode;
(void) container_flag;
ret = drvDeviceGetPhyIdByIndex(dev_id, &physical_id);
if (ret != 0) {
DMS_ERR("Get physical_id failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
*vdev_flag = (physical_id >= ASCEND_PDEV_MAX_NUM ? 1 : 0);
#endif
return 0;
}
STATIC int udis_is_supported(unsigned int dev_id)
{
int ret;
halChipInfo chip_info = {{0}, {0}, {0}};
const char *chip_type = "Ascend";
const char *cloud_v3_name = "910_93";
unsigned int vdev_flag = 0;
ret = halGetChipInfo(dev_id, &chip_info);
if (ret != 0) {
DMS_ERR("Get chip info failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
if (strncmp((const char *)chip_info.type, chip_type, strlen(chip_type)) != 0) {
return DRV_ERROR_NOT_SUPPORT;
}
if (strncmp((const char *)chip_info.name, cloud_v3_name, strlen(cloud_v3_name)) != 0) {
return 0;
}
ret = udis_check_is_vdev(dev_id, &vdev_flag);
if (ret != 0) {
DMS_ERR("Get vdev flag failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
if (vdev_flag == 1) {
return DRV_ERROR_NOT_SUPPORT;
}
return 0;
}
STATIC int udis_input_check(unsigned int dev_id, const struct udis_dev_info *info)
{
size_t name_len = 0;
if (info == NULL) {
DMS_ERR("Invalid para. info is NULL (dev_id=%u)\n", dev_id);
return DRV_ERROR_PARA_ERROR;
}
if (info->module_type >= UDIS_MODULE_MAX) {
DMS_ERR("Invalid module type. (dev_id=%u; module_type=%d; max_module_type=%u)\n",
dev_id, info->module_type, UDIS_MODULE_MAX - 1);
return DRV_ERROR_PARA_ERROR;
}
name_len = strnlen(info->name, UDIS_MAX_NAME_LEN);
if ((name_len == 0) || (name_len >= UDIS_MAX_NAME_LEN)) {
DMS_ERR("Invalid para, name length invalid. (dev_id=%u; module_type=%u; name_len=%u; max_name_len=%u)\n",
dev_id, info->module_type, name_len, UDIS_MAX_NAME_LEN - 1);
return DRV_ERROR_PARA_ERROR;
}
return 0;
}
int udis_get_device_info(unsigned int dev_id, struct udis_dev_info *info)
{
int ret = 0;
struct urd_cmd cmd = {0};
struct urd_cmd_para cmd_para = {0};
struct udis_get_ioctl_in in = {0};
struct udis_get_ioctl_out out = {0};
ret = udis_is_supported(dev_id);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Udis support check failed. (dev_id=%u; ret=%d)", dev_id, ret);
return ret;
}
ret = udis_input_check(dev_id, info);
if (ret != 0) {
return ret;
}
in.module_type = info->module_type;
ret = strcpy_s(in.name, UDIS_MAX_NAME_LEN, info->name);
if (ret != 0) {
DMS_ERR("Failed to copy info name, (dev_id=%u)\n", dev_id);
return DRV_ERROR_PARA_ERROR;
}
in.data = info->data;
in.in_len = sizeof(info->data);
urd_usr_cmd_fill(&cmd, DMS_MAIN_CMD_BASIC, DMS_SUBCMD_GET_UDIS_DEVICE_INFO, NULL, 0);
urd_usr_cmd_para_fill(&cmd_para, (void*)&in, sizeof(struct udis_get_ioctl_in),
&out, sizeof(struct udis_get_ioctl_out));
ret = urd_dev_usr_cmd(dev_id, &cmd, &cmd_para);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Get info from udis failed. (dev_id=%u; module_type=%u; name=%s; ret=%d)",
dev_id, info->module_type, info->name, ret);
return ret;
}
info->data_len = out.out_len;
info->acc_ctrl = out.acc_ctrl;
info->last_update_time = out.last_update_time;
return 0;
}
int udis_set_device_info(unsigned int dev_id, const struct udis_dev_info *info)
{
int ret = 0;
struct urd_cmd cmd = {0};
struct urd_cmd_para cmd_para = {0};
struct udis_set_ioctl_in in = {0};
ret = udis_is_supported(dev_id);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Udis support check failed. (dev_id=%u; ret=%d)", dev_id, ret);
return ret;
}
ret = udis_input_check(dev_id, info);
if (ret != 0) {
return ret;
}
if ((info->data_len == 0) || (info->data_len > UDIS_MAX_DATA_LEN)) {
DMS_ERR("Invalid data len. (dev_id=%u; module_type=%u; name=%s; data_len=%u; max_data_len=%u)\n",
dev_id, info->module_type, info->name, info->data_len, UDIS_MAX_DATA_LEN);
return DRV_ERROR_PARA_ERROR;
}
in.module_type = info->module_type;
ret = strcpy_s(in.name, UDIS_MAX_NAME_LEN, info->name);
if (ret != 0) {
DMS_ERR("Failed to copy info name, (dev_id=%u)\n", dev_id);
return DRV_ERROR_PARA_ERROR;
}
in.data = info->data;
in.data_len = info->data_len;
in.acc_ctrl = info->acc_ctrl;
urd_usr_cmd_fill(&cmd, DMS_MAIN_CMD_BASIC, DMS_SUBCMD_SET_UDIS_DEVICE_INFO, NULL, 0);
urd_usr_cmd_para_fill(&cmd_para, (void *)&in, sizeof(struct udis_set_ioctl_in), NULL, 0);
ret = urd_dev_usr_cmd(dev_id, &cmd, &cmd_para);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Set info from udis failed. (dev_id=%u; module_type=%u; name=%s; ret=%d)",
dev_id, info->module_type, info->name, ret);
return ret;
}
DMS_INFO("Set udis info success. (dev_id=%u; module_type=%u; name=%s)\n",
dev_id, info->module_type, info->name);
return 0;
}