ETxnStatus txnQ_Restart (TI_HANDLE hTxnQ, TI_UINT32 uFuncId) { TTxnQObj *pTxnQ = (TTxnQObj*) hTxnQ; TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Restart()\n"); context_EnterCriticalSection (pTxnQ->hContext); /* If a Txn from the calling function is in progress, set state to RESTART return PENDING */ if (pTxnQ->pCurrTxn) { if (TXN_PARAM_GET_FUNC_ID(pTxnQ->pCurrTxn) == uFuncId) { pTxnQ->aFuncInfo[uFuncId].eState = FUNC_STATE_RESTART; context_LeaveCriticalSection (pTxnQ->hContext); TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Restart(): pCurrTxn pending\n"); /* Return PENDING to indicate that the restart will be completed later (in TxnDone) */ return TXN_STATUS_PENDING; } } context_LeaveCriticalSection (pTxnQ->hContext); /* Clear the calling function's queues (call function CB with status=RECOVERY) */ txnQ_ClearQueues (hTxnQ, uFuncId); /* Return COMPLETE to indicate that the restart was completed */ return TXN_STATUS_COMPLETE; }
/** * \fn txnQ_TxnDoneCb * \brief Pending Transaction completion CB * * Called back by bus-driver upon pending transaction completion in TxnDone context (external!). * Enqueue completed transaction in TxnDone queue and call scheduler to send queued transactions. * * \note * \param hTxnQ - The module's object * \param pTxn - The completed transaction object * \return void * \sa */ static void txnQ_TxnDoneCb (TI_HANDLE hTxnQ, void *hTxn) { TTxnQObj *pTxnQ = (TTxnQObj*)hTxnQ; TTxnStruct *pTxn = (TTxnStruct *)hTxn; TI_UINT32 uFuncId = TXN_PARAM_GET_FUNC_ID(pTxn); /* If the function of the completed Txn is waiting for restart */ if (pTxnQ->aFuncInfo[uFuncId].eState == FUNC_STATE_RESTART) { /* First, Clear the restarted function queues */ txnQ_ClearQueues (hTxnQ, uFuncId); /* Call function CB for current Txn with restart indication */ TXN_PARAM_SET_STATUS(pTxn, TXN_PARAM_STATUS_RECOVERY); pTxnQ->aFuncInfo[uFuncId].fTxnQueueDoneCb (pTxnQ->aFuncInfo[uFuncId].hCbHandle, pTxn); } /* In the normal case (no restart), enqueue completed transaction in TxnDone queue */ else { TI_STATUS eStatus; context_EnterCriticalSection (pTxnQ->hContext); eStatus = que_Enqueue (pTxnQ->hTxnDoneQueue, (TI_HANDLE)pTxn); context_LeaveCriticalSection (pTxnQ->hContext); } /* Indicate that no transaction is currently processed in the bus-driver */ pTxnQ->pCurrTxn = NULL; /* Send queued transactions as possible (TRUE indicates we are in external context) */ txnQ_RunScheduler (pTxnQ, NULL); }
/** * \fn twIf_PendRestratTimeout * \brief Pending restart process timeout handler * * Called if timer expires upon fail to complete the last bus transaction that was * pending during restart process. * Calls the recovery callback to continue the restart process. * * \note * \param hTwIf - The module's object * \return void * \sa */ static void twIf_PendRestratTimeout (TI_HANDLE hTwIf, TI_BOOL bTwdInitOccured) { TTwIfObj *pTwIf = (TTwIfObj*)hTwIf; pTwIf->bPendRestartTimerRunning = TI_FALSE; /* Clear the Txn queues since TxnDone wasn't called so it wasn't done by the TxnQ module */ txnQ_ClearQueues (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN); /* Call the recovery callback to continue the restart process */ pTwIf->fRecoveryCb(pTwIf->hRecoveryCb); }
/** * \fn txnQ_TxnDoneCb * \brief Pending Transaction completion CB * * Called back by bus-driver upon pending transaction completion in TxnDone context (external!). * Enqueue completed transaction in TxnDone queue and call scheduler to send queued transactions. * * \note * \param hTxnQ - The module's object * \param pTxn - The completed transaction object * \return void * \sa */ static void txnQ_TxnDoneCb (handle_t hTxnQ, void *hTxn) { TTxnQObj *pTxnQ = (TTxnQObj*)hTxnQ; TTxnStruct *pTxn = (TTxnStruct *)hTxn; McpU32 uFuncId = TXN_PARAM_GET_FUNC_ID(pTxn); #ifdef TRAN_DBG if (pTxn != pTxnQ->pCurrTxn) { MCPF_REPORT_ERROR(pTxnQ->hMcpf, QUEUE_MODULE_LOG, ("%s: CB returned pTxn 0x%p while pCurrTxn is 0x%p !!\n", __FUNCTION__, pTxn, pTxnQ->pCurrTxn)); } #endif /* Enter critical section if configured to do so */ if (pTxnQ->bProtectTxnDone) { MCPF_ENTER_CRIT_SEC (pTxnQ->hMcpf); } /* If the function of the completed Txn is waiting for restart */ if (pTxnQ->aFuncInfo[uFuncId].eState == FUNC_STATE_RESTART) { /* Call function CB for current Txn with recovery indication */ TXN_PARAM_SET_STATUS(pTxn, TXN_STATUS_RECOVERY); pTxnQ->aFuncInfo[uFuncId].fTxnQueueDoneCb (pTxnQ->aFuncInfo[uFuncId].hCbHandle, pTxn, MCP_TRUE); /* Clear the restarted function queues (call function CB with status=RECOVERY) */ txnQ_ClearQueues (pTxnQ, uFuncId, MCP_TRUE); } /* In the normal case (no restart), enqueue completed transaction in TxnDone queue */ else { que_Enqueue (pTxnQ->hTxnDoneQueue, (handle_t)pTxn); } /* Indicate that no transaction is currently processed in the bus-driver */ pTxnQ->pCurrTxn = NULL; /* Send queued transactions as possible (TRUE indicates we are in external context) */ txnQ_RunScheduler (pTxnQ, NULL, MCP_TRUE); /* Leave critical section if configured to do so */ if (pTxnQ->bProtectTxnDone) { MCPF_EXIT_CRIT_SEC (pTxnQ->hMcpf); } }
/** * \fn txnQ_TxnDoneCb * \brief Pending Transaction completion CB * * Called back by bus-driver upon pending transaction completion in TxnDone context (external!). * Enqueue completed transaction in TxnDone queue and call scheduler to send queued transactions. * * \note * \param hTxnQ - The module's object * \param pTxn - The completed transaction object * \return void * \sa */ static void txnQ_TxnDoneCb (TI_HANDLE hTxnQ, void *hTxn) { TTxnQObj *pTxnQ = (TTxnQObj*)hTxnQ; TTxnStruct *pTxn = (TTxnStruct *)hTxn; TI_UINT32 uFuncId = TXN_PARAM_GET_FUNC_ID(pTxn); #ifdef TI_DBG TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_TxnDoneCb()\n"); if (pTxn != pTxnQ->pCurrTxn) { TRACE2(pTxnQ->hReport, REPORT_SEVERITY_ERROR, "txnQ_TxnDoneCb(): CB returned pTxn 0x%x while pCurrTxn is 0x%x !!\n", pTxn, pTxnQ->pCurrTxn); } #endif /* If the function of the completed Txn is waiting for restart */ if (pTxnQ->aFuncInfo[uFuncId].eState == FUNC_STATE_RESTART) { TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_TxnDoneCb(): Handling restart\n"); /* First, Clear the restarted function queues */ txnQ_ClearQueues (hTxnQ, uFuncId); /* Call function CB for current Txn with restart indication */ TXN_PARAM_SET_STATUS(pTxn, TXN_PARAM_STATUS_RECOVERY); pTxnQ->aFuncInfo[uFuncId].fTxnQueueDoneCb (pTxnQ->aFuncInfo[uFuncId].hCbHandle, pTxn); } /* In the normal case (no restart), enqueue completed transaction in TxnDone queue */ else { TI_STATUS eStatus; context_EnterCriticalSection (pTxnQ->hContext); eStatus = que_Enqueue (pTxnQ->hTxnDoneQueue, (TI_HANDLE)pTxn); if (eStatus != TI_OK) { TRACE3(pTxnQ->hReport, REPORT_SEVERITY_ERROR, "txnQ_TxnDoneCb(): Enqueue failed, pTxn=0x%x, HwAddr=0x%x, Len0=%d\n", pTxn, pTxn->uHwAddr, pTxn->aLen[0]); } context_LeaveCriticalSection (pTxnQ->hContext); } /* Indicate that no transaction is currently processed in the bus-driver */ pTxnQ->pCurrTxn = NULL; /* Send queued transactions as possible (TRUE indicates we are in external context) */ txnQ_RunScheduler (pTxnQ, NULL); }
/** * \fn txnQ_Restart * \brief Restart caller's queues * * Called upon functional driver stop command or upon recovery. * If no transaction in progress for the calling function, clear its queues (call the CBs). * If a transaction from this function is in progress, just set state to RESTART and when * called back upon TxnDone clear the queues. * Perform in critical section to prevent preemption from TxnDone. * Note that the Restart applies only to the calling function's queues. * * \note * \param hTxnQ - The module's object * \param uFuncId - The calling functional driver * \return COMPLETE if queues were restarted, PENDING if waiting for TxnDone to restart queues * \sa txnQ_ClearQueues */ ETxnStatus txnQ_Restart (handle_t hTxnQ, const McpU32 uFuncId) { TTxnQObj *pTxnQ = (TTxnQObj*) hTxnQ; #ifdef TRAN_DBG if (pTxnQ->aFuncInfo[uFuncId].eState != FUNC_STATE_RUNNING) { MCPF_REPORT_ERROR(pTxnQ->hMcpf, QUEUE_MODULE_LOG, ("%s: Called while func %d state is %d!\n", __FUNCTION__, uFuncId, pTxnQ->aFuncInfo[uFuncId].eState)); } #endif MCPF_ENTER_CRIT_SEC (pTxnQ->hMcpf); /* If a Txn from the calling function is in progress, set state to RESTART return PENDING */ if (pTxnQ->pCurrTxn) { if (TXN_PARAM_GET_FUNC_ID(pTxnQ->pCurrTxn) == uFuncId) { pTxnQ->aFuncInfo[uFuncId].eState = FUNC_STATE_RESTART; MCPF_EXIT_CRIT_SEC (pTxnQ->hMcpf); /* Return PENDING to indicate that the restart will be completed later (in TxnDone) */ return TXN_STATUS_PENDING; } } /* Clear the calling function's queues (call function CB with status=RECOVERY) */ txnQ_ClearQueues (pTxnQ, uFuncId, MCP_FALSE); MCPF_EXIT_CRIT_SEC (pTxnQ->hMcpf); /* Return COMPLETE to indicate that the restart was completed */ return TXN_STATUS_COMPLETE; }