* 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.
*/
#ifdef CONFIG_GENERIC_BUG
#undef CONFIG_GENERIC_BUG
#endif
#ifdef CONFIG_BUG
#undef CONFIG_BUG
#endif
#ifdef CONFIG_DEBUG_BUGVERBOSE
#undef CONFIG_DEBUG_BUGVERBOSE
#endif
#include "ka_task_pub.h"
#include "ka_memory_pub.h"
#include "ka_list_pub.h"
#include "ka_compiler_pub.h"
#include "hdcdrv_core.h"
#include "hdcdrv_mem.h"
ka_delayed_work_t *hdcdrv_get_recycle_mem(void)
{
return &(hdc_ctrl->recycle_mem);
}
ka_device_t* hdcdrv_get_pdev_dev(int dev_id)
{
if (hdc_ctrl->devices[dev_id].valid != HDCDRV_VALID) {
hdcdrv_err("Device is not ready. (dev_id=%d)\n", dev_id);
return NULL;
}
return hdc_ctrl->devices[dev_id].dev;
}
* 2 add/del -> sep -> ctrl.dev[id].lo/re
* 3 send/rx src & pm(fid == 0) -> uni -> ctrl.lo
* 4 send/rx/dma-dst -> sep -> ctrl.dev[id].lo/re
*/
struct hdcdrv_dev_fmem *hdcdrv_get_dev_fmem_uni(void)
{
return &(hdc_ctrl->fmem);
}
struct hdcdrv_dev_fmem *hdcdrv_get_dev_fmem_sep(int devid)
{
return &(hdc_ctrl->devices[devid].fmem);
}
void hdcdrv_iova_fmem_unmap(u32 dev_id, u32 fid, struct hdcdrv_fast_mem* f_mem, u32 num)
{
#ifdef CFG_FEATURE_VFIO
u32 i;
for (i = 0; i < num; i++) {
if (f_mem->mem[i].dma_sgt != NULL) {
vmngh_dma_unmap_guest_page(dev_id, fid, f_mem->mem[i].dma_sgt);
}
}
#endif
}
#ifdef CFG_FEATURE_VFIO
static void hdcdrv_iova_new_mem(u32 dev_id, u32 fid, u32 old_num, struct hdcdrv_mem_f old_mem[],
struct hdcdrv_mem_f new_mem[])
{
u32 i, j;
u32 num_new = 0;
ka_scatterlist_t *sgl = NULL;
u32 len_per_sgt;
for (i = 0; i < old_num; i++) {
sgl = old_mem[i].dma_sgt->sgl;
len_per_sgt = 0;
for (j = 0; j < old_mem[i].dma_sgt->nents; j++) {
if (sgl == NULL) {
break;
}
new_mem[num_new + j].addr = ka_mm_sg_dma_address(sgl) + (old_mem[i].addr & (KA_MM_PAGE_SIZE - 1));
new_mem[num_new + j].len = ka_mm_sg_dma_len(sgl);
new_mem[num_new + j].dma_sgt = (j == 0) ? (old_mem[i].dma_sgt) : (NULL);
len_per_sgt = len_per_sgt + new_mem[num_new + j].len;
sgl = ka_base_sg_next(sgl);
}
num_new = num_new + old_mem[i].dma_sgt->nents;
if (len_per_sgt != old_mem[i].len) {
hdcdrv_warn("sgt_len not match. (dev_id=%u; fid=%u; mem=%u; len=%u; sgt=%u)\n",
dev_id, fid, i, old_mem[i].len, len_per_sgt);
}
}
}
#endif
int hdcdrv_iova_fmem_map(u32 dev_id, u32 fid, struct hdcdrv_fast_mem* f_mem)
{
#ifdef CFG_FEATURE_VFIO
ka_dma_addr_t dma_addr;
u32 i, unmap_num;
int num_new;
struct hdcdrv_mem_f *new_mem = NULL;
u32 new_mem_size;
ka_sg_table_t *dma_sgt = NULL;
num_new = 0;
for (i = 0; i < (u32)f_mem->phy_addr_num; i++) {
dma_addr = vmngh_dma_map_guest_page(dev_id, fid, f_mem->mem[i].addr, f_mem->mem[i].len, &dma_sgt);
if ((dma_sgt == NULL) || (dma_addr == DMA_MAP_ERROR)) {
hdcdrv_err("Calling vmngh_dma_map_guest_page failed. (dev=%u; fid=%u)\n", dev_id, fid);
unmap_num = i;
goto map_fail;
}
if ((num_new + dma_sgt->nents) > HDCDRV_MEM_MAX_PHY_NUM) {
hdcdrv_err("New physic number too big. (dev=%u; fid=%u)\n", dev_id, fid);
unmap_num = i;
goto map_fail;
}
num_new = num_new + (int)dma_sgt->nents;
f_mem->mem[i].dma_sgt = dma_sgt;
}
new_mem_size = (u32)num_new * sizeof(struct hdcdrv_mem_f);
new_mem = hdcdrv_kvmalloc(new_mem_size, KA_SUB_MODULE_TYPE_2);
if (new_mem == NULL) {
unmap_num = (u32)f_mem->phy_addr_num;
hdcdrv_err("Calling alloc failed. (dev=%u; fid=%u)\n", dev_id, fid);
goto map_fail;
}
hdcdrv_iova_new_mem(dev_id, fid, (u32)f_mem->phy_addr_num, f_mem->mem, new_mem);
hdcdrv_kvfree((void **)&f_mem->mem, KA_SUB_MODULE_TYPE_2);
f_mem->mem = new_mem;
f_mem->phy_addr_num = num_new;
f_mem->dma_map = 1;
return HDCDRV_OK;
map_fail:
hdcdrv_iova_fmem_unmap(dev_id, fid, f_mem, unmap_num);
return HDCDRV_ERR;
#else
return HDCDRV_OK;
#endif
}
STATIC struct hdcdrv_mem_pool *get_pool(struct hdcdrv_dev *dev, int pool_type, u32 data_len)
{
struct hdcdrv_mem_pool *pool = NULL;
if (data_len <= (u32)(HDCDRV_SMALL_PACKET_SEGMENT - HDCDRV_MEM_BLOCK_HEAD_SIZE)) {
pool = &dev->small_mem_pool[pool_type];
} else {
pool = &dev->huge_mem_pool[pool_type];
}
return pool;
}
STATIC int alloc_mem_later(struct hdcdrv_mem_pool *pool, ka_list_head_t *wait_head)
{
int ret = HDCDRV_OK;
ka_task_spin_lock_bh(&pool->mem_lock);
if (pool->head == pool->tail) {
if (wait_head != NULL) {
if (wait_head->next == NULL) {
ka_list_add_tail(wait_head, &pool->wait_list);
}
}
#ifdef CFG_FEATURE_HDC_REG_MEM
hdcdrv_limit_exclusive(warn, HDCDRV_LIMIT_LOG_0x10B, "mem pool used up.\n");
#endif
ret = HDCDRV_DMA_MEM_ALLOC_FAIL;
}
ka_task_spin_unlock_bh(&pool->mem_lock);
return ret;
}
struct hdcdrv_mem_pool *find_mem_pool(int pool_type, int dev_id, int len)
{
struct hdcdrv_dev *dev = NULL;
#ifndef CFG_FEATURE_MIRROR
if (ka_unlikely((len > hdcdrv_mem_block_capacity()) || (len <= 0))) {
hdcdrv_err_limit("data len invalid. (len=%d, capacity=%d)\n", len, hdcdrv_mem_block_capacity());
return NULL;
}
#endif
dev = &hdc_ctrl->devices[dev_id];
if (dev->valid != HDCDRV_VALID) {
hdcdrv_err("Input parameter is error. (dev_id=%d)\n", dev_id);
return NULL;
}
return get_pool(dev, pool_type, (u32)len);
}
int alloc_mem(struct hdcdrv_mem_pool *pool, void **buf, ka_dma_addr_t *addr, u32 *offset, ka_list_head_t *wait_head)
{
int ret;
if (pool == NULL) {
hdcdrv_err("pool is invalid.\n");
return HDCDRV_ERR;
}
ret = alloc_mem_later(pool, wait_head);
if (ret != HDCDRV_OK) {
return ret;
}
ret = hdccom_alloc_mem(pool, buf, addr, offset);
if (ret != HDCDRV_OK) {
if (ret != HDCDRV_DMA_MEM_ALLOC_FAIL) {
hdcdrv_err("Alloc memory failed. (ret=%d)\n", ret);
}
return ret;
}
return HDCDRV_OK;
}
STATIC void hdcdrv_mem_avail(int pool_type, ka_list_head_t *target)
{
struct hdcdrv_msg_chan *msg_chan = NULL;
if (pool_type == HDCDRV_MEM_POOL_TYPE_RX) {
msg_chan = ka_list_entry(target, struct hdcdrv_msg_chan, wait_mem_list);
msg_chan->dbg_stat.hdcdrv_mem_avail1++;
hdcdrv_rx_msg_schedule_task(msg_chan);
}
}
STATIC void free_mem_notify(struct hdcdrv_mem_pool *pool, u32 type)
{
ka_list_head_t *list = NULL;
ka_task_spin_lock_bh(&pool->mem_lock);
if (!ka_list_empty_careful(&pool->wait_list)) {
list = pool->wait_list.next;
ka_list_del(list);
list->next = NULL;
list->prev = NULL;
hdcdrv_mem_avail((int)type, list);
}
ka_task_spin_unlock_bh(&pool->mem_lock);
}
void free_mem(void *buf)
{
struct hdcdrv_mem_block_head *block_head = NULL;
struct hdcdrv_mem_pool *pool = NULL;
int ret;
if (hdcdrv_mem_block_head_check(buf) != HDCDRV_OK) {
hdcdrv_err_spinlock("Block head check failed.\n");
return;
}
block_head = (struct hdcdrv_mem_block_head *)buf;
pool = get_pool(&hdc_ctrl->devices[block_head->devid], (int)block_head->type, block_head->size);
if (pool->ring == NULL) {
hdcdrv_warn_spinlock("Pool ring has freed.\n");
return;
}
ret = hdccom_free_mem(pool, buf);
if (ret != HDCDRV_OK) {
hdcdrv_err_spinlock("Calling free_mem failed. (pool_type=%d; device=%d; ret=%d)\n",
block_head->type, block_head->devid, ret);
return;
}
free_mem_notify(pool, block_head->type);
return;
}
int hdcdrv_map_reserve_mem(struct hdccom_mem_init *init_mem, int pool_type, u32 segment, u32 num)
{
u32 peer_id;
int ret = 0;
ret = hdcdrv_get_peer_id_by_devid((u32)init_mem->dev_id, &peer_id);
if (ret != 0) {
hdcdrv_err("devid adapt fail. (devid=%d)\n", init_mem->dev_id);
return HDCDRV_ERR;
}
ret = devdrv_get_reserve_mem_info(peer_id, &init_mem->reserve_mem_pa, &init_mem->reserve_mem_size);
if (ret != 0) {
hdcdrv_err("devdrv_get_reserve_mem_info failed. (pool_type=%d, devid=%d)\n", pool_type, init_mem->dev_id);
return HDCDRV_ERR;
}
if (pool_type == HDCDRV_RESERVE_MEM_POOL_TYPE_TX) {
init_mem->reserve_mem_size /= HDCDRV_RESERVE_MEM_POOL_TYPE_NUM;
} else if (pool_type == HDCDRV_RESERVE_MEM_POOL_TYPE_RX) {
init_mem->reserve_mem_pa += init_mem->reserve_mem_size / HDCDRV_RESERVE_MEM_POOL_TYPE_NUM;
init_mem->reserve_mem_size /= HDCDRV_RESERVE_MEM_POOL_TYPE_NUM;
}
if (init_mem->reserve_mem_size < (segment * num)) {
hdcdrv_err("Init reserve mem failed. (pool_type=%d; segment=%u; num=%u; size=0x%lx)\n", pool_type,
segment, num, init_mem->reserve_mem_size);
return HDCDRV_ERR;
}
init_mem->reserve_mem_va = ka_mm_ioremap_cache(init_mem->reserve_mem_pa, init_mem->reserve_mem_size);
if (init_mem->reserve_mem_va == NULL) {
hdcdrv_err("Calling ka_mm_ioremap failed. (pool_type=%d)\n", pool_type);
return HDCDRV_ERR;
}
init_mem->reserve_mem_dma_addr = devdrv_dma_map_resource(init_mem->dev, init_mem->reserve_mem_pa, segment * num,
KA_DMA_BIDIRECTIONAL, 0);
if (ka_mm_dma_mapping_error(init_mem->dev, init_mem->reserve_mem_dma_addr) != 0) {
hdcdrv_err("devdrv_dma_map_resource failed. (dev_id=%d; segment=%u)\n",
init_mem->dev_id, segment);
return HDCDRV_ERR;
}
return HDCDRV_OK;
}
void hdcdrv_unmap_reserve_mem(struct hdcdrv_mem_pool *pool, ka_device_t *dev)
{
if (pool->reserve_mem_dma_addr != (~(ka_dma_addr_t)0)) {
devdrv_dma_unmap_resource(dev, pool->reserve_mem_dma_addr, pool->reserve_mem_size,
KA_DMA_BIDIRECTIONAL, 0);
pool->reserve_mem_dma_addr = ~(ka_dma_addr_t)0;
}
if (pool->reserve_mem_va != NULL) {
ka_mm_iounmap(pool->reserve_mem_va);
pool->reserve_mem_va = NULL;
}
}
int alloc_mem_pool(int pool_type, int dev_id, u32 segment, u32 num)
{
struct hdcdrv_dev *hdc_dev = &hdc_ctrl->devices[dev_id];
struct hdcdrv_mem_pool *pool;
struct hdccom_mem_init init_mem = {0};
int ret;
if (num == 0) {
hdcdrv_warn("hdccom_init_mem_pool num is 0. (dev_id=%d; pool_type=%d)\n", dev_id, pool_type);
return HDCDRV_OK;
}
pool = get_pool(hdc_dev, pool_type, segment);
init_mem.dev = hdc_dev->dev;
init_mem.pool_type = pool_type;
init_mem.dev_id = dev_id;
init_mem.segment = segment;
init_mem.num = num;
init_mem.reserve_mem_dma_addr = ~(ka_dma_addr_t)0;
if ((init_mem.pool_type == HDCDRV_RESERVE_MEM_POOL_TYPE_TX) ||
(init_mem.pool_type == HDCDRV_RESERVE_MEM_POOL_TYPE_RX)) {
ret = hdcdrv_map_reserve_mem(&init_mem, pool_type, segment, num);
pool->reserve_mem_va = init_mem.reserve_mem_va;
pool->reserve_mem_dma_addr = init_mem.reserve_mem_dma_addr;
pool->reserve_mem_size = init_mem.reserve_mem_size;
if (ret != HDCDRV_OK) {
hdcdrv_err("Calling hdcdrv_reserve_mem_init failed. (dev_id=%d; pool_type=%d)\n", dev_id, pool_type);
return ret;
}
}
ret = hdccom_init_mem_pool(pool, &init_mem);
if (ret != HDCDRV_OK) {
hdcdrv_err("Calling hdccom_init_mem_pool failed. (dev_id=%d; pool_type=%d)\n", dev_id, pool_type);
return ret;
}
return HDCDRV_OK;
}
void free_mem_pool(int pool_type, int dev_id, u32 segment)
{
struct hdcdrv_dev *hdc_dev = &hdc_ctrl->devices[dev_id];
struct hdcdrv_mem_pool *pool = NULL;
int ret;
pool = get_pool(hdc_dev, pool_type, segment);
ret = hdccom_free_mem_pool(pool, hdc_dev->dev, segment);
if (ret != HDCDRV_OK) {
hdcdrv_err("Calling hdccom_free_mem_pool failed. (dev_id=%d; pool_type=%d; ret=%d)\n",
dev_id, pool_type, ret);
}
if ((pool_type == HDCDRV_RESERVE_MEM_POOL_TYPE_TX) ||
(pool_type == HDCDRV_RESERVE_MEM_POOL_TYPE_RX)) {
hdcdrv_unmap_reserve_mem(pool, hdc_dev->dev);
}
return;
}
int hdcdrv_mem_block_capacity(void)
{
#ifdef CFG_FEATURE_HDC_REG_MEM
return HDCDRV_SMALL_PACKET_SEGMENT - HDCDRV_MEM_BLOCK_HEAD_SIZE;
#else
return hdc_ctrl->segment - HDCDRV_MEM_BLOCK_HEAD_SIZE;
#endif
}
int hdcdrv_init_alloc_mem_pool(u32 dev_id, u32 small_packet_num, u32 huge_packet_num)
{
int ret;
ret = alloc_mem_pool(HDCDRV_MEM_POOL_TYPE_TX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT, small_packet_num);
if (ret != HDCDRV_OK) {
goto free_small_tx;
}
hdcdrv_set_time_stamp(&(hdcdrv_get_init_stamp_info()->alloc_mem_pool0));
ret = alloc_mem_pool(HDCDRV_MEM_POOL_TYPE_RX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT, small_packet_num);
if (ret != HDCDRV_OK) {
goto free_small_rx;
}
hdcdrv_set_time_stamp(&(hdcdrv_get_init_stamp_info()->alloc_mem_pool1));
ret = alloc_mem_pool(HDCDRV_MEM_POOL_TYPE_TX, (int)dev_id, (u32)hdc_ctrl->segment, huge_packet_num);
if (ret != HDCDRV_OK) {
goto free_huge_tx;
}
hdcdrv_set_time_stamp(&(hdcdrv_get_init_stamp_info()->alloc_mem_pool2));
ret = alloc_mem_pool(HDCDRV_MEM_POOL_TYPE_RX, (int)dev_id, (u32)hdc_ctrl->segment, huge_packet_num);
if (ret != HDCDRV_OK) {
goto free_huge_rx;
}
hdcdrv_set_time_stamp(&(hdcdrv_get_init_stamp_info()->alloc_mem_pool3));
return HDCDRV_OK;
free_huge_rx:
free_mem_pool(HDCDRV_MEM_POOL_TYPE_RX, (int)dev_id, (u32)hdc_ctrl->segment);
free_huge_tx:
free_mem_pool(HDCDRV_MEM_POOL_TYPE_TX, (int)dev_id, (u32)hdc_ctrl->segment);
free_small_rx:
free_mem_pool(HDCDRV_MEM_POOL_TYPE_RX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT);
free_small_tx:
free_mem_pool(HDCDRV_MEM_POOL_TYPE_TX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT);
return HDCDRV_ERR;
}
void hdcdrv_uninit_alloc_mem_pool(u32 dev_id)
{
free_mem_pool(HDCDRV_MEM_POOL_TYPE_RX, (int)dev_id, (u32)hdc_ctrl->segment);
free_mem_pool(HDCDRV_MEM_POOL_TYPE_TX, (int)dev_id, (u32)hdc_ctrl->segment);
free_mem_pool(HDCDRV_MEM_POOL_TYPE_RX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT);
free_mem_pool(HDCDRV_MEM_POOL_TYPE_TX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT);
}
int hdcdrv_init_reserve_mem_pool(u32 dev_id, u32 small_packet_num, u32 huge_packet_num)
{
int ret;
ret = alloc_mem_pool(HDCDRV_RESERVE_MEM_POOL_TYPE_TX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT, small_packet_num);
if (ret != HDCDRV_OK) {
goto free_reserve_tx;
}
hdcdrv_set_time_stamp(&(hdcdrv_get_init_stamp_info()->alloc_mem_pool0));
ret = alloc_mem_pool(HDCDRV_RESERVE_MEM_POOL_TYPE_RX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT, small_packet_num);
if (ret != HDCDRV_OK) {
goto free_reserve_rx;
}
hdcdrv_set_time_stamp(&(hdcdrv_get_init_stamp_info()->alloc_mem_pool1));
return HDCDRV_OK;
free_reserve_rx:
free_mem_pool(HDCDRV_RESERVE_MEM_POOL_TYPE_RX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT);
free_reserve_tx:
free_mem_pool(HDCDRV_RESERVE_MEM_POOL_TYPE_TX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT);
return HDCDRV_ERR;
}
void hdcdrv_uninit_reserve_mem_pool(u32 dev_id)
{
free_mem_pool(HDCDRV_RESERVE_MEM_POOL_TYPE_RX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT);
free_mem_pool(HDCDRV_RESERVE_MEM_POOL_TYPE_TX, (int)dev_id, HDCDRV_SMALL_PACKET_SEGMENT);
}
int hdcdrv_init_mem_pool(u32 dev_id)
{
int ret;
u32 small_packet_num = HDCDRV_SMALL_PACKET_NUM;
u32 huge_packet_num = HDCDRV_HUGE_PACKET_NUM;
if (hdcdrv_get_running_status() != HDCDRV_RUNNING_NORMAL) {
return HDCDRV_OK;
}
hdcdrv_get_mempool_size(&small_packet_num, &huge_packet_num);
#ifdef CFG_FEATURE_RESERVE_MEM_POOL
ret = hdcdrv_init_reserve_mem_pool(dev_id, small_packet_num, huge_packet_num);
#else
ret = hdcdrv_init_alloc_mem_pool(dev_id, small_packet_num, huge_packet_num);
#endif
if (ret != HDCDRV_OK) {
hdcdrv_err("hdcdrv_init_mem_pool failed.\n");
return HDCDRV_ERR;
}
hdcdrv_info("hdcdrv_init_mem_pool success.\n");
return HDCDRV_OK;
}
void hdcdrv_uninit_mem_pool(u32 dev_id)
{
if (hdcdrv_get_running_status() != HDCDRV_RUNNING_NORMAL) {
return;
}
#ifdef CFG_FEATURE_RESERVE_MEM_POOL
hdcdrv_uninit_reserve_mem_pool(dev_id);
#else
hdcdrv_uninit_alloc_mem_pool(dev_id);
#endif
hdcdrv_info("hdcdrv_uninit_mem_pool success.\n");
}
int hdcdrv_list_node_mem_alloc(struct hdcdrv_ctx *ctx, struct hdcdrv_mem_fd_list **new_node)
{
if ((ctx != NULL) && (ctx != HDCDRV_KERNEL_WITHOUT_CTX)) {
*new_node = (struct hdcdrv_mem_fd_list *)hdcdrv_kzalloc(sizeof(struct hdcdrv_mem_fd_list),
KA_GFP_KERNEL | __KA_GFP_ACCOUNT, KA_SUB_MODULE_TYPE_1);
if (*new_node == NULL) {
hdcdrv_err("Calling ka_mm_kzalloc failed.\n");
return HDCDRV_MEM_ALLOC_FAIL;
}
}
return HDCDRV_OK;
}
void hdcdrv_list_node_mem_free(void *ctx, struct hdcdrv_mem_fd_list *new_node)
{
if ((ctx != NULL) && ((struct hdcdrv_ctx *)ctx != HDCDRV_KERNEL_WITHOUT_CTX)) {
hdcdrv_kfree(new_node, KA_SUB_MODULE_TYPE_1);
}
}
long hdcdrv_fast_alloc_mem(struct hdcdrv_ctx *ctx, struct hdcdrv_cmd_alloc_mem *cmd)
{
long ret;
struct hdcdrv_fast_node *f_node = NULL;
struct hdcdrv_mem_fd_list *new_node = NULL;
ret = hdcdrv_list_node_mem_alloc(ctx, &new_node);
if (ret != HDCDRV_OK) {
return ret;
}
ret = hdccom_fast_alloc_mem((void *)ctx, cmd, &f_node);
if ((ret != HDCDRV_OK) || (f_node == NULL)) {
if (ret == HDCDRV_VA_UNMAP_FAILED) {
hdcdrv_bind_mem_ctx(&ctx->abnormal_ctx_fmem, f_node, new_node);
} else {
hdcdrv_list_node_mem_free((void *)ctx, new_node);
new_node = NULL;
}
hdcdrv_err("Calling alloc memory error. (dev=%d)\n", cmd->dev_id);
return ret;
}
if ((ctx != NULL) && (ctx != HDCDRV_KERNEL_WITHOUT_CTX)) {
hdcdrv_bind_mem_ctx(&ctx->ctx_fmem, f_node, new_node);
}
f_node->ctx = (void *)ctx;
return HDCDRV_OK;
}
bool hdcdrv_mem_is_notify(const struct hdcdrv_fast_mem *f_mem)
{
if ((f_mem->mem_type == HDCDRV_FAST_MEM_TYPE_RX_DATA) || (f_mem->mem_type == HDCDRV_FAST_MEM_TYPE_RX_CTRL)) {
return false;
}
return true;
}