* 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_base_pub.h"
#include "ka_fs_pub.h"
#include "ka_kernel_def_pub.h"
#include "pbl_feature_loader.h"
#include "securec.h"
#include "svm_task.h"
#include "svm_proc_fs.h"
#define SVM_PROC_TOP_NAME "svm"
#define SVM_PROC_FS_MODE 0444
#define SVM_PROC_NAME_LEN 64
static ka_proc_dir_entry_t *svm_top_entry = NULL;
static int svm_task_feature_show(ka_seq_file_t *seq, void *offset)
{
u64 priv = (u64)(uintptr_t)(ka_fs_get_seq_file_private(seq));
u32 udevid = (u32)(priv >> 32) & 0xffff;
u32 feature_id = (u32)(priv >> 48);
int tgid = (int)priv;
module_feature_auto_show_task(udevid, tgid, feature_id, seq);
return 0;
}
int svm_task_feature_open(ka_inode_t *inode, ka_file_t *file)
{
return ka_fs_single_open(file, svm_task_feature_show, ka_base_pde_data(inode));
}
static int svm_dev_feature_show(ka_seq_file_t *seq, void *offset)
{
u64 priv = (u64)(uintptr_t)(ka_fs_get_seq_file_private(seq));
u32 udevid = (u32)(priv >> 32);
u32 feature_id = (u32)priv;
module_feature_auto_show_dev(udevid, feature_id, seq);
return 0;
}
int svm_dev_feature_open(ka_inode_t *inode, ka_file_t *file)
{
return ka_fs_single_open(file, svm_dev_feature_show, ka_base_pde_data(inode));
}
static const ka_procfs_ops_t svm_task_feature = {
ka_fs_init_pf_owner(KA_THIS_MODULE) \
ka_fs_init_pf_open(svm_task_feature_open) \
ka_fs_init_pf_read(ka_fs_seq_read) \
ka_fs_init_pf_lseek(ka_fs_seq_lseek) \
ka_fs_init_pf_release(ka_fs_single_release) \
};
static const ka_procfs_ops_t svm_dev_feature = {
ka_fs_init_pf_owner(KA_THIS_MODULE) \
ka_fs_init_pf_open(svm_dev_feature_open) \
ka_fs_init_pf_read(ka_fs_seq_read) \
ka_fs_init_pf_lseek(ka_fs_seq_lseek) \
ka_fs_init_pf_release(ka_fs_single_release) \
};
ka_proc_dir_entry_t *svm_proc_fs_add_task(u32 udevid, ka_proc_dir_entry_t *dev_entry, int tgid, u32 task_id)
{
char name[SVM_PROC_NAME_LEN];
(void)sprintf_s(name, SVM_PROC_NAME_LEN, "task-%d_id-%u", tgid, task_id);
return ka_fs_proc_mkdir(name, dev_entry);
}
void svm_proc_fs_del_task(ka_proc_dir_entry_t *task_entry)
{
if (task_entry != NULL) {
ka_fs_proc_remove(task_entry);
}
}
void svm_proc_task_add_feature(u32 udevid, int tgid, ka_proc_dir_entry_t *task_entry,
u32 feature_id, const char *feature_name)
{
u64 priv = (u32)tgid | ((u64)(udevid) << 32) | ((u64)(feature_id) << 48);
(void)ka_fs_proc_create_data(feature_name, SVM_PROC_FS_MODE, task_entry, &svm_task_feature, (void *)(uintptr_t)priv);
}
ka_proc_dir_entry_t *svm_proc_fs_add_dev(u32 udevid, u32 inst)
{
char name[SVM_PROC_NAME_LEN];
if (svm_top_entry == NULL) {
return NULL;
}
(void)sprintf_s(name, SVM_PROC_NAME_LEN, "dev-%u_inst-%u", udevid, inst);
return ka_fs_proc_mkdir(name, svm_top_entry);
}
void svm_proc_fs_del_dev(ka_proc_dir_entry_t *dev_entry)
{
if (dev_entry != NULL) {
ka_fs_proc_remove(dev_entry);
}
}
void svm_proc_dev_add_feature(u32 udevid, ka_proc_dir_entry_t *dev_entry, u32 feature_id, const char *feature_name)
{
u64 priv = (u32)feature_id | ((u64)(udevid) << 32);
(void)ka_fs_proc_create_data(feature_name, SVM_PROC_FS_MODE, dev_entry, &svm_dev_feature, (void *)(uintptr_t)priv);
}
int svm_proc_fs_init(void)
{
svm_top_entry = ka_fs_proc_mkdir(SVM_PROC_TOP_NAME, NULL);
return 0;
}
void svm_proc_fs_uninit(void)
{
if (svm_top_entry != NULL) {
ka_fs_remove_proc_subtree(SVM_PROC_TOP_NAME, NULL);
svm_top_entry = NULL;
}
}