/*
 * SdioBusDrv.c
 *
 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.      
 * All rights reserved.                                                  
 *                                                                       
 * Redistribution and use in source and binary forms, with or without    
 * modification, are permitted provided that the following conditions    
 * are met:                                                              
 *                                                                       
 *  * Redistributions of source code must retain the above copyright     
 *    notice, this list of conditions and the following disclaimer.      
 *  * Redistributions in binary form must reproduce the above copyright  
 *    notice, this list of conditions and the following disclaimer in    
 *    the documentation and/or other materials provided with the         
 *    distribution.                                                      
 *  * Neither the name Texas Instruments nor the names of its            
 *    contributors may be used to endorse or promote products derived    
 *    from this software without specific prior written permission.      
 *                                                                       
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

 
/** \file   SdioBusDrv.c 
 *  \brief  The SDIO bus driver upper layer. Platform independent. 
 *          Uses the SdioAdapter API. 
 *          Introduces a generic bus-independent API upwards.
 *  
 *  \see    BusDrv.h, SdioAdapter.h, SdioAdapter.c
 */

#define __FILE_ID__  FILE_ID_122
#include "tidef.h"
#include "report.h"
#include "osApi.h"
#include "TxnDefs.h"
#include "SdioAdapter.h"
#include "BusDrv.h"
#include "bmtrace_api.h"


/* remove the chipID check when WL6-PG1.0 becomes obsolete (temporary global variable!!) */
extern TI_BOOL bChipIs1273Pg10;


/************************************************************************
 * Defines
 ************************************************************************/
#define MAX_TXN_PARTS     MAX_XFER_BUFS * 2   /* Max number of txn parts derived from one TxnStruct */


/************************************************************************
 * Types
 ************************************************************************/

/* A single SDIO bus transaction which is a part of a complete transaction (TTxnStruct) */ 
typedef struct
{
    TI_BOOL          bBlkMode;           /* If TRUE this is a block-mode SDIO transaction */
    TI_UINT32        uLength;            /* Length in byte */
    TI_UINT32        uHwAddr;            /* The device address to write to or read from */
    void *           pHostAddr;          /* The host buffer address to write from or read into */
    TI_BOOL          bMore;              /* If TRUE, indicates the lower driver to keep awake for more transactions */
} TTxnPart; 


/* The busDrv module Object */
typedef struct _TBusDrvObj
{
    TI_HANDLE	     hOs;		   	 
    TI_HANDLE	     hReport;

	TBusDrvTxnDoneCb fTxnDoneCb;         /* The callback to call upon full transaction completion. */
	TI_HANDLE        hCbHandle;          /* The callback handle */
    TTxnStruct *     pCurrTxn;           /* The transaction currently being processed */
    ETxnStatus       eCurrTxnStatus;     /* COMPLETE, PENDING or ERROR */
    TTxnPart         aTxnParts[MAX_TXN_PARTS]; /* The actual bus transactions of current transaction */
    TI_UINT32        uCurrTxnPartsNum;   /* Number of transaction parts composing the current transaction */
    TI_UINT32        uCurrTxnPartsCount; /* Number of transaction parts already executed */
    TI_UINT32        uCurrTxnPartsCountSync; /* Number of transaction parts completed in Sync mode (returned COMPLETE) */
    TI_UINT32        uBlkSizeShift;      /* In block-mode:  uBlkSize = (1 << uBlkSizeShift) = 512 bytes */
    TI_UINT32        uBlkSize;           /* In block-mode:  uBlkSize = (1 << uBlkSizeShift) = 512 bytes */
    TI_UINT32        uBlkSizeMask;       /* In block-mode:  uBlkSizeMask = uBlkSize - 1 = 0x1FF*/
    TI_UINT8 *       pDmaBuffer;         /* DMA-able buffer for buffering all write transactions */

} TBusDrvObj;


/************************************************************************
 * Internal functions prototypes
 ************************************************************************/
