* 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 NVME_CHAN_H
#define NVME_CHAN_H
#include <linux/types.h>
#include "ka_base_pub.h"
#include "ka_task_pub.h"
#include "ka_list_pub.h"
#include "ka_system_pub.h"
#include "pbl_kref_safe.h"
#include "trs_chan.h"
struct trs_chan_ts_inst;
struct trs_chan_irq_ctx {
struct trs_chan_ts_inst *ts_inst;
u32 irq_type;
u32 irq_index;
u32 irq;
u32 chan_num;
ka_task_spinlock_t lock;
ka_list_head_t chan_list;
ka_tasklet_struct_t task;
};
struct trs_chan_hw_sq_ctx {
int chan_id;
};
struct trs_chan_hw_cq_ctx {
int chan_id;
u32 irq_index;
bool valid;
};
struct trs_chan_maint_sq_ctx {
int chan_id;
};
struct trs_chan_maint_cq_ctx{
int chan_id;
};
#define TRS_CHAN_GUARD_WORK_DELAY_MS 100
#define TRS_CHAN_GUARD_WORK_MAGIC 0x9876CDEF
struct trs_chan_guard_work {
u32 work_magic;
ka_delayed_work_t cq_guard_work;
struct trs_chan_ts_inst *ts_inst;
};
struct trs_chan_ts_inst {
struct kref_safe ref;
ka_mutex_t mutex;
ka_idr_t chan_idr;
int hw_type;
u32 chan_num;
u32 maint_irq_num;
u32 normal_irq_num;
u32 sq_max_id;
u32 cq_max_id;
u32 maint_sq_max_id;
u32 maint_cq_max_id;
struct trs_id_inst inst;
struct trs_chan_adapt_ops ops;
struct trs_chan_irq_ctx *maint_irq;
struct trs_chan_irq_ctx *normal_irq;
struct trs_chan_hw_sq_ctx *hw_sq_ctx;
struct trs_chan_hw_cq_ctx *hw_cq_ctx;
struct trs_chan_maint_sq_ctx *maint_sq_ctx;
struct trs_chan_maint_cq_ctx *maint_cq_ctx;
struct trs_chan_guard_work guard_work;
ka_proc_dir_entry_t *entry;
bool trace_enable;
int location;
};
struct trs_chan_ts_inst *trs_chan_ts_inst_get(struct trs_id_inst *inst);
void trs_chan_ts_inst_put(struct trs_chan_ts_inst *ts_inst);
static inline int trs_chan_sq_to_chan_id(struct trs_chan_ts_inst *ts_inst, u32 sqid)
{
return (sqid < ts_inst->sq_max_id) ? ts_inst->hw_sq_ctx[sqid].chan_id : -1;
}
static inline int trs_chan_cq_to_chan_id(struct trs_chan_ts_inst *ts_inst, u32 cqid)
{
return (cqid < ts_inst->cq_max_id) ? ts_inst->hw_cq_ctx[cqid].chan_id : -1;
}
static inline int trs_chan_maint_sq_to_chan_id(struct trs_chan_ts_inst *ts_inst, u32 sqid)
{
return (sqid < ts_inst->maint_sq_max_id) ? ts_inst->maint_sq_ctx[sqid].chan_id : -1;
}
static inline int trs_chan_maint_cq_to_chan_id(struct trs_chan_ts_inst *ts_inst, u32 cqid)
{
return (cqid < ts_inst->maint_cq_max_id) ? ts_inst->maint_cq_ctx[cqid].chan_id : -1;
}
static inline bool trs_chan_trace_is_enabled(struct trs_chan_ts_inst *ts_inst)
{
return ts_inst->trace_enable;
}
#endif