* 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.
*/
#ifndef UDA_DEV_H
#define UDA_DEV_H
#include "ka_base_pub.h"
#include "ka_task_pub.h"
#include "securec.h"
#include "uda_access.h"
#define UDA_STATUS_INIT_MASK (0x1 << 0)
#define UDA_STATUS_SUSPEND_MASK (0x1 << 1)
#define UDA_STATUS_MIA_MASK (0x1 << 2)
#define UDA_STATUS_HOT_RESET_MASK (0x1 << 3)
#define UDA_STATUS_REMOVED_MASK (0x1 << 4)
#define UDA_STATUS_PRE_HOT_RESET_MASK (0x1 << 5)
#define UDA_REORDER_GROUP_DEV_MAX_NUM 4
#define UDA_GUID_LEN 4
#define UDA_UDEVID_REORDER_WORK_FINISH 1
#define UDA_ALL_DEV_UP_WORK_FINISH 1
#define UDA_ENABLE_CHAR_NUMBERING 1
#ifdef CFG_FEATURE_CHAR_NUMBERING_BY_LOGIC_ID
# define UDA_WAIT_ALL_DEV_UP_FLAG true
#else
# define UDA_WAIT_ALL_DEV_UP_FLAG false
#endif
struct uda_dev_inst {
ka_kref_t ref;
u32 udevid;
u32 inst_id;
u32 status;
u32 agent_flag;
u32 action_para[UDA_ACTION_MAX];
struct uda_dev_type type;
struct uda_dev_para para;
struct uda_mia_dev_para mia_para;
struct uda_access access;
void *agent_dev;
};
struct uda_reorder_insts {
unsigned int udevid;
unsigned int logic_id;
unsigned int dev_add_num;
unsigned int wait_all_dev_work_state;
ka_work_struct_t wait_all_dev_work;
struct uda_dev_type dev_type;
struct uda_dev_para *dev_para;
ka_mutex_t work_mutex;
};
static inline bool uda_is_init_status(u32 status)
{
return ((status & UDA_STATUS_INIT_MASK) != 0);
}
static inline bool uda_is_suspend_status(u32 status)
{
return ((status & UDA_STATUS_SUSPEND_MASK) != 0);
}
static inline bool uda_is_mia_status(u32 status)
{
return ((status & UDA_STATUS_MIA_MASK) != 0);
}
static inline bool uda_is_hotreset_status(u32 status)
{
return ((status & UDA_STATUS_HOT_RESET_MASK) != 0);
}
static inline bool uda_is_pre_hotreset_status(u32 status)
{
return ((status & UDA_STATUS_PRE_HOT_RESET_MASK) != 0);
}
static inline bool uda_is_removed_status(u32 status)
{
return ((status & UDA_STATUS_REMOVED_MASK) != 0);
}
static inline bool uda_is_init_status_conflict(u32 status, enum uda_notified_action action)
{
return ((uda_is_init_status(status) && (action == UDA_INIT))
|| (!uda_is_init_status(status) && (action == UDA_UNINIT)));
}
static inline bool uda_is_suspend_status_conflict(u32 status, enum uda_notified_action action)
{
return ((uda_is_suspend_status(status) && (action == UDA_SUSPEND))
|| (!uda_is_suspend_status(status) && (action == UDA_RESUME)));
}
static inline bool uda_is_mia_status_conflict(u32 status, enum uda_notified_action action)
{
return ((uda_is_mia_status(status) && (action == UDA_TO_MIA))
|| (!uda_is_mia_status(status) && (action == UDA_TO_SIA)));
}
static inline bool uda_is_hotreset_status_conflict(u32 status, enum uda_notified_action action)
{
return ((uda_is_hotreset_status(status) && (action == UDA_HOTRESET))
|| (!uda_is_hotreset_status(status) && (action == UDA_HOTRESET_CANCEL)));
}
static inline bool uda_is_pre_hotreset_status_conflict(u32 status, enum uda_notified_action action)
{
return ((uda_is_pre_hotreset_status(status) && (action == UDA_PRE_HOTRESET))
|| (!uda_is_pre_hotreset_status(status) && (action == UDA_PRE_HOTRESET_CANCEL)));
}
static inline bool uda_is_action_conflict(u32 status, enum uda_notified_action action)
{
return (uda_is_init_status_conflict(status, action) || uda_is_suspend_status_conflict(status, action)
|| uda_is_mia_status_conflict(status, action) || uda_is_hotreset_status_conflict(status, action)
|| uda_is_pre_hotreset_status_conflict(status, action));
}
static inline void uda_update_status_by_action(u32 *status, enum uda_notified_action action)
{
if (action == UDA_INIT) {
*status = UDA_STATUS_INIT_MASK;
} else if (action == UDA_UNINIT) {
*status &= ~UDA_STATUS_INIT_MASK;
} else if (action == UDA_SUSPEND) {
*status |= UDA_STATUS_SUSPEND_MASK;
} else if (action == UDA_RESUME) {
*status &= ~UDA_STATUS_SUSPEND_MASK;
} else if (action == UDA_TO_MIA) {
*status |= UDA_STATUS_MIA_MASK;
} else if (action == UDA_TO_SIA) {
*status &= ~UDA_STATUS_MIA_MASK;
} else if (action == UDA_HOTRESET) {
*status |= UDA_STATUS_HOT_RESET_MASK;
} else if (action == UDA_HOTRESET_CANCEL) {
*status &= ~UDA_STATUS_HOT_RESET_MASK;
} else if (action == UDA_REMOVE) {
*status |= UDA_STATUS_REMOVED_MASK;
} else if (action == UDA_PRE_HOTRESET) {
*status |= UDA_STATUS_PRE_HOT_RESET_MASK;
} else if (action == UDA_PRE_HOTRESET_CANCEL) {
*status &= ~UDA_STATUS_PRE_HOT_RESET_MASK;
}
}
static inline int uda_dev_type_valid_check(struct uda_dev_type *type)
{
if ((type->hw < 0) || (type->hw >= UDA_HW_MAX) || (type->object < 0) || (type->object >= UDA_OBJECT_MAX)
|| (type->location < 0) || (type->location >= UDA_LOCATION_MAX)
|| (type->prop < 0) || (type->prop >= UDA_PROP_MAX)) {
uda_err("Invalid value. (hw=%d; object=%d; location=%d; prop=%d)\n",
type->hw, type->object, type->location, type->prop);
return -EINVAL;
}
return 0;
}
static inline bool uda_dev_type_is_match(struct uda_dev_type *type1, struct uda_dev_type *type2)
{
return ((type1->hw == type2->hw) && (type1->object == type2->object)
&& (type1->location == type2->location) && (type1->prop == type2->prop));
}
#define TYPE_BUF_LEN 64
void uda_type_to_string(struct uda_dev_type *type, char buf[], u32 buf_len);
static inline void uda_show_type(const char *reason, struct uda_dev_type *type)
{
char buf[TYPE_BUF_LEN];
uda_type_to_string(type, buf, TYPE_BUF_LEN);
uda_info("%s: %s\n", reason, buf);
}
struct uda_dev_inst *uda_dev_inst_get(u32 udevid);
struct uda_dev_inst *uda_dev_inst_get_ex(u32 udevid);
void uda_dev_inst_put(struct uda_dev_inst *dev_inst);
int uda_udevid_to_remote_udevid(u32 udevid, u32 *remote_udevid);
int uda_guid_compare(u32 *guid, u32 *other_guid);
void uda_module_id_sort(unsigned int start, unsigned int end);
int uda_dev_init(void);
void uda_dev_uninit(void);
u32 uda_get_dev_num_all(void);
u32 uda_get_dev_num_local(void);
#endif