static void busDrv_PrepareTxnParts  (TBusDrvObj *pBusDrv, TTxnStruct *pTxn);
static void busDrv_SendTxnParts     (TBusDrvObj *pBusDrv);
static void busDrv_TxnDoneCb        (TI_HANDLE hBusDrv, TI_INT32 status);
 


/************************************************************************
 *
 *   Module functions implementation
 *
 ************************************************************************/

/** 
 * \fn     busDrv_Create 
 * \brief  Create the module
 * 
 * Create and clear the bus driver's object, and the SDIO-adapter.
 * 
 * \note   
 * \param  hOs - Handle to Os Abstraction Layer
 * \return Handle of the allocated object, NULL if allocation failed 
 * \sa     busDrv_Destroy
 */ 
TI_HANDLE busDrv_Create (TI_HANDLE hOs)
{
    TI_HANDLE   hBusDrv;
    TBusDrvObj *pBusDrv;

    hBusDrv = os_memoryAlloc(hOs, sizeof(TBusDrvObj));
    if (hBusDrv == NULL)
    {
        return NULL;
    }
    
    pBusDrv = (TBusDrvObj *)hBusDrv;

    os_memoryZero(hOs, hBusDrv, sizeof(TBusDrvObj));
    
    pBusDrv->hOs = hOs;

    return pBusDrv;
}


/** 
 * \fn     busDrv_Destroy
 * \brief  Destroy the module. 
 * 
 * Close SDIO lower bus driver and free the module's object.
 * 
 * \note   
 * \param  The module's object
 * \return TI_OK on success or TI_NOK on failure 
 * \sa     busDrv_Create
 */ 
TI_STATUS busDrv_Destroy (TI_HANDLE hBusDrv)
{
    TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;

    if (pBusDrv)
    {
        os_memoryFree (pBusDrv->hOs, pBusDrv, sizeof(TBusDrvObj));     
    }
    return TI_OK;
}


/** 
 * \fn     busDrv_Init
 * \brief  Init bus driver 
 * 
 * Init module parameters.

 * \note   
 * \param  hBusDrv - The module's handle
 * \param  hReport - report module handle
 * \return void
 * \sa     
 */ 
void busDrv_Init (TI_HANDLE hBusDrv, TI_HANDLE hReport)
{
    TBusDrvObj *pBusDrv = (TBusDrvObj*) hBusDrv;

    pBusDrv->hReport = hReport;
}


/** 
 * \fn     busDrv_ConnectBus
 * \brief  Configure bus driver
 * 
 * Called by TxnQ.
 * Configure the bus driver with its connection configuration (such as baud-rate, bus width etc) 
 *     and establish the physical connection. 
 * Done once upon init (and not per functional driver startup). 
 * 
 * \note   
 * \param  hBusDrv    - The module's object
 * \param  pBusDrvCfg - A union used for per-bus specific configuration. 
 * \param  fCbFunc    - CB function for Async transaction completion (after all txn parts are completed).
 * \param  hCbArg     - The CB function handle
 * \return TI_OK / TI_NOK
 * \sa     
 */ 
