Exemplo n.º 1
0
/** 
 * \fn     twIf_TxnDoneCb
 * \brief  Transaction completion CB
 * 
 * This callback is called by the TxnQ upon transaction completion, unless is was completed in
 *     the original context where it was issued.
 * It may be called from bus driver external context (TxnDone ISR) or from WLAN driver context.
 *  
 * \note   
 * \param  hTwIf - The module's object
 * \param  pTxn  - The completed transaction object 
 * \return void
 * \sa     twIf_HandleTxnDone
 */
static void twIf_TxnDoneCb(TI_HANDLE hTwIf, TTxnStruct * pTxn)
{
	TTwIfObj *pTwIf = (TTwIfObj *) hTwIf;

#ifdef TI_DBG
	pTwIf->uDbgCountTxnDoneCb++;
	TRACE6(pTwIf->hReport, REPORT_SEVERITY_INFORMATION,
	       "twIf_TxnDoneCb: Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n",
	       pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0], pTxn->aLen[1],
	       pTxn->aLen[2], pTxn->aLen[3]);
#endif

	/* In case of recovery flag, Call directly restart callback */
	if (TXN_PARAM_GET_STATUS(pTxn) == TXN_PARAM_STATUS_RECOVERY) {
		if (pTwIf->fRecoveryCb) {
			TRACE0(pTwIf->hReport, REPORT_SEVERITY_INFORMATION,
			       "twIf_TxnDoneCb: During Recovery\n");
			pTwIf->bTxnDoneInRecovery = TI_TRUE;
			/* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
			context_RequestSchedule(pTwIf->hContext,
						pTwIf->uContextId);
			return;
		}
	}

	/* If the completed Txn is ELP, nothing to do (not counted) so exit */
	if (TXN_PARAM_GET_SINGLE_STEP(pTxn)) {
		return;
	}

	if (pTxn->fTxnDoneCb) {
		TI_STATUS eStatus;

		/* In critical section, enqueue the completed transaction in the TxnDoneQ. */
		context_EnterCriticalSection(pTwIf->hContext);
		eStatus = que_Enqueue(pTwIf->hTxnDoneQueue, (TI_HANDLE) pTxn);
		if (eStatus != TI_OK) {
			TRACE3(pTwIf->hReport, REPORT_SEVERITY_ERROR,
			       "twIf_TxnDoneCb(): Enqueue failed, pTxn=0x%x, HwAddr=0x%x, Len0=%d\n",
			       pTxn, pTxn->uHwAddr, pTxn->aLen[0]);
		}
		context_LeaveCriticalSection(pTwIf->hContext);
	} else {
		context_EnterCriticalSection(pTwIf->hContext);
		/* Decrement pending Txn counter, It's value will be checked in twIf_HandleTxnDone() */
		if (pTwIf->uPendingTxnCount > 0) {	/* in case of callback on recovery after restart */
			pTwIf->uPendingTxnCount--;
		}
		context_LeaveCriticalSection(pTwIf->hContext);

	}

	/* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
	context_RequestSchedule(pTwIf->hContext, pTwIf->uContextId);
}
Exemplo n.º 2
0
/** 
 * \fn     twIf_TxnDoneCb
 * \brief  Transaction completion CB
 * 
 * This callback is called by the TxnQ upon transaction completion, unless is was completed in
 *     the original context where it was issued.
 * It may be called from bus driver external context (TxnDone ISR) or from WLAN driver context.
 *  
 * \note   
 * \param  hTwIf - The module's object
 * \param  pTxn  - The completed transaction object 
 * \return void
 * \sa     twIf_HandleTxnDone
 */ 
static void twIf_TxnDoneCb (TI_HANDLE hTwIf, TTxnStruct *pTxn)
{
    TTwIfObj *pTwIf = (TTwIfObj*)hTwIf;

#ifdef TI_DBG
    pTwIf->uDbgCountTxnDoneCb++;
#endif

    /* In case of recovery flag, Call directly restart callback */
    if (TXN_PARAM_GET_STATUS(pTxn) == TXN_PARAM_STATUS_RECOVERY)
    {
        if (pTwIf->fRecoveryCb)
        {
            pTwIf->bTxnDoneInRecovery = TI_TRUE;
            /* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
            context_RequestSchedule (pTwIf->hContext, pTwIf->uContextId);
            return;
        }
    }

    /* If the completed Txn is ELP, nothing to do (not counted) so exit */
    if (TXN_PARAM_GET_SINGLE_STEP(pTxn)) 
    {
        return;
    }

    if (pTxn->fTxnDoneCb)
    {
        TI_STATUS eStatus;

        /* In critical section, enqueue the completed transaction in the TxnDoneQ. */
        context_EnterCriticalSection (pTwIf->hContext);
        eStatus = que_Enqueue (pTwIf->hTxnDoneQueue, (TI_HANDLE)pTxn);
        context_LeaveCriticalSection (pTwIf->hContext);
    }
    else
    {
        context_EnterCriticalSection (pTwIf->hContext);
         /* Decrement pending Txn counter, It's value will be checked in twIf_HandleTxnDone() */
        if (pTwIf->uPendingTxnCount > 0) /* in case of callback on recovery after restart */
        {
            pTwIf->uPendingTxnCount--;
        }
        context_LeaveCriticalSection (pTwIf->hContext);

    }
    
    /* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
    context_RequestSchedule (pTwIf->hContext, pTwIf->uContextId);
}
Exemplo n.º 3
0
/** 
 * \fn     twIf_HandleTxnDone
 * \brief  Completed transactions handler
 * 
 * The completed transactions handler, called upon TxnDone event, either from the context engine
 *     or directly from twIf_TxnDoneCb() if we are already in the WLAN driver's context.
 * Dequeue all completed transactions in critical section, and call their callbacks if available.
 * If awake is not required and no pending transactions in TxnQ, issue Sleep event to SM.
 *  
 * \note   
 * \param  hTwIf - The module's object
 * \return void
 * \sa     
 */
static void twIf_HandleTxnDone(TI_HANDLE hTwIf)
{
	TTwIfObj *pTwIf = (TTwIfObj *) hTwIf;
	TTxnStruct *pTxn;

	/* In case of recovery, call the recovery callback and exit */
	if (pTwIf->bTxnDoneInRecovery) {
		TRACE0(pTwIf->hReport, REPORT_SEVERITY_INFORMATION,
		       "twIf_HandleTxnDone: call RecoveryCb\n");
		pTwIf->bTxnDoneInRecovery = TI_FALSE;
		if (pTwIf->bPendRestartTimerRunning) {
			tmr_StopTimer(pTwIf->hPendRestartTimer);
			pTwIf->bPendRestartTimerRunning = TI_FALSE;
		}
		pTwIf->fRecoveryCb(pTwIf->hRecoveryCb);
		return;
	}

	/* Loop while there are completed transactions to handle */
	while (1) {
		/* In critical section, dequeue completed transaction from the TxnDoneQ. */
		context_EnterCriticalSection(pTwIf->hContext);
		pTxn = (TTxnStruct *) que_Dequeue(pTwIf->hTxnDoneQueue);
		context_LeaveCriticalSection(pTwIf->hContext);

		/* If no more transactions to handle, exit */
		if (pTxn != NULL) {
			context_EnterCriticalSection(pTwIf->hContext);
			/* Decrement pending Txn counter */
			if (pTwIf->uPendingTxnCount > 0) {	/* in case of callback on recovery after restart */
				pTwIf->uPendingTxnCount--;
			}
			context_LeaveCriticalSection(pTwIf->hContext);

			TRACE4(pTwIf->hReport, REPORT_SEVERITY_INFORMATION,
			       "twIf_HandleTxnDone: Completed-Txn: Params=0x%x, HwAddr=0x%x, Len0=%d, fTxnDoneCb=0x%x\n",
			       pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0],
			       pTxn->fTxnDoneCb);

			/* If Txn failed and error CB available, call it to initiate recovery */
			if (TXN_PARAM_GET_STATUS(pTxn) ==
			    TXN_PARAM_STATUS_ERROR) {
				TRACE6(pTwIf->hReport, REPORT_SEVERITY_ERROR,
				       "twIf_HandleTxnDone: Txn failed!!  Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n",
				       pTxn->uTxnParams, pTxn->uHwAddr,
				       pTxn->aLen[0], pTxn->aLen[1],
				       pTxn->aLen[2], pTxn->aLen[3]);

				if (pTwIf->fErrCb) {
					pTwIf->fErrCb(pTwIf->hErrCb,
						      BUS_FAILURE);
				}
				/* in error do not continue */
				return;
			}

			/* If Txn specific CB available, call it (may free Txn resources and issue new Txns) */
			if (pTxn->fTxnDoneCb != NULL) {
				((TTxnDoneCb) (pTxn->fTxnDoneCb)) (pTxn->
								   hCbHandle,
								   pTxn);
			}
		}

		/*If uPendingTxnCount == 0 and awake not required, issue Sleep event to SM */
		if ((pTwIf->uAwakeReqCount == 0)
		    && (pTwIf->uPendingTxnCount == 0)) {
			twIf_HandleSmEvent(pTwIf, SM_EVENT_SLEEP);
		}

		if (pTxn == NULL) {
			return;
		}
	}
}