* 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 "apm_ioctl.h"
static void drv_fill_bind_para(struct apm_cmd_bind *para, struct drvBindHostpidInfo *info)
{
para->devid = info->chip_id;
para->proc_type = (int)info->cp_type;
para->mode = info->mode;
para->master_pid = info->host_pid;
(void)memcpy_s(¶->slave_pid, sizeof(int), info->sign, sizeof(int));
if (para->slave_pid == 0) {
para->slave_pid = getpid();
}
}
drvError_t drvBindHostPid(struct drvBindHostpidInfo info)
{
struct apm_cmd_bind para;
int ret;
if ((info.len != PROCESS_SIGN_LENGTH) || (info.vfid != 0)) {
apm_err("Invalid param. (sig_len=%u; proc_type=%d; vfid=%d)\n", info.len, (int)info.cp_type, info.vfid);
return DRV_ERROR_PARA_ERROR;
}
drv_fill_bind_para(¶, &info);
ret = apm_cmd_ioctl(APM_BIND, ¶);
if (ret != 0) {
apm_err("Bind pid fail. (ret=%d; devid=%u; master_pid=%d; proc_type=%d; mode=%d)\n",
ret, para.devid, para.master_pid, para.proc_type, para.mode);
return ret;
}
return DRV_ERROR_NONE;
}
drvError_t drvUnbindHostPid(struct drvBindHostpidInfo info)
{
struct apm_cmd_bind para;
int ret;
if ((info.len != PROCESS_SIGN_LENGTH) || (info.vfid != 0)) {
apm_err("Invalid param. (sig_len=%u; proc_type=%d; vfid=%d)\n", info.len, (int)info.cp_type, info.vfid);
return DRV_ERROR_PARA_ERROR;
}
drv_fill_bind_para(¶, &info);
ret = apm_cmd_ioctl(APM_UNBIND, ¶);
if (ret != 0) {
apm_err("Unbind pid fail. (ret=%d; devid=%u; master_pid=%d; proc_type=%d)\n",
ret, para.devid, para.master_pid, para.proc_type);
return ret;
}
return DRV_ERROR_NONE;
}
static inline int apm_trans_first_proc_type_from_bitmap(unsigned int proc_type_bitmap)
{
int proc_type;
for (proc_type = 0; proc_type < PROCESS_CPTYPE_MAX; proc_type++) {
if ((proc_type_bitmap & (unsigned int)(0x1 << proc_type)) != 0) {
break;
}
}
return proc_type;
}
int apm_query_master_pid(unsigned int cmd, int slave_pid,
unsigned int *udevid, unsigned int *master_pid, unsigned int *proc_type)
{
struct apm_cmd_query_master_info para = {.slave_pid = (unsigned int)slave_pid};
int ret;
if (cmd == APM_QUERY_MASTER_INFO_BY_DEVICE_SLAVE) {
para.udevid = *udevid;
}
ret = apm_cmd_ioctl(cmd, ¶);
if (ret != 0) {
apm_warn("Query bindpid warn. (ret=%d; slave_pid=%d)\n", ret, slave_pid);
return ret;
}
if (udevid != NULL) {
*udevid = para.udevid;
}
if (master_pid != NULL) {
*master_pid = (unsigned int)para.master_pid;
}
if (proc_type != NULL) {
*proc_type = (unsigned int)apm_trans_first_proc_type_from_bitmap(para.proc_type_bitmap);
}
return DRV_ERROR_NONE;
}
drvError_t drvQueryProcessHostPid(int pid, unsigned int *chip_id, unsigned int *vfid,
unsigned int *host_pid, unsigned int *cp_type)
{
if (vfid != NULL) {
*vfid = 0;
}
return apm_query_master_pid(APM_QUERY_MASTER_INFO, pid, chip_id, host_pid, cp_type);
}
int halQueryMasterPidByDeviceSlave(unsigned int devid, int slave_pid, unsigned int *master_pid, unsigned int *proc_type)
{
return apm_query_master_pid(APM_QUERY_MASTER_INFO_BY_DEVICE_SLAVE, slave_pid, &devid, master_pid, proc_type);
}
int halQueryMasterPidByHostSlave(int slave_pid, unsigned int *udevid, unsigned int *master_pid, unsigned int *proc_type)
{
return apm_query_master_pid(APM_QUERY_MASTER_INFO_BY_HOST_SLAVE, slave_pid, udevid, master_pid, proc_type);
}