TI_STATUS busDrv_ConnectBus (TI_HANDLE        hBusDrv, 
                             TBusDrvCfg       *pBusDrvCfg,
                             TBusDrvTxnDoneCb fCbFunc,
                             TI_HANDLE        hCbArg,
                             TBusDrvTxnDoneCb fConnectCbFunc)
{
    TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
    int         iStatus;

    /* Save the parameters (TxnQ callback for TxnDone events, and block-size) */
    pBusDrv->fTxnDoneCb    = fCbFunc;
    pBusDrv->hCbHandle     = hCbArg;
    pBusDrv->uBlkSizeShift = pBusDrvCfg->tSdioCfg.uBlkSizeShift;
    pBusDrv->uBlkSize      = 1 << pBusDrv->uBlkSizeShift;
    pBusDrv->uBlkSizeMask  = pBusDrv->uBlkSize - 1;
    /* This should cover stop send Txn parts in recovery */
    pBusDrv->uCurrTxnPartsCount = 0;
    pBusDrv->uCurrTxnPartsNum = 0;
    pBusDrv->uCurrTxnPartsCountSync = 0;

	
    /*
     * Configure the SDIO driver parameters and handle SDIO enumeration.
     *
     * Note: The DMA-able buffer address to use for write transactions is provided from the 
     *           SDIO driver into pBusDrv->pDmaBuffer.
     */
    iStatus = sdioAdapt_ConnectBus (busDrv_TxnDoneCb, 
                                    hBusDrv, 
                                    pBusDrv->uBlkSizeShift, 
                                    pBusDrvCfg->tSdioCfg.uBusDrvThreadPriority,
                                    &pBusDrv->pDmaBuffer);

    if (pBusDrv->pDmaBuffer == NULL)
    {
        TRACE0(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "busDrv_ConnectBus: Didn't get DMA buffer from SDIO driver!!");
        return TI_NOK;
    }


    if (iStatus == 0) 
    {
        return TI_OK;
    }
    else 
    {
        TRACE2(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "busDrv_ConnectBus: Status = 0x%x, BlkSize = %d\n", iStatus, pBusDrv->uBlkSize);
        return TI_NOK;
    }
}


/** 
 * \fn     busDrv_DisconnectBus
 * \brief  Disconnect SDIO driver
 * 
 * Called by TxnQ. Disconnect the SDIO driver.
 *  
 * \note   
 * \param  hBusDrv - The module's object
 * \return TI_OK / TI_NOK
 * \sa     
 */ 
