예제 #1
0
INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm)
{
    UINT32 i = 0;
    osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
    RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE);
    RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE);
    osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));
    /* Put all to free Q */
    for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++)
    {
        osal_signal_init(&(stp_btm->arQue[i].signal));
        _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i]));
    }

    return 0;
}
MTKSTP_BTM_T *stp_btm_init(void)
{
    INT32 i = 0x0;
    INT32 ret =-1;
    
    osal_unsleepable_lock_init(&stp_btm->wq_spinlock);
    osal_event_init(&stp_btm->STPd_event);
    stp_btm->wmt_notify = wmt_lib_btm_cb;
    
    RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE);
    RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE);

    /* Put all to free Q */
    for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) 
    {
         osal_signal_init(&(stp_btm->arQue[i].signal));
         _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i]));
    }

    /*Generate PSM thread, to servie STP-CORE for packet retrying and core dump receiving*/
    stp_btm->BTMd.pThreadData = (VOID *)stp_btm;
    stp_btm->BTMd.pThreadFunc = (VOID *)_stp_btm_proc;
    osal_memcpy(stp_btm->BTMd.threadName, BTM_THREAD_NAME , osal_strlen(BTM_THREAD_NAME));

    ret = osal_thread_create(&stp_btm->BTMd);
    if (ret < 0) 
    {
        STP_BTM_ERR_FUNC("osal_thread_create fail...\n");
        goto ERR_EXIT1;
    }
    
    /* Start STPd thread*/
    ret = osal_thread_run(&stp_btm->BTMd);
    if(ret < 0)
    {
        STP_BTM_ERR_FUNC("osal_thread_run FAILS\n");
        goto ERR_EXIT1;
    }

    return stp_btm;

ERR_EXIT1:

    return NULL;

}
static INT32 _stp_btm_proc (void *pvData)
{
    MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *)pvData;
    P_OSAL_OP pOp;
    INT32 id;
    INT32 result;
    
    if (!stp_btm) 
    {
        STP_BTM_WARN_FUNC("!stp_btm \n");
        return -1;
    }

    for (;;) 
    {
        pOp = NULL;
        
        osal_wait_for_event(&stp_btm->STPd_event, 
            _stp_btm_wait_for_msg,
            (void *)stp_btm
            );

        if (osal_thread_should_stop(&stp_btm->BTMd)) 
        {
            STP_BTM_INFO_FUNC("should stop now... \n");
            // TODO: clean up active opQ
            break;
        }

        /* get Op from activeQ */
        pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ);

        if (!pOp) 
        {
            STP_BTM_WARN_FUNC("get_lxop activeQ fail\n");
            continue;
        }

        id = osal_op_get_id(pOp);

        STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n",
            id, (id >= 4)?("???"):(g_btm_op_name[id]), RB_COUNT(&stp_btm->rActiveOpQ));

        if (id >= STP_OPID_BTM_NUM) 
        {
            STP_BTM_WARN_FUNC("abnormal opid id: 0x%x \n", id);
            result = -1;
            goto handler_done;
        }
        
        result = _stp_btm_handler(stp_btm, &pOp->op);

