blob: 6e4baa28ea6b798c297e909309a506a64ae5703f [file] [log] [blame]
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* drivers/amlogic/media/di_multi/di_que.c
*
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 <linux/kernel.h>
#include <linux/err.h>
#include <linux/seq_file.h>
#include <linux/kfifo.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include "deinterlace.h"
#include "di_data_l.h"
#include "di_que.h"
#include "di_vframe.h"
#include "di_sys.h"
#include "di_prc.h"
const char * const di_name_new_que[QUE_NUB] = {
"QUE_IN_FREE", /*0*/
"QUE_PRE_READY", /*1*/
"QUE_POST_FREE", /*2*/
"QUE_POST_READY", /*3*/
"QUE_POST_BACK", /*4*/
"QUE_POST_DOING",
// "QUE_POST_KEEP",
// "QUE_POST_KEEP_BACK",
"QUE_DBG",
/* "QUE_NUB",*/
};
#define que_dbg dim_print
void pw_queue_clear(unsigned int ch, enum QUE_TYPE qtype)
{
struct di_ch_s *pch = get_chdata(ch);
#ifdef MARK_HIS
if (qtype >= QUE_NUB)
return;
#endif
kfifo_reset(&pch->fifo[qtype]);
}
bool pw_queue_in(unsigned int ch, enum QUE_TYPE qtype, unsigned int buf_index)
{
struct di_ch_s *pch = get_chdata(ch);
#ifdef MARK_HIS
if (qtype >= QUE_NUB)
return false;
#endif
if (kfifo_in(&pch->fifo[qtype], &buf_index, sizeof(unsigned int))
!= sizeof(unsigned int))
return false;
#ifdef MARK_HIS
/*below for debug: save in que*/
if (qtype <= QUE_POST_RECYC) {
if (buf_index >= MAX_POST_BUF_NUM) {
pr_err("%s:err:overflow?[%d]\n", __func__, buf_index);
} else {
ppw = &pch->lpost_buf[buf_index];
ppw->in_qtype = qtype;
}
}
#endif
return true;
}
bool pw_queue_out(unsigned int ch, enum QUE_TYPE qtype,
unsigned int *buf_index)
{
struct di_ch_s *pch = get_chdata(ch);
unsigned int index;
#ifdef MARK_HIS
if (qtype >= QUE_NUB)
return false;
#endif
if (kfifo_out(&pch->fifo[qtype], &index, sizeof(unsigned int))
!= sizeof(unsigned int)) {
PR_ERR("%s:ch[%d],qtye[%d],buf[%d]\n",
__func__, ch, qtype, *buf_index);
return false;
}
*buf_index = index;
return true;
}
static bool pw_queue_peek(unsigned int ch, enum QUE_TYPE qtype,
unsigned int *buf_index)
{
struct di_ch_s *pch = get_chdata(ch);
unsigned int index;
#ifdef MARK_HIS
if (qtype >= QUE_NUB)
return false;
#endif
if (kfifo_out_peek(&pch->fifo[qtype], &index, sizeof(unsigned int))
!= sizeof(unsigned int))
return false;
*buf_index = index;
return true;
}
bool pw_queue_move(unsigned int ch, enum QUE_TYPE qtypef, enum QUE_TYPE qtypet,
unsigned int *oindex)
{
struct di_ch_s *pch = get_chdata(ch);
unsigned int index;
/*struct di_post_buf_s *ppw;*/ /*debug only*/
#ifdef MARK_HIS
if (qtypef >= QUE_NUB || qtypet >= QUE_NUB)
return false;
#endif
if (kfifo_out(&pch->fifo[qtypef], &index, sizeof(unsigned int))
!= sizeof(unsigned int)) {
PR_ERR("qtypef[%d] is empty\n", qtypef);
return false;
}
if (kfifo_in(&pch->fifo[qtypet], &index, sizeof(unsigned int))
!= sizeof(unsigned int)) {
PR_ERR("qtypet[%d] is full\n", qtypet);
return false;
}
*oindex = index;
#ifdef MARK_HIS
if (qtypet <= QUE_POST_RECYC) {
/*below for debug: save in que*/
if (index >= MAX_POST_BUF_NUM) {
pr_err("%s:err:overflow?[%d]\n", __func__, index);
} else {
ppw = &pch->lpost_buf[index];
ppw->in_qtype = qtypet;
}
}
#endif
return true;
}
bool pw_queue_empty(unsigned int ch, enum QUE_TYPE qtype)
{
struct di_ch_s *pch = get_chdata(ch);
if (kfifo_is_empty(&pch->fifo[qtype]))
return true;
return false;
}
/**********************************************************
*
**********************************************************/
int di_que_list_count(unsigned int ch, enum QUE_TYPE qtype)
{
struct di_ch_s *pch = get_chdata(ch);
unsigned int length;
#ifdef MARK_HIS
if (qtype >= QUE_NUB)
return -1;
#endif
length = kfifo_len(&pch->fifo[qtype]);
length = length / sizeof(unsigned int);
return length;
}
/***************************************/
/*outbuf : array size MAX_FIFO_SIZE*/
/***************************************/
bool di_que_list(unsigned int ch, enum QUE_TYPE qtype, unsigned int *outbuf,
unsigned int *rsize)
{
struct di_ch_s *pch = get_chdata(ch);
/* unsigned int tmp[MAX_FIFO_SIZE + 1];*/
int i;
unsigned int index;
bool ret = false;
/*que_dbg("%s:begin\n", __func__);*/
for (i = 0; i < MAX_FIFO_SIZE; i++)
outbuf[i] = 0xff;
if (kfifo_is_empty(&pch->fifo[qtype])) {
que_dbg("\t%d:empty\n", qtype);
*rsize = 0;
return true;
}
ret = true;
memcpy(&pch->fifo[QUE_DBG], &pch->fifo[qtype],
sizeof(pch->fifo[qtype]));
#ifdef MARK_HIS
if (kfifo_is_empty(&pbm->fifo[QUE_DBG]))
pr_err("%s:err, kfifo can not copy?\n", __func__);
#endif
i = 0;
*rsize = 0;
while (kfifo_out(&pch->fifo[QUE_DBG], &index, sizeof(unsigned int))
== sizeof(unsigned int)) {
outbuf[i] = index;
/*pr_info("%d->%d\n",i,index);*/
i++;
}
*rsize = di_que_list_count(ch, qtype);
#ifdef MARK_HIS /*debug only*/
que_dbg("%s: size[%d]\n", di_name_new_que[qtype], *rsize);
for (i = 0; i < *rsize; i++)
que_dbg("%d,", outbuf[i]);
que_dbg("\n");
#endif
/*que_dbg("finish\n");*/
return ret;
}
int di_que_is_empty(unsigned int ch, enum QUE_TYPE qtype)
{
struct di_ch_s *pch = get_chdata(ch);
#ifdef MARK_HIS
if (qtype >= QUE_NUB)
return -1;
#endif
return kfifo_is_empty(&pch->fifo[qtype]);
}
void di_que_init(unsigned int ch)
{
int i;
struct di_ch_s *pch = get_chdata(ch);
for (i = 0; i < QUE_NUB; i++) {
if (// i == QUE_POST_KEEP ||
// i == QUE_POST_KEEP_BACK ||
i == QUE_POST_KEEP_RE_ALLOC)
continue;
pw_queue_clear(ch, i);
}
bufq_mem_clear(pch);
}
bool di_que_alloc(unsigned int ch)
{
int i;
int ret;
bool flg_err;
struct di_ch_s *pch = get_chdata(ch);
/*kfifo----------------------------*/
flg_err = 0;
for (i = 0; i < QUE_NUB; i++) {
ret = kfifo_alloc(&pch->fifo[i],
sizeof(unsigned int) * MAX_FIFO_SIZE,
GFP_KERNEL);
if (ret < 0) {
flg_err = 1;
PR_ERR("%s:%d:can't get kfifo\n", __func__, i);
break;
}
pch->flg_fifo[i] = 1;
}
#ifdef MARK_HIS /*canvas-----------------------------*/
canvas_alloc();
#endif
/* pdp_clear();*/
if (!flg_err) {
/*pbm->flg_fifo = 1;*/
dbg_reg("%s:ok\n", __func__);
ret = true;
} else {
di_que_release(ch);
ret = false;
}
return ret;
}
void di_que_release(unsigned int ch)
{
struct di_ch_s *pch = get_chdata(ch);
int i;
/* canvas_release();*/
for (i = 0; i < QUE_NUB; i++) {
if (pch->flg_fifo[i]) {
kfifo_free(&pch->fifo[i]);
pch->flg_fifo[i] = 0;
}
}
pr_info("%s:ok\n", __func__);
}
/********************************************
*get di_buf from index that same in que
* (di_buf->type << 8) | (di_buf->index)
********************************************/
struct di_buf_s *pw_qindex_2_buf(unsigned int ch, unsigned int qindex)
{
union UDI_QBUF_INDEX index;
struct di_buf_s *di_buf;
struct di_buf_pool_s *pbuf_pool = get_buf_pool(ch);
index.d32 = qindex;
di_buf = &pbuf_pool[index.b.type - 1].di_buf_ptr[index.b.index];
return di_buf;
}
/********************************************/
/*get di_buf from index that same in que*/
/*(di_buf->type << 8) | (di_buf->index)*/
/********************************************/
static unsigned int pw_buf_2_qindex(unsigned int ch, struct di_buf_s *pdi_buf)
{
union UDI_QBUF_INDEX index;
index.b.index = pdi_buf->index;
index.b.type = pdi_buf->type;
return index.d32;
}
/*di_buf is out*/
struct di_buf_s *di_que_out_to_di_buf(unsigned int ch, enum QUE_TYPE qtype)
{
unsigned int q_index;
struct di_buf_s *pdi_buf = NULL;
if (!pw_queue_peek(ch, qtype, &q_index)) {
PR_ERR("%s:ch[%d]no buf\n", __func__, ch);
return pdi_buf;
}
pdi_buf = pw_qindex_2_buf(ch, q_index);
if (!pdi_buf) {
PR_ERR("%s:ch[%d]buf is null[0x%x]\n", __func__, ch, q_index);
return NULL;
}
pw_queue_out(ch, qtype, &q_index);
pdi_buf->queue_index = -1;
return pdi_buf;
}
/*di_buf is input*/
bool di_que_out(unsigned int ch, enum QUE_TYPE qtype, struct di_buf_s *di_buf)
{
unsigned int q_index;
unsigned int q_index2;
if (!pw_queue_peek(ch, qtype, &q_index)) {
PR_ERR("%s:no buf ch[%d], qtype[%d], buf[%d,%d]\n", __func__,
ch, qtype, di_buf->type, di_buf->index);
return false;
}
q_index2 = pw_buf_2_qindex(ch, di_buf);
if (q_index2 != q_index) {
PR_ERR("di:%s:%d not map[0x%x,0x%x]\n", __func__,
qtype, q_index2, q_index);
return false;
}
pw_queue_out(ch, qtype, &q_index);
di_buf->queue_index = -1;
return true;
}
bool di_que_in(unsigned int ch, enum QUE_TYPE qtype, struct di_buf_s *di_buf)
{
unsigned int q_index;
if (!di_buf) {
PR_ERR("di:%s:err:di_buf is NULL,ch[%d],qtype[%d]\n",
__func__, ch, qtype);
return false;
}
if (di_buf->queue_index != -1) {
PR_ERR("%s:buf in some que,ch[%d],qt[%d],qi[%d],bi[%d]\n",
__func__,
ch, qtype, di_buf->queue_index, di_buf->index);
dump_stack();
di_buf->queue_index = -1;
}
q_index = pw_buf_2_qindex(ch, di_buf);
if (!pw_queue_in(ch, qtype, q_index)) {
PR_ERR("%s:can't que in,ch[%d],qtype[%d],q_index[%d]\n",
__func__,
ch, qtype, q_index);
return false;
}
di_buf->queue_index = qtype + QUEUE_NUM;
if (qtype == QUE_PRE_READY)
dim_print("di:pre_ready in %d\n", di_buf->index);
return true;
}
bool di_que_is_in_que(unsigned int ch, enum QUE_TYPE qtype,
struct di_buf_s *di_buf)
{
unsigned int q_index;
unsigned int arr[MAX_FIFO_SIZE + 1];
unsigned int asize = 0;
bool ret = false;
unsigned int i;
if (!di_buf)
return false;
q_index = pw_buf_2_qindex(ch, di_buf);
di_que_list(ch, qtype, &arr[0], &asize);
if (asize == 0)
return ret;
for (i = 0; i < asize; i++) {
if (arr[i] == q_index) {
ret = true;
break;
}
}
return ret;
}
/* clear and rebuild que*/
bool di_que_out_not_fifo(unsigned int ch, enum QUE_TYPE qtype,
struct di_buf_s *di_buf)
{
unsigned int q_index;
unsigned int arr[MAX_FIFO_SIZE + 1];
unsigned int asize = 0;
unsigned int i;
bool ret = false;
if (!pw_queue_peek(ch, qtype, &q_index))
return false;
q_index = pw_buf_2_qindex(ch, di_buf);
di_que_list(ch, qtype, &arr[0], &asize);
pw_queue_clear(ch, qtype);
if (asize == 0) {
PR_ERR("%s:size 0\n", __func__);
return ret;
}
for (i = 0; i < asize; i++) {
if (arr[i] == q_index) {
ret = true;
di_buf->queue_index = -1;
continue;
}
pw_queue_in(ch, qtype, arr[i]);
}
return ret;
}
/*same as get_di_buf_head*/
struct di_buf_s *di_que_peek(unsigned int ch, enum QUE_TYPE qtype)
{
struct di_buf_s *di_buf = NULL;
unsigned int q_index;
if (!pw_queue_peek(ch, qtype, &q_index))
return di_buf;
di_buf = pw_qindex_2_buf(ch, q_index);
return di_buf;
}
bool di_que_type_2_new(unsigned int q_type, enum QUE_TYPE *nqtype)
{
if (!F_IN(q_type, QUEUE_NEW_THD_MIN, QUEUE_NEW_THD_MAX))
return false;
*nqtype = (enum QUE_TYPE)(q_type - QUEUE_NUM);
return true;
}
/**********************************************************/
/**********************************************************/
/*ary add this function for reg ini value, no need wait peek*/
void queue_init2(unsigned int channel)
{
int i, j;
struct queue_s *pqueue = get_queue(channel);
for (i = 0; i < QUEUE_NUM; i++) {
queue_t *q = &pqueue[i];
for (j = 0; j < MAX_QUEUE_POOL_SIZE; j++)
q->pool[j] = 0;
q->in_idx = 0;
q->out_idx = 0;
q->num = 0;
q->type = 0;
if (i == QUEUE_RECYCLE ||
i == QUEUE_DISPLAY ||
i == QUEUE_TMP ||
i == QUEUE_POST_DOING)
q->type = 1;
#ifdef MARK_HIS
if (i == QUEUE_LOCAL_FREE && dim_get_use_2_int_buf())
q->type = 2;
#endif
}
}
void queue_init(unsigned int channel, int local_buffer_num)
{
int i, j;
struct di_buf_s *pbuf_local = get_buf_local(channel);
struct di_buf_s *pbuf_in = get_buf_in(channel);
struct di_buf_s *pbuf_post = get_buf_post(channel);
struct queue_s *pqueue = get_queue(channel);
struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel);
for (i = 0; i < QUEUE_NUM; i++) {
queue_t *q = &pqueue[i];
for (j = 0; j < MAX_QUEUE_POOL_SIZE; j++)
q->pool[j] = 0;
q->in_idx = 0;
q->out_idx = 0;
q->num = 0;
q->type = 0;
if (i == QUEUE_RECYCLE ||
i == QUEUE_DISPLAY ||
i == QUEUE_TMP
/*||(i == QUEUE_POST_DOING)*/
)
q->type = 1;
if (i == QUEUE_LOCAL_FREE &&
dimp_get(edi_mp_use_2_interlace_buff))
q->type = 2;
}
if (local_buffer_num > 0) {
pbuf_pool[VFRAME_TYPE_IN - 1].di_buf_ptr = &pbuf_in[0];
pbuf_pool[VFRAME_TYPE_IN - 1].size = MAX_IN_BUF_NUM;
pbuf_pool[VFRAME_TYPE_LOCAL - 1].di_buf_ptr = &pbuf_local[0];
pbuf_pool[VFRAME_TYPE_LOCAL - 1].size = local_buffer_num;
pbuf_pool[VFRAME_TYPE_POST - 1].di_buf_ptr = &pbuf_post[0];
pbuf_pool[VFRAME_TYPE_POST - 1].size = MAX_POST_BUF_NUM;
}
}
struct di_buf_s *get_di_buf_head(unsigned int channel, int queue_idx)
{
struct queue_s *pqueue = get_queue(channel);
queue_t *q = &pqueue[queue_idx];
int idx;
unsigned int pool_idx, di_buf_idx;
struct di_buf_s *di_buf = NULL;
struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel);
enum QUE_TYPE nqtype;/*new que*/
if (dimp_get(edi_mp_di_log_flag) & DI_LOG_QUEUE)
dim_print("%s:<%d:%d,%d,%d>\n", __func__, queue_idx,
q->num, q->in_idx, q->out_idx);
/* ****new que***** */
if (di_que_type_2_new(queue_idx, &nqtype))
return di_que_peek(channel, nqtype);
/* **************** */
if (q->num > 0) {
if (q->type == 0) {
idx = q->out_idx;
} else {
for (idx = 0; idx < MAX_QUEUE_POOL_SIZE; idx++)
if (q->pool[idx] != 0)
break;
}
if (idx < MAX_QUEUE_POOL_SIZE) {
pool_idx = ((q->pool[idx] >> 8) & 0xff) - 1;
di_buf_idx = q->pool[idx] & 0xff;
if (pool_idx < VFRAME_TYPE_NUM) {
if (di_buf_idx < pbuf_pool[pool_idx].size)
di_buf = &pbuf_pool[pool_idx].di_buf_ptr[di_buf_idx];
}
}
}
if ((di_buf) && ((((pool_idx + 1) << 8) | di_buf_idx) !=
((di_buf->type << 8) | di_buf->index))) {
pr_dbg("%s: Error (%x,%x)\n", __func__,
(((pool_idx + 1) << 8) | di_buf_idx),
((di_buf->type << 8) | (di_buf->index)));
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(2);
dim_vcry_set_log_q_idx(queue_idx);
dim_vcry_set_log_di_buf(di_buf);
}
dim_vcry_flg_inc();
di_buf = NULL;
}
if (dimp_get(edi_mp_di_log_flag) & DI_LOG_QUEUE) {
if (di_buf)
dim_print("%s: 0x%p(%d,%d)\n", __func__, di_buf,
pool_idx, di_buf_idx);
else
dim_print("%s: 0x%p\n", __func__, di_buf);
}
return di_buf;
}
/*ary: note:*/
/*a. di_buf->queue_index = -1*/
/*b. */
void queue_out(unsigned int channel, struct di_buf_s *di_buf)
{
int i;
queue_t *q;
struct queue_s *pqueue = get_queue(channel);
enum QUE_TYPE nqtype;/*new que*/
if (!di_buf) {
PR_ERR("%s:Error\n", __func__);
if (dim_vcry_get_flg() == 0)
dim_vcry_set_log_reason(3);
dim_vcry_flg_inc();
return;
}
/* ****new que***** */
if (di_que_type_2_new(di_buf->queue_index, &nqtype)) {
di_que_out(channel, nqtype, di_buf); /*?*/
return;
}
/* **************** */
if (di_buf->queue_index >= 0 && di_buf->queue_index < QUEUE_NUM) {
q = &pqueue[di_buf->queue_index];
if (dimp_get(edi_mp_di_log_flag) & DI_LOG_QUEUE)
dim_print("%s:<%d:%d,%d,%d> 0x%p\n", __func__,
di_buf->queue_index, q->num, q->in_idx,
q->out_idx, di_buf);
if (q->num > 0) {
if (q->type == 0) {
if (q->pool[q->out_idx] ==
((di_buf->type << 8) | di_buf->index)) {
q->num--;
q->pool[q->out_idx] = 0;
q->out_idx++;
if (q->out_idx >= MAX_QUEUE_POOL_SIZE)
q->out_idx = 0;
di_buf->queue_index = -1;
} else {
PR_ERR("%s: Error (%d, %x,%x)\n",
__func__,
di_buf->queue_index,
q->pool[q->out_idx],
((di_buf->type << 8) |
(di_buf->index)));
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(4);
dim_vcry_set_log_q_idx(di_buf->queue_index);
dim_vcry_set_log_di_buf(di_buf);
}
dim_vcry_flg_inc();
}
} else if (q->type == 1) {
int pool_val =
(di_buf->type << 8) | (di_buf->index);
for (i = 0; i < MAX_QUEUE_POOL_SIZE; i++) {
if (q->pool[i] == pool_val) {
q->num--;
q->pool[i] = 0;
di_buf->queue_index = -1;
break;
}
}
if (i == MAX_QUEUE_POOL_SIZE) {
PR_ERR("%s: Error\n", __func__);
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(5);
dim_vcry_set_log_q_idx(di_buf->queue_index);
dim_vcry_set_log_di_buf(di_buf);
}
dim_vcry_flg_inc();
}
} else if (q->type == 2) {
int pool_val =
(di_buf->type << 8) | (di_buf->index);
if (di_buf->index < MAX_QUEUE_POOL_SIZE &&
q->pool[di_buf->index] == pool_val) {
q->num--;
q->pool[di_buf->index] = 0;
di_buf->queue_index = -1;
} else {
PR_ERR("%s: Error\n", __func__);
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(5);
dim_vcry_set_log_q_idx(di_buf->queue_index);
dim_vcry_set_log_di_buf(di_buf);
}
dim_vcry_flg_inc();
}
}
}
} else {
PR_ERR("%s: queue_index %d is not right\n",
__func__, di_buf->queue_index);
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(6);
dim_vcry_set_log_q_idx(0);
dim_vcry_set_log_di_buf(di_buf);
}
dim_vcry_flg_inc();
}
if (dimp_get(edi_mp_di_log_flag) & DI_LOG_QUEUE)
dim_print("%s done\n", __func__);
}
void queue_out_dbg(unsigned int channel, struct di_buf_s *di_buf)
{
int i;
queue_t *q;
struct queue_s *pqueue = get_queue(channel);
enum QUE_TYPE nqtype;/*new que*/
if (!di_buf) {
PR_ERR("%s:Error\n", __func__);
if (dim_vcry_get_flg() == 0)
dim_vcry_set_log_reason(3);
dim_vcry_flg_inc();
return;
}
/* ****new que***** */
if (di_que_type_2_new(di_buf->queue_index, &nqtype)) {
di_que_out(channel, nqtype, di_buf); /*?*/
pr_info("dbg1:nqtype=%d\n", nqtype);
return;
}
/* **************** */
if (di_buf->queue_index >= 0 && di_buf->queue_index < QUEUE_NUM) {
q = &pqueue[di_buf->queue_index];
if (dimp_get(edi_mp_di_log_flag) & DI_LOG_QUEUE)
dim_print("%s:<%d:%d,%d,%d> 0x%p\n", __func__,
di_buf->queue_index, q->num, q->in_idx,
q->out_idx, di_buf);
if (q->num > 0) {
if (q->type == 0) {
pr_info("dbg3\n");
if (q->pool[q->out_idx] ==
((di_buf->type << 8) | di_buf->index)) {
q->num--;
q->pool[q->out_idx] = 0;
q->out_idx++;
if (q->out_idx >= MAX_QUEUE_POOL_SIZE)
q->out_idx = 0;
di_buf->queue_index = -1;
} else {
PR_ERR("%s: Error (%d, %x,%x)\n",
__func__,
di_buf->queue_index,
q->pool[q->out_idx],
((di_buf->type << 8) |
(di_buf->index)));
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(4);
dim_vcry_set_log_q_idx(di_buf->queue_index);
dim_vcry_set_log_di_buf(di_buf);
}
dim_vcry_flg_inc();
}
} else if (q->type == 1) {
int pool_val =
(di_buf->type << 8) | (di_buf->index);
for (i = 0; i < MAX_QUEUE_POOL_SIZE; i++) {
if (q->pool[i] == pool_val) {
q->num--;
q->pool[i] = 0;
di_buf->queue_index = -1;
break;
}
}
pr_info("dbg2:i=%d,qindex=%d\n", i,
di_buf->queue_index);
if (i == MAX_QUEUE_POOL_SIZE) {
PR_ERR("%s: Error\n", __func__);
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(5);
dim_vcry_set_log_q_idx(di_buf->queue_index);
dim_vcry_set_log_di_buf(di_buf);
}
dim_vcry_flg_inc();
}
} else if (q->type == 2) {
int pool_val =
(di_buf->type << 8) | (di_buf->index);
pr_info("dbg4\n");
if (di_buf->index < MAX_QUEUE_POOL_SIZE &&
q->pool[di_buf->index] == pool_val) {
q->num--;
q->pool[di_buf->index] = 0;
di_buf->queue_index = -1;
} else {
PR_ERR("%s: Error\n", __func__);
if (dim_vcry_get_flg() == 0) {
dim_vcry_set
(5,
di_buf->queue_index,
di_buf);
}
dim_vcry_flg_inc();
}
}
}
} else {
PR_ERR("%s: Error, queue_index %d is not right\n",
__func__, di_buf->queue_index);
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(6);
dim_vcry_set_log_q_idx(0);
dim_vcry_set_log_di_buf(di_buf);
}
dim_vcry_flg_inc();
}
if (dimp_get(edi_mp_di_log_flag) & DI_LOG_QUEUE)
dim_print("%s done\n", __func__);
}
/***************************************/
/* set di_buf->queue_index*/
/***************************************/
void queue_in(unsigned int channel, struct di_buf_s *di_buf, int queue_idx)
{
queue_t *q = NULL;
struct queue_s *pqueue = get_queue(channel);
enum QUE_TYPE nqtype;/*new que*/
if (!di_buf) {
PR_ERR("%s:Error\n", __func__);
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(7);
dim_vcry_set_log_q_idx(queue_idx);
dim_vcry_set_log_di_buf(di_buf);
}
dim_vcry_flg_inc();
return;
}
/* ****new que***** */
if (di_que_type_2_new(queue_idx, &nqtype)) {
di_que_in(channel, nqtype, di_buf);
return;
}
/* **************** */
if (di_buf->queue_index != -1) {
PR_ERR("%s:%s[%d] queue_index(%d) is not -1, to que[%d]\n",
__func__, dim_get_vfm_type_name(di_buf->type),
di_buf->index, di_buf->queue_index, queue_idx);
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(8);
dim_vcry_set_log_q_idx(queue_idx);
dim_vcry_set_log_di_buf(di_buf);
}
dim_vcry_flg_inc();
return;
}
q = &pqueue[queue_idx];
if (dimp_get(edi_mp_di_log_flag) & DI_LOG_QUEUE)
dim_print("%s:<%d:%d,%d,%d> 0x%p\n", __func__, queue_idx,
q->num, q->in_idx, q->out_idx, di_buf);
if (q->type == 0) {
q->pool[q->in_idx] = (di_buf->type << 8) | (di_buf->index);
di_buf->queue_index = queue_idx;
q->in_idx++;
if (q->in_idx >= MAX_QUEUE_POOL_SIZE)
q->in_idx = 0;
q->num++;
} else if (q->type == 1) {
int i;
for (i = 0; i < MAX_QUEUE_POOL_SIZE; i++) {
if (q->pool[i] == 0) {
q->pool[i] =
(di_buf->type << 8) | (di_buf->index);
di_buf->queue_index = queue_idx;
q->num++;
break;
}
}
if (i == MAX_QUEUE_POOL_SIZE) {
#ifdef PRINT_BASIC
PR_ERR("%s: Error\n", __func__);
#endif
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(9);
dim_vcry_set_log_q_idx(queue_idx);
}
dim_vcry_flg_inc();
}
} else if (q->type == 2) {
if (di_buf->index < MAX_QUEUE_POOL_SIZE &&
q->pool[di_buf->index] == 0) {
q->pool[di_buf->index] =
(di_buf->type << 8) | (di_buf->index);
di_buf->queue_index = queue_idx;
q->num++;
} else {
PR_ERR("%s: Error\n", __func__);
if (dim_vcry_get_flg() == 0) {
dim_vcry_set_log_reason(9);
dim_vcry_set_log_q_idx(queue_idx);
}
dim_vcry_flg_inc();
}
}
if (dimp_get(edi_mp_di_log_flag) & DI_LOG_QUEUE)
dim_print("%s done\n", __func__);
}
int list_count(unsigned int channel, int queue_idx)
{
struct queue_s *pqueue;
enum QUE_TYPE nqtype;/*new que*/
/* ****new que***** */
if (di_que_type_2_new(queue_idx, &nqtype)) {
PR_ERR("%s:err: over flow\n", __func__);
return di_que_list_count(channel, nqtype);
}
/* **************** */
pqueue = get_queue(channel);
return pqueue[queue_idx].num;
}
bool queue_empty(unsigned int channel, int queue_idx)
{
struct queue_s *pqueue;
bool ret;
enum QUE_TYPE nqtype;/*new que*/
/* ****new que***** */
if (di_que_type_2_new(queue_idx, &nqtype)) {
PR_ERR("%s:err: over flow\n", __func__);
return di_que_is_empty(channel, nqtype);
}
/* **************** */
pqueue = get_queue(channel);
ret = (pqueue[queue_idx].num == 0);
return ret;
}
bool is_in_queue(unsigned int channel, struct di_buf_s *di_buf, int queue_idx)
{
bool ret = 0;
struct di_buf_s *p = NULL;
int itmp;
unsigned int overflow_cnt;
enum QUE_TYPE nqtype;/*new que*/
/* ****new que***** */
if (di_que_type_2_new(queue_idx, &nqtype))
return di_que_is_in_que(channel, nqtype, di_buf);
/* **************** */
overflow_cnt = 0;
if (!di_buf || queue_idx < 0 || queue_idx >= QUEUE_NUM) {
ret = 0;
dim_print("%s: not in queue:%d!!!\n", __func__, queue_idx);
return ret;
}
queue_for_each_entry(p, channel, queue_idx, list) {
if (p == di_buf) {
ret = 1;
break;
}
if (overflow_cnt++ > MAX_QUEUE_POOL_SIZE) {
ret = 0;
dim_print("%s: overflow_cnt!!!\n", __func__);
break;
}
}
return ret;
}