TI_STATUS busDrv_DisconnectBus (TI_HANDLE hBusDrv)
{
    TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;

    TRACE0(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_DisconnectBus()\n");

    /* Disconnect SDIO driver */
    return sdioAdapt_DisconnectBus ();
}


/** 
 * \fn     busDrv_Transact
 * \brief  Process transaction 
 * 
 * Called by the TxnQ module to initiate a new transaction.
 * Prepare the transaction parts (lower layer single transactions),
 *      and send them one by one to the lower layer.
 * 
 * \note   It's assumed that this function is called only when idle (i.e. previous Txn is done).
 * \param  hBusDrv - The module's object
 * \param  pTxn    - The transaction object 
 * \return COMPLETE if Txn completed in this context, PENDING if not, ERROR if failed
 * \sa     busDrv_PrepareTxnParts, busDrv_SendTxnParts
 */ 
ETxnStatus busDrv_Transact (TI_HANDLE hBusDrv, TTxnStruct *pTxn)
{
    TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
    CL_TRACE_START_L4();

    pBusDrv->pCurrTxn           = pTxn;
    pBusDrv->uCurrTxnPartsCount = 0;
    pBusDrv->uCurrTxnPartsCountSync = 0;

    /* Prepare the transaction parts in a table. */
    busDrv_PrepareTxnParts (pBusDrv, pTxn);

    /* Send the prepared transaction parts. */
    busDrv_SendTxnParts (pBusDrv);

    TRACE1(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_Transact: Status = %d\n", pBusDrv->eCurrTxnStatus);

    CL_TRACE_END_L4("tiwlan_drv.ko", "INHERIT", "TXN", ".Transact");

    /* return transaction status - COMPLETE, PENDING or ERROR */
    /* The status is updated in busDrv_SendTxnParts(). It is Async (pending) if not completed in this context */
    return pBusDrv->eCurrTxnStatus;
}


/** 
 * \fn     busDrv_PrepareTxnParts
 * \brief  Prepare write or read transaction parts
 * 
 * Called by busDrv_Transact().
 * Prepares the actual sequence of SDIO bus transactions in a table.
 * Use a DMA-able buffer for the bus transaction, so all data is copied
 *     to it from the host buffer(s) before write transactions,
 *     or copied from it to the host buffers after read transactions.
 * 
 * \note   
 * \param  pBusDrv - The module's object
 * \param  pTxn    - The transaction object 
 * \return void
 * \sa     busDrv_Transact, busDrv_SendTxnParts, 
 */ 
static void busDrv_PrepareTxnParts (TBusDrvObj *pBusDrv, TTxnStruct *pTxn)
{
    TI_UINT32 uPartNum = 0;
    TI_UINT32 uTxnLength   = 0;
    TI_UINT8 *pHostBuf     = pBusDrv->pDmaBuffer; /* Host buffer to use for actual transaction is the DMA buffer */
    TI_UINT32 uCurrHwAddr = pTxn->uHwAddr;
    TI_BOOL   bFixedHwAddr = TXN_PARAM_GET_FIXED_ADDR(pTxn);
    TI_UINT32 uBufNum;
    TI_UINT32 uBufLen;
    TI_UINT32 uRemainderLen;

    /* Go over the transaction buffers */
    for (uBufNum = 0; uBufNum < MAX_XFER_BUFS; uBufNum++) 
    {
        uBufLen = pTxn->aLen[uBufNum];

        /* If no more buffers, exit the loop */
        if (uBufLen == 0)
        {
            break;
        }

        /* For write transaction, copy the data to the DMA buffer */
        if (TXN_PARAM_GET_DIRECTION(pTxn) == TXN_DIRECTION_WRITE)
        {
            os_memoryCopy (pBusDrv->hOs, pHostBuf + uTxnLength, pTxn->aBuf[uBufNum], uBufLen);
        }

        /* Add buffer length to total transaction length */
        uTxnLength += uBufLen;
        }

        /* If current buffer has a remainder, prepare its transaction part */
        uRemainderLen = uTxnLength & pBusDrv->uBlkSizeMask;
        if (uRemainderLen > 0)
        {
            pBusDrv->aTxnParts[uPartNum].bBlkMode  = TI_FALSE;
            pBusDrv->aTxnParts[uPartNum].uLength   = uRemainderLen;
            pBusDrv->aTxnParts[uPartNum].uHwAddr   = uCurrHwAddr;
            pBusDrv->aTxnParts[uPartNum].pHostAddr = (void *)pHostBuf;
            pBusDrv->aTxnParts[uPartNum].bMore     = TI_TRUE;

            /* If not fixed HW address, increment it by this part's size */
            if (!bFixedHwAddr)
            {
                uCurrHwAddr += uRemainderLen;
            }

            uPartNum++;
        }

        /*  SDIO block-mode doesn't work on PG1.0 so split to 512 bytes blocks! 
           Remove when PG1.0 is obsolete! */
        if (bChipIs1273Pg10)
        {
            TI_UINT32 uLen;

            for (uLen = uRemainderLen; uLen < uTxnLength; uLen += pBusDrv->uBlkSize)
    		{
    			pBusDrv->aTxnParts[uPartNum].bBlkMode  = TI_FALSE;
    			pBusDrv->aTxnParts[uPartNum].uLength   = pBusDrv->uBlkSize;
    			pBusDrv->aTxnParts[uPartNum].uHwAddr   = uCurrHwAddr;
                pBusDrv->aTxnParts[uPartNum].pHostAddr = (void *)(pHostBuf + uLen);
    			pBusDrv->aTxnParts[uPartNum].bMore     = TI_TRUE;
    
    			/* If not fixed HW address, increment it by this part's size */
    			if (!bFixedHwAddr)
    			{
    				uCurrHwAddr += pBusDrv->uBlkSize;
    			}
    
    			uPartNum++;
    		}
        }


        /* For PG2.0, use SDIO block mode */
        else 
        {
            /* If current buffer has full SDIO blocks, prepare a block-mode transaction part */
            if (uTxnLength >= pBusDrv->uBlkSize)
            {
                pBusDrv->aTxnParts[uPartNum].bBlkMode  = TI_TRUE;
                pBusDrv->aTxnParts[uPartNum].uLength   = uTxnLength - uRemainderLen;
                pBusDrv->aTxnParts[uPartNum].uHwAddr   = uCurrHwAddr;
                pBusDrv->aTxnParts[uPartNum].pHostAddr = (void *)(pHostBuf + uRemainderLen);
                pBusDrv->aTxnParts[uPartNum].bMore     = TI_TRUE;
    
                uPartNum++;
        }
    }

    /* Set last More flag as specified for the whole Txn */
    pBusDrv->aTxnParts[uPartNum - 1].bMore = TXN_PARAM_GET_MORE(pTxn);
    pBusDrv->uCurrTxnPartsNum = uPartNum;
}


/** 
 * \fn     busDrv_SendTxnParts
 * \brief  Send prepared transaction parts
 * 
 * Called first by busDrv_Transact(), and also from TxnDone CB after Async completion.
 * Sends the prepared transaction parts in a loop.
 * If a transaction part is Async, the loop continues later in the TxnDone ISR context.
 * When all parts are done, the upper layer TxnDone CB is called.
 * 
 * \note   
 * \param  pBusDrv - The module's object
 * \return void
 * \sa     busDrv_Transact, busDrv_PrepareTxnParts
 */ 
static void busDrv_SendTxnParts (TBusDrvObj *pBusDrv)
{
    ETxnStatus  eStatus;
    TTxnPart   *pTxnPart;
    TTxnStruct *pTxn = pBusDrv->pCurrTxn;

    /* While there are transaction parts to send */
    while (pBusDrv->uCurrTxnPartsCount < pBusDrv->uCurrTxnPartsNum)
    {
        pTxnPart = &(pBusDrv->aTxnParts[pBusDrv->uCurrTxnPartsCount]);
        pBusDrv->uCurrTxnPartsCount++;

        /* Assume pending to be ready in case we are preempted by the TxnDon CB !! */
        pBusDrv->eCurrTxnStatus = TXN_STATUS_PENDING;   

        /* If single step, send ELP byte */
        if (TXN_PARAM_GET_SINGLE_STEP(pTxn)) 
        {
            /* Overwrite the function id with function 0 - for ELP register !!!! */
            eStatus = sdioAdapt_TransactBytes (TXN_FUNC_ID_CTRL,
                                               pTxnPart->uHwAddr,
                                               pTxnPart->pHostAddr,
                                               pTxnPart->uLength,
                                               TXN_PARAM_GET_DIRECTION(pTxn),
                                               pTxnPart->bMore);

            /* If first write failed try once again (may happen once upon chip wakeup) */
            if (eStatus == TXN_STATUS_ERROR)
            {
                /* Overwrite the function id with function 0 - for ELP register !!!! */
                eStatus = sdioAdapt_TransactBytes (TXN_FUNC_ID_CTRL,
                                                   pTxnPart->uHwAddr,
                                                   pTxnPart->pHostAddr,
                                                   pTxnPart->uLength,
                                                   TXN_PARAM_GET_DIRECTION(pTxn),
                                                   pTxnPart->bMore);
                TRACE0(pBusDrv->hReport, REPORT_SEVERITY_WARNING, "busDrv_SendTxnParts: SDIO Single-Step transaction failed once so try again");
            }
        }
        else
        {
            eStatus = sdioAdapt_Transact (TXN_PARAM_GET_FUNC_ID(pTxn),
                                          pTxnPart->uHwAddr,
                                          pTxnPart->pHostAddr,
                                          pTxnPart->uLength,
                                          TXN_PARAM_GET_DIRECTION(pTxn),
                                          pTxnPart->bBlkMode,
                                          ((TXN_PARAM_GET_FIXED_ADDR(pTxn) == 1) ? 0 : 1),
                                          pTxnPart->bMore);
        }

        TRACE7(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_SendTxnParts: PartNum = %d, SingleStep = %d, Direction = %d, HwAddr = 0x%x, HostAddr = 0x%x, Length = %d, BlkMode = %d\n", pBusDrv->uCurrTxnPartsCount-1, TXN_PARAM_GET_SINGLE_STEP(pTxn), TXN_PARAM_GET_DIRECTION(pTxn), pTxnPart->uHwAddr, pTxnPart->pHostAddr, pTxnPart->uLength, pTxnPart->bBlkMode);

        /* If pending TxnDone (Async), continue this loop in the next TxnDone interrupt */
        if (eStatus == TXN_STATUS_PENDING)
        {
            return; 
        }

        /* Update current transaction status to deduce if it is all finished in the original context (Sync) or not. */
        pBusDrv->eCurrTxnStatus = eStatus;
        pBusDrv->uCurrTxnPartsCountSync++;

        /* If error, set error in Txn struct, call TxnDone CB if not fully sync, and exit */
        if (eStatus == TXN_STATUS_ERROR)
        {
            TXN_PARAM_SET_STATUS(pTxn, TXN_PARAM_STATUS_ERROR);
            if (pBusDrv->uCurrTxnPartsCountSync != pBusDrv->uCurrTxnPartsCount)
            {
                pBusDrv->fTxnDoneCb (pBusDrv->hCbHandle, pTxn);
            }
        	return;
        }
    }

    /* If we got here we sent all buffers and we don't pend transaction end */
    TRACE3(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_SendTxnParts: Txn finished successfully, Status = %d, PartsCount = %d, SyncCount = %d\n", pBusDrv->eCurrTxnStatus, pBusDrv->uCurrTxnPartsCount, pBusDrv->uCurrTxnPartsCountSync);

    /* For read transaction, copy the data from the DMA-able buffer to the host buffer(s) */
    if (TXN_PARAM_GET_DIRECTION(pTxn) == TXN_DIRECTION_READ)
    {
        TI_UINT32 uBufNum;
        TI_UINT32 uBufLen;
        TI_UINT8 *pDmaBuf = pBusDrv->pDmaBuffer; /* After the read transaction the data is in the DMA buffer */

        for (uBufNum = 0; uBufNum < MAX_XFER_BUFS; uBufNum++)
        {
            uBufLen = pTxn->aLen[uBufNum];

            /* If no more buffers, exit the loop */
            if (uBufLen == 0)
            {
                break;
            }

            os_memoryCopy (pBusDrv->hOs, pTxn->aBuf[uBufNum], pDmaBuf, uBufLen);
            pDmaBuf += uBufLen;
        }
    }

    /* Set status OK in Txn struct, and call TxnDone CB if not fully sync */
    TXN_PARAM_SET_STATUS(pTxn, TXN_PARAM_STATUS_OK);
    if (pBusDrv->uCurrTxnPartsCountSync != pBusDrv->uCurrTxnPartsCount)
    {
        pBusDrv->fTxnDoneCb (pBusDrv->hCbHandle, pTxn);
    }
}


/** 
 * \fn     busDrv_TxnDoneCb
 * \brief  Continue async transaction processing (CB)
 * 
 * Called back by the lower (BSP) bus-driver upon Async transaction completion (TxnDone ISR).
 * Call busDrv_SendTxnParts to continue sending the remained transaction parts.
 * 
 * \note   
 * \param  hBusDrv - The module's object
 * \param  status  - The last transaction result - 0 = OK, else Error
 * \return void
 * \sa     busDrv_SendTxnParts
 */ 
static void busDrv_TxnDoneCb (TI_HANDLE hBusDrv, int iStatus)
{
    TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
    CL_TRACE_START_L1();

    /* If last transaction part failed, set error in Txn struct, call TxnDone CB and exit. */
    if (iStatus != 0)
    {
        TRACE1(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "busDrv_TxnDoneCb: Status = 0x%x\n", iStatus);

        TXN_PARAM_SET_STATUS(pBusDrv->pCurrTxn, TXN_PARAM_STATUS_ERROR);
        pBusDrv->fTxnDoneCb (pBusDrv->hCbHandle, pBusDrv->pCurrTxn);
        CL_TRACE_END_L1("tiwlan_drv.ko", "TXN_DONE", "BusDrvCB", "");
        return;
    }

    TRACE0(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_TxnDoneCb()\n");

    /* Continue sending the remained transaction parts. */
    busDrv_SendTxnParts (pBusDrv);

    CL_TRACE_END_L1("tiwlan_drv.ko", "TXN_DONE", "BusDrvCB", "");
}