handler_done:

        if (result) 
        {
            STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, (id >= 4)?("???"):(g_btm_op_name[id]), result);
        }

        if (osal_op_is_wait_for_signal(pOp)) 
        {
            osal_op_raise_signal(pOp, result);
        }
        else 
        {
            /* put Op back to freeQ */
            _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp);
        }
        
        if (STP_OPID_BTM_EXIT == id) 
        {
            break;
        }
    }
    
    STP_BTM_INFO_FUNC("exits \n");

    return 0;
};
INT32 _stp_btm_put_act_op (
    MTKSTP_BTM_T *stp_btm,
    P_OSAL_OP pOp
    )
{
    INT32 bRet = 0;
    INT32 bCleanup = 0;
    long wait_ret = -1;

    P_OSAL_SIGNAL pSignal = NULL;

    do {
        if (!stp_btm || !pOp) 
        {
            break;
        }

        pSignal = &pOp->signal;
        
        if (pSignal->timeoutValue) 
        {
            pOp->result = -9;
            osal_signal_init(&pOp->signal);
        }

        /* put to active Q */
        bRet = _stp_btm_put_op(stp_btm, &stp_btm->rActiveOpQ, pOp);
        if(0 == bRet)
        {
            STP_BTM_WARN_FUNC("put active queue fail\n");
            bCleanup = 1;//MTK_WCN_BOOL_TRUE;
            break;
        }
        
        /* wake up wmtd */
        osal_trigger_event(&stp_btm->STPd_event);

        if (pSignal->timeoutValue == 0) 
        {
            bRet = 1;//MTK_WCN_BOOL_TRUE;
            /* clean it in wmtd */
            break;
        }
        
        /* wait result, clean it here */
        bCleanup = 1;//MTK_WCN_BOOL_TRUE;

        /* check result */
        wait_ret = osal_wait_for_signal_timeout(&pOp->signal);

        STP_BTM_DBG_FUNC("wait completion:%ld\n", wait_ret);
        if (!wait_ret) 
        {
            STP_BTM_ERR_FUNC("wait completion timeout \n");
            // TODO: how to handle it? retry?
        }
        else 
        {
            if (pOp->result) 
            {
                STP_BTM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result);
            }
            
            bRet = (pOp->result) ? 0 : 1;
        }
    } while(0);

    if (bCleanup) {
        /* put Op back to freeQ */
        _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp);
    }

    return bRet;
}
예제 #5
0
static INT32 _stp_btm_proc(PVOID pvData)
{
	MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData;
	P_OSAL_OP pOp;
	INT32 id;
	INT32 result;

	if (!stp_btm) {
		STP_BTM_WARN_FUNC("!stp_btm\n");
		return -1;
	}

	for (;;) {
		pOp = NULL;

		osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (PVOID)stp_btm);

		if (osal_thread_should_stop(&stp_btm->BTMd)) {
			STP_BTM_INFO_FUNC("should stop now...\n");
			/* TODO: clean up active opQ */
			break;
		}
#if 1
		if (gDumplogflag) {
			/* pr_warn("enter place1\n"); */
			if (mtk_wcn_stp_is_uart_mand_mode() || mtk_wcn_stp_is_uart_fullset_mode())
				dump_uart_history();
			gDumplogflag = 0;
			continue;
		}
#endif

		/* get Op from activeQ */
		pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ);

		if (!pOp) {
			STP_BTM_WARN_FUNC("get_lxop activeQ fail\n");
			continue;
		}

		id = osal_op_get_id(pOp);

		STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n",
				 id, (id >= 4) ? ("???") : (g_btm_op_name[id]),
				 RB_COUNT(&stp_btm->rActiveOpQ));

		if (id >= STP_OPID_BTM_NUM) {
			STP_BTM_WARN_FUNC("abnormal opid id: 0x%x\n", id);
			result = -1;
			goto handler_done;
		}

		osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
		stp_btm_set_current_op(stp_btm, pOp);
		osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));
		result = _stp_btm_handler(stp_btm, &pOp->op);
		osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock));
		stp_btm_set_current_op(stp_btm, NULL);
		osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock));

 handler_done:

		if (result) {
			STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n",
				id, (id >= 4) ? ("???") : (g_btm_op_name[id]), result);
		}

		if (osal_op_is_wait_for_signal(pOp)) {
			osal_op_raise_signal(pOp, result);
		} else {
			/* put Op back to freeQ */
			_stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp);
		}

		if (STP_OPID_BTM_EXIT == id) {
			break;
		} else if (STP_OPID_BTM_RST == id) {
			/* prevent multi reset case */
			stp_btm_reset_btm_wq(stp_btm);
		}
	}

	STP_BTM_INFO_FUNC("exits\n");

	return 0;
};