summaryrefslogtreecommitdiff
path: root/wilink_6_1/Txn
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2009-05-12 12:22:02 -0700
committerDmitry Shmidt <dimitrysh@google.com>2009-05-12 12:22:02 -0700
commit981801b95b81e6d1c7a2085967406e86af0f08fc (patch)
tree3cf403b311a43d23c0b605827913f9637b136763 /wilink_6_1/Txn
parent02d7515eca810acbc93be9324751d712af6d38c7 (diff)
downloadti-981801b95b81e6d1c7a2085967406e86af0f08fc.tar.gz
Initial code package of WiLink_Driver_6.1.0.0.84
Diffstat (limited to 'wilink_6_1/Txn')
-rw-r--r--wilink_6_1/Txn/BusDrv.h178
-rw-r--r--wilink_6_1/Txn/SdioBusDrv.c532
-rw-r--r--wilink_6_1/Txn/TxnDefs.h79
-rw-r--r--wilink_6_1/Txn/TxnQueue.c807
-rw-r--r--wilink_6_1/Txn/TxnQueue.h244
-rw-r--r--wilink_6_1/Txn/WspiBusDrv.c399
6 files changed, 2239 insertions, 0 deletions
diff --git a/wilink_6_1/Txn/BusDrv.h b/wilink_6_1/Txn/BusDrv.h
new file mode 100644
index 0000000..cb6d13a
--- /dev/null
+++ b/wilink_6_1/Txn/BusDrv.h
@@ -0,0 +1,178 @@
+/*
+ * BusDrv.h
+ *
+ * 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 BusDrv.h
+ * \brief Bus-Driver module API definition
+ *
+ * \see SdioBusDrv.c, WspiBusDrv.c
+ */
+
+#ifndef __BUS_DRV_API_H__
+#define __BUS_DRV_API_H__
+
+
+#include "TxnDefs.h"
+#include "queue.h"
+
+
+/************************************************************************
+ * Defines
+ ************************************************************************/
+
+#define WSPI_PAD_LEN_WRITE 4
+#define WSPI_PAD_LEN_READ 8
+#define MAX_XFER_BUFS 4
+
+#define TXN_PARAM_STATUS_OK 0
+#define TXN_PARAM_STATUS_ERROR 1
+#define TXN_PARAM_STATUS_RECOVERY 2
+
+#define TXN_DIRECTION_WRITE 0
+#define TXN_DIRECTION_READ 1
+
+#define TXN_HIGH_PRIORITY 0
+#define TXN_LOW_PRIORITY 1
+#define TXN_NUM_PRIORITYS 2
+
+#define TXN_INC_ADDR 0
+#define TXN_FIXED_ADDR 1
+#define TXN_NON_SLEEP_ELP 1
+#define TXN_SLEEP_ELP 0
+
+/************************************************************************
+ * Macros
+ ************************************************************************/
+/* Get field from TTxnStruct->uTxnParams */
+#define TXN_PARAM_GET_PRIORITY(pTxn) ( (pTxn->uTxnParams & 0x00000003) >> 0 )
+#define TXN_PARAM_GET_FUNC_ID(pTxn) ( (pTxn->uTxnParams & 0x0000000C) >> 2 )
+#define TXN_PARAM_GET_DIRECTION(pTxn) ( (pTxn->uTxnParams & 0x00000010) >> 4 )
+#define TXN_PARAM_GET_FIXED_ADDR(pTxn) ( (pTxn->uTxnParams & 0x00000020) >> 5 )
+#define TXN_PARAM_GET_MORE(pTxn) ( (pTxn->uTxnParams & 0x00000040) >> 6 )
+#define TXN_PARAM_GET_SINGLE_STEP(pTxn) ( (pTxn->uTxnParams & 0x00000080) >> 7 )
+#define TXN_PARAM_GET_STATUS(pTxn) ( (pTxn->uTxnParams & 0x00000F00) >> 8 )
+
+/* Set field in TTxnStruct->uTxnParams */
+#define TXN_PARAM_SET_PRIORITY(pTxn, uValue) ( pTxn->uTxnParams = (pTxn->uTxnParams & ~0x00000003) | (uValue << 0 ) )
+#define TXN_PARAM_SET_FUNC_ID(pTxn, uValue) ( pTxn->uTxnParams = (pTxn->uTxnParams & ~0x0000000C) | (uValue << 2 ) )
+#define TXN_PARAM_SET_DIRECTION(pTxn, uValue) ( pTxn->uTxnParams = (pTxn->uTxnParams & ~0x00000010) | (uValue << 4 ) )
+#define TXN_PARAM_SET_FIXED_ADDR(pTxn, uValue) ( pTxn->uTxnParams = (pTxn->uTxnParams & ~0x00000020) | (uValue << 5 ) )
+#define TXN_PARAM_SET_MORE(pTxn, uValue) ( pTxn->uTxnParams = (pTxn->uTxnParams & ~0x00000040) | (uValue << 6 ) )
+#define TXN_PARAM_SET_SINGLE_STEP(pTxn, uValue) ( pTxn->uTxnParams = (pTxn->uTxnParams & ~0x00000080) | (uValue << 7 ) )
+#define TXN_PARAM_SET_STATUS(pTxn, uValue) ( pTxn->uTxnParams = (pTxn->uTxnParams & ~0x00000F00) | (uValue << 8 ) )
+
+#define TXN_PARAM_SET(pTxn, uPriority, uId, uDirection, uAddr) \
+ TXN_PARAM_SET_PRIORITY(pTxn, uPriority); \
+ TXN_PARAM_SET_FUNC_ID(pTxn, uId); \
+ TXN_PARAM_SET_DIRECTION(pTxn, uDirection); \
+ TXN_PARAM_SET_FIXED_ADDR(pTxn, uAddr);
+
+#define BUILD_TTxnStruct(pTxn, uAddr, pBuf, uLen, fCB, hCB) \
+ pTxn->aBuf[0] = (TI_UINT8*)(pBuf); \
+ pTxn->aLen[0] = (TI_UINT16)(uLen); \
+ pTxn->aLen[1] = 0; \
+ pTxn->uHwAddr = uAddr; \
+ pTxn->hCbHandle = (void*)hCB; \
+ pTxn->fTxnDoneCb = (void*)fCB;
+
+
+/************************************************************************
+ * Types
+ ************************************************************************/
+/* The TxnDone CB called by the bus driver upon Async Txn completion */
+typedef void (*TBusDrvTxnDoneCb)(TI_HANDLE hCbHandle, void *pTxn);
+
+/* The TxnDone CB called by the TxnQueue upon Async Txn completion */
+typedef void (*TTxnQueueDoneCb)(TI_HANDLE hCbHandle, void *pTxn);
+
+/* The TxnDone CB of the specific Txn originator (Xfer layer) called upon Async Txn completion */
+typedef void (*TTxnDoneCb)(TI_HANDLE hCbHandle, void *pTxn);
+
+/* The transactions structure */
+typedef struct
+{
+ TQueNodeHdr tTxnQNode; /* Header for queueing */
+ TI_UINT32 uTxnParams; /* Txn attributes (bit fields) - see macros above */
+ TI_UINT32 uHwAddr; /* Physical (32 bits) HW Address */
+ TTxnDoneCb fTxnDoneCb; /* CB called by TwIf upon Async Txn completion (may be NULL) */
+ TI_HANDLE hCbHandle; /* The handle to use when calling fTxnDoneCb */
+ TI_UINT16 aLen[MAX_XFER_BUFS]; /* Lengths of the following aBuf data buffers respectively.
+ Zero length marks last used buffer, or MAX_XFER_BUFS of all are used. */
+ TI_UINT8* aBuf[MAX_XFER_BUFS]; /* Host data buffers to be written to or read from the device */
+ TI_UINT8 aWspiPad[WSPI_PAD_LEN_READ]; /* Padding used by WSPI bus driver for its header or fixed-busy bytes */
+
+} TTxnStruct;
+
+/* Parameters for all bus types configuration in ConnectBus process */
+
+typedef struct
+{
+ TI_UINT32 uBlkSizeShift;
+ TI_UINT32 uBusDrvThreadPriority;
+} TSdioCfg;
+
+typedef struct
+{
+ TI_UINT32 uDummy;
+} TWspiCfg;
+
+typedef struct
+{
+ TI_UINT32 uBaudRate;
+} TUartCfg;
+
+typedef union
+{
+ TSdioCfg tSdioCfg;
+ TWspiCfg tWspiCfg;
+ TUartCfg tUartCfg;
+
+} TBusDrvCfg;
+
+
+/************************************************************************
+ * Functions
+ ************************************************************************/
+TI_HANDLE busDrv_Create (TI_HANDLE hOs);
+TI_STATUS busDrv_Destroy (TI_HANDLE hBusDrv);
+void busDrv_Init (TI_HANDLE hBusDrv, TI_HANDLE hReport);
+TI_STATUS busDrv_ConnectBus (TI_HANDLE hBusDrv,
+ TBusDrvCfg *pBusDrvCfg,
+ TBusDrvTxnDoneCb fCbFunc,
+ TI_HANDLE hCbArg,
+ TBusDrvTxnDoneCb fConnectCbFunc);
+TI_STATUS busDrv_DisconnectBus (TI_HANDLE hBusDrv);
+ETxnStatus busDrv_Transact (TI_HANDLE hBusDrv, TTxnStruct *pTxn);
+
+#endif /*__BUS_DRV_API_H__*/
+
diff --git a/wilink_6_1/Txn/SdioBusDrv.c b/wilink_6_1/Txn/SdioBusDrv.c
new file mode 100644
index 0000000..7152189
--- /dev/null
+++ b/wilink_6_1/Txn/SdioBusDrv.c
@@ -0,0 +1,532 @@
+/*
+ * 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*/
+
+} 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 */
+ iStatus = sdioAdapt_ConnectBus (busDrv_TxnDoneCb,
+ hBusDrv,
+ pBusDrv->uBlkSizeShift,
+ pBusDrvCfg->tSdioCfg.uBusDrvThreadPriority);
+
+ 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.
+ *
+ * \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 uBufNum;
+ TI_UINT32 uPartNum = 0;
+ TI_UINT32 uRemainderLen;
+ TI_UINT32 uCurrHwAddr = pTxn->uHwAddr;
+ TI_BOOL bFixedHwAddr = TXN_PARAM_GET_FIXED_ADDR(pTxn);
+
+ /* For all occupied buffers in current transaction do */
+ for (uBufNum = 0; uBufNum < MAX_XFER_BUFS; uBufNum++)
+ {
+ /* If no more buffers, exit the for loop */
+ if (pTxn->aLen[uBufNum] == 0)
+ {
+ break;
+ }
+
+ /* If current buffer has a remainder, prepare its transaction part */
+ uRemainderLen = pTxn->aLen[uBufNum] & 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 *)(pTxn->aBuf[uBufNum]);
+ 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 < pTxn->aLen[uBufNum]; 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 *)(pTxn->aBuf[uBufNum] + 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 (pTxn->aLen[uBufNum] >= pBusDrv->uBlkSize)
+ {
+ pBusDrv->aTxnParts[uPartNum].bBlkMode = TI_TRUE;
+ pBusDrv->aTxnParts[uPartNum].uLength = pTxn->aLen[uBufNum] - uRemainderLen;
+ pBusDrv->aTxnParts[uPartNum].uHwAddr = uCurrHwAddr;
+ pBusDrv->aTxnParts[uPartNum].pHostAddr = (void *)(pTxn->aBuf[uBufNum] + uRemainderLen);
+ pBusDrv->aTxnParts[uPartNum].bMore = TI_TRUE;
+
+ /* If not fixed HW address, increment it by this part's size */
+ if (!bFixedHwAddr)
+ {
+ uCurrHwAddr += pTxn->aLen[uBufNum] - uRemainderLen;
+ }
+
+ 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;
+
+ /* 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(pBusDrv->pCurrTxn))
+ {
+ /* 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(pBusDrv->pCurrTxn),
+ pTxnPart->bMore);
+ }
+ else
+ {
+ eStatus = sdioAdapt_Transact (TXN_PARAM_GET_FUNC_ID(pBusDrv->pCurrTxn),
+ pTxnPart->uHwAddr,
+ pTxnPart->pHostAddr,
+ pTxnPart->uLength,
+ TXN_PARAM_GET_DIRECTION(pBusDrv->pCurrTxn),
+ pTxnPart->bBlkMode,
+ ((TXN_PARAM_GET_FIXED_ADDR(pBusDrv->pCurrTxn)==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(pBusDrv->pCurrTxn), TXN_PARAM_GET_DIRECTION(pBusDrv->pCurrTxn), 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(pBusDrv->pCurrTxn, TXN_PARAM_STATUS_ERROR);
+ if (pBusDrv->uCurrTxnPartsCountSync != pBusDrv->uCurrTxnPartsCount)
+ {
+ pBusDrv->fTxnDoneCb (pBusDrv->hCbHandle, pBusDrv->pCurrTxn);
+ }
+ 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);
+
+ /* Set status OK in Txn struct, and call TxnDone CB if not fully sync */
+ TXN_PARAM_SET_STATUS(pBusDrv->pCurrTxn, TXN_PARAM_STATUS_OK);
+ if (pBusDrv->uCurrTxnPartsCountSync != pBusDrv->uCurrTxnPartsCount)
+ {
+ pBusDrv->fTxnDoneCb (pBusDrv->hCbHandle, pBusDrv->pCurrTxn);
+ }
+}
+
+
+/**
+ * \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", "");
+}
+
+
+
diff --git a/wilink_6_1/Txn/TxnDefs.h b/wilink_6_1/Txn/TxnDefs.h
new file mode 100644
index 0000000..68f7c3a
--- /dev/null
+++ b/wilink_6_1/Txn/TxnDefs.h
@@ -0,0 +1,79 @@
+/*
+ * TxnDefs.h
+ *
+ * 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 TxnDefs.h
+ * \brief Common TXN definitions
+ *
+ * These defintions are used also by the SDIO/SPI adapters, so they shouldn't
+ * base on any non-standart types (e.g. use unsigned int and not TI_UINT32)
+ *
+ * \see
+ */
+
+#ifndef __TXN_DEFS_API_H__
+#define __TXN_DEFS_API_H__
+
+
+/************************************************************************
+ * Defines
+ ************************************************************************/
+#define TXN_FUNC_ID_CTRL 0
+#define TXN_FUNC_ID_BT 1
+#define TXN_FUNC_ID_WLAN 2
+
+
+/************************************************************************
+ * Types
+ ************************************************************************/
+/* Transactions status (shouldn't override TI_OK and TI_NOK values) */
+/** \enum ETxnStatus
+ * \brief Txn Transactions status
+ *
+ * \par Description
+ * Txn Transactions status - shouldn't override TI_OK and TI_NOK values
+ *
+ * \sa
+ */
+typedef enum
+{
+ TXN_STATUS_NONE = 2, /**< */
+ TXN_STATUS_OK, /**< */
+ TXN_STATUS_COMPLETE, /**< */
+ TXN_STATUS_PENDING, /**< */
+ TXN_STATUS_ERROR /**< */
+
+} ETxnStatus;
+
+
+#endif /*__TXN_DEFS_API_H__*/
diff --git a/wilink_6_1/Txn/TxnQueue.c b/wilink_6_1/Txn/TxnQueue.c
new file mode 100644
index 0000000..5be7112
--- /dev/null
+++ b/wilink_6_1/Txn/TxnQueue.c
@@ -0,0 +1,807 @@
+/*
+ * TxnQueue.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 TxnQueue.c
+ * \brief The transaction-queue module.
+ *
+ * The Transaction Queue encapsulates the bus access from a functional driver (WLAN, BT).
+ * This TI proprietary module presents the same interface and same behavior for different
+ * bus configuration: SDIO (multi or single function) or SPI and for different modes
+ * of operation: Synchronous, a-synchronous or combination of both.
+ * It will also be used over the RS232 interface (using wUART protocol) which is applicable
+ * for RS applications (on PC).
+ *
+ * The TxnQ module provides the following requirements:
+ * Inter process protection on queue's internal database and synchronization between
+ * functional drivers that share the bus.
+ * Support multiple queues per function, handled by priority.
+ * Support the TTxnStruct API (as the Bus Driver) with the ability to manage commands
+ * queuing of multiple functions on top of the Bus Driver.
+ * The TxnQ (as well as the layers above it) is agnostic to the bus driver used beneath it
+ * (SDIO, WSPI or wUART), since all bus drivers introduce the same API and hide bus details.
+ * The TxnQ has no OS dependencies. It supports access from multiple OS threads.
+ * Note: It is assumed that any transaction forwarded to the TxnQ has enough resources in HW.
+ *
+ * \see TxnQueue.h
+ */
+
+#define __FILE_ID__ FILE_ID_123
+#include "tidef.h"
+#include "report.h"
+#include "context.h"
+#include "osApi.h"
+#include "TxnDefs.h"
+#include "BusDrv.h"
+#include "TxnQueue.h"
+
+
+
+/************************************************************************
+ * Defines
+ ************************************************************************/
+#define MAX_FUNCTIONS 4 /* Maximum 4 functional drivers (including Func 0 which is for bus control) */
+#define MAX_PRIORITY 2 /* Maximum 2 prioritys per functional driver */
+#define TXN_QUE_SIZE 64 /* Txn-queue size */
+#define TXN_DONE_QUE_SIZE 64 /* TxnDone-queue size */
+
+
+/************************************************************************
+ * Types
+ ************************************************************************/
+
+/* Functional driver's SM States */
+typedef enum
+{
+ FUNC_STATE_NONE, /* Function not registered */
+ FUNC_STATE_STOPPED, /* Queues are stopped */
+ FUNC_STATE_RUNNING, /* Queues are running */
+ FUNC_STATE_RESTART /* Wait for current Txn to finish before restarting queues */
+} EFuncState;
+
+/* The functional drivers registered to TxnQ */
+typedef struct
+{
+ EFuncState eState; /* Function crrent state */
+ TI_UINT32 uNumPrios; /* Number of queues (priorities) for this function */
+ TTxnQueueDoneCb fTxnQueueDoneCb; /* The CB called by the TxnQueue upon full transaction completion. */
+ TI_HANDLE hCbHandle; /* The callback handle */
+ TTxnStruct * pSingleStep; /* A single step transaction waiting to be sent */
+
+} TFuncInfo;
+
+
+/* The TxnQueue module Object */
+typedef struct _TTxnQObj
+{
+ TI_HANDLE hOs;
+ TI_HANDLE hReport;
+ TI_HANDLE hContext;
+ TI_HANDLE hBusDrv;
+
+ TFuncInfo aFuncInfo[MAX_FUNCTIONS]; /* Registered functional drivers - see above */
+ TI_HANDLE aTxnQueues[MAX_FUNCTIONS][MAX_PRIORITY]; /* Handle of the Transactions-Queue */
+ TI_HANDLE hTxnDoneQueue; /* Queue for completed transactions not reported to yet to the upper layer */
+ TTxnStruct * pCurrTxn; /* The transaction currently processed in the bus driver (NULL if none) */
+ TI_UINT32 uMinFuncId; /* The minimal function ID actually registered (through txnQ_Open) */
+ TI_UINT32 uMaxFuncId; /* The maximal function ID actually registered (through txnQ_Open) */
+ TI_BOOL bSchedulerBusy; /* If set, the scheduler is currently running so it shouldn't be reentered */
+ TI_BOOL bSchedulerPend; /* If set, a call to the scheduler was postponed because it was busy */
+
+ /* Environment dependent: TRUE if needed and allowed to protect TxnDone in critical section */
+ TTxnDoneCb fConnectCb;
+ TI_HANDLE hConnectCb;
+
+} TTxnQObj;
+
+
+/************************************************************************
+ * Internal functions prototypes
+ ************************************************************************/
+static void txnQ_TxnDoneCb (TI_HANDLE hTxnQ, void *hTxn);
+static ETxnStatus txnQ_RunScheduler (TTxnQObj *pTxnQ, TTxnStruct *pInputTxn);
+static ETxnStatus txnQ_Scheduler (TTxnQObj *pTxnQ, TTxnStruct *pInputTxn);
+static TTxnStruct *txnQ_SelectTxn (TTxnQObj *pTxnQ);
+static void txnQ_ClearQueues (TTxnQObj *pTxnQ, TI_UINT32 uFuncId);
+static void txnQ_ConnectCB (TI_HANDLE hTxnQ, void *hTxn);
+
+
+
+/************************************************************************
+ *
+ * Module functions implementation
+ *
+ ************************************************************************/
+
+TI_HANDLE txnQ_Create (TI_HANDLE hOs)
+{
+ TI_HANDLE hTxnQ;
+ TTxnQObj *pTxnQ;
+ TI_UINT32 i;
+
+ hTxnQ = os_memoryAlloc(hOs, sizeof(TTxnQObj));
+ if (hTxnQ == NULL)
+ return NULL;
+
+ pTxnQ = (TTxnQObj *)hTxnQ;
+
+ os_memoryZero(hOs, hTxnQ, sizeof(TTxnQObj));
+
+ pTxnQ->hOs = hOs;
+ pTxnQ->pCurrTxn = NULL;
+ pTxnQ->uMinFuncId = MAX_FUNCTIONS; /* Start at maximum and save minimal value in txnQ_Open */
+ pTxnQ->uMaxFuncId = 0; /* Start at minimum and save maximal value in txnQ_Open */
+
+ for (i = 0; i < MAX_FUNCTIONS; i++)
+ {
+ pTxnQ->aFuncInfo[i].eState = FUNC_STATE_NONE;
+ pTxnQ->aFuncInfo[i].uNumPrios = 0;
+ pTxnQ->aFuncInfo[i].pSingleStep = NULL;
+ pTxnQ->aFuncInfo[i].fTxnQueueDoneCb = NULL;
+ pTxnQ->aFuncInfo[i].hCbHandle = NULL;
+ }
+
+ /* Create the Bus-Driver module */
+ pTxnQ->hBusDrv = busDrv_Create (hOs);
+ if (pTxnQ->hBusDrv == NULL)
+ {
+ WLAN_OS_REPORT(("%s: Error - failed to create BusDrv\n", __FUNCTION__));
+ txnQ_Destroy (hTxnQ);
+ return NULL;
+ }
+
+ return pTxnQ;
+}
+
+TI_STATUS txnQ_Destroy (TI_HANDLE hTxnQ)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*)hTxnQ;
+
+ if (pTxnQ)
+ {
+ if (pTxnQ->hBusDrv)
+ {
+ busDrv_Destroy (pTxnQ->hBusDrv);
+ }
+ if (pTxnQ->hTxnDoneQueue)
+ {
+ que_Destroy (pTxnQ->hTxnDoneQueue);
+ }
+ os_memoryFree (pTxnQ->hOs, pTxnQ, sizeof(TTxnQObj));
+ }
+ return TI_OK;
+}
+
+void txnQ_Init (TI_HANDLE hTxnQ, TI_HANDLE hOs, TI_HANDLE hReport, TI_HANDLE hContext)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*)hTxnQ;
+ TI_UINT32 uNodeHeaderOffset;
+
+ pTxnQ->hOs = hOs;
+ pTxnQ->hReport = hReport;
+ pTxnQ->hContext = hContext;
+
+ /* Create the TxnDone queue. */
+ uNodeHeaderOffset = TI_FIELD_OFFSET(TTxnStruct, tTxnQNode);
+ pTxnQ->hTxnDoneQueue = que_Create (pTxnQ->hOs, pTxnQ->hReport, TXN_DONE_QUE_SIZE, uNodeHeaderOffset);
+ if (pTxnQ->hTxnDoneQueue == NULL)
+ {
+ TRACE0(pTxnQ->hReport, REPORT_SEVERITY_ERROR, ": TxnDone queue creation failed!\n");
+ }
+
+ busDrv_Init (pTxnQ->hBusDrv, hReport);
+}
+
+TI_STATUS txnQ_ConnectBus (TI_HANDLE hTxnQ, TBusDrvCfg *pBusDrvCfg, TTxnDoneCb fConnectCb, TI_HANDLE hConnectCb)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*) hTxnQ;
+
+ TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_ConnectBus()\n");
+
+ pTxnQ->fConnectCb = fConnectCb;
+ pTxnQ->hConnectCb = hConnectCb;
+
+ return busDrv_ConnectBus (pTxnQ->hBusDrv, pBusDrvCfg, txnQ_TxnDoneCb, hTxnQ, txnQ_ConnectCB);
+}
+
+TI_STATUS txnQ_DisconnectBus (TI_HANDLE hTxnQ)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*) hTxnQ;
+
+ return busDrv_DisconnectBus (pTxnQ->hBusDrv);
+}
+
+TI_STATUS txnQ_Open (TI_HANDLE hTxnQ,
+ TI_UINT32 uFuncId,
+ TI_UINT32 uNumPrios,
+ TTxnQueueDoneCb fTxnQueueDoneCb,
+ TI_HANDLE hCbHandle)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*) hTxnQ;
+ TI_UINT32 uNodeHeaderOffset;
+ TI_UINT32 i;
+
+ if (uFuncId > MAX_FUNCTIONS || uNumPrios > MAX_PRIORITY)
+ {
+ TRACE2(pTxnQ->hReport, REPORT_SEVERITY_ERROR, ": Invalid Params! uFuncId = %d, uNumPrios = %d\n", uFuncId, uNumPrios);
+ return TI_NOK;
+ }
+
+ context_EnterCriticalSection (pTxnQ->hContext);
+
+ /* Save functional driver info */
+ pTxnQ->aFuncInfo[uFuncId].uNumPrios = uNumPrios;
+ pTxnQ->aFuncInfo[uFuncId].fTxnQueueDoneCb = fTxnQueueDoneCb;
+ pTxnQ->aFuncInfo[uFuncId].hCbHandle = hCbHandle;
+ pTxnQ->aFuncInfo[uFuncId].eState = FUNC_STATE_STOPPED;
+
+ /* Create the functional driver's queues. */
+ uNodeHeaderOffset = TI_FIELD_OFFSET(TTxnStruct, tTxnQNode);
+ for (i = 0; i < uNumPrios; i++)
+ {
+ pTxnQ->aTxnQueues[uFuncId][i] = que_Create (pTxnQ->hOs, pTxnQ->hReport, TXN_QUE_SIZE, uNodeHeaderOffset);
+ if (pTxnQ->aTxnQueues[uFuncId][i] == NULL)
+ {
+ TRACE0(pTxnQ->hReport, REPORT_SEVERITY_ERROR, ": Queues creation failed!\n");
+ context_LeaveCriticalSection (pTxnQ->hContext);
+ return TI_NOK;
+ }
+ }
+
+ /* Update functions actual range (to optimize Txn selection loops - see txnQ_SelectTxn) */
+ if (uFuncId < pTxnQ->uMinFuncId)
+ {
+ pTxnQ->uMinFuncId = uFuncId;
+ }
+ if (uFuncId > pTxnQ->uMaxFuncId)
+ {
+ pTxnQ->uMaxFuncId = uFuncId;
+ }
+
+ context_LeaveCriticalSection (pTxnQ->hContext);
+
+ TRACE2(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, ": Function %d registered successfully, uNumPrios = %d\n", uFuncId, uNumPrios);
+
+ return TI_OK;
+}
+
+void txnQ_Close (TI_HANDLE hTxnQ, TI_UINT32 uFuncId)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*)hTxnQ;
+ TI_UINT32 i;
+
+ context_EnterCriticalSection (pTxnQ->hContext);
+
+ /* Destroy the functional driver's queues */
+ for (i = 0; i < pTxnQ->aFuncInfo[uFuncId].uNumPrios; i++)
+ {
+ que_Destroy (pTxnQ->aTxnQueues[uFuncId][i]);
+ }
+
+ /* Clear functional driver info */
+ pTxnQ->aFuncInfo[uFuncId].uNumPrios = 0;
+ pTxnQ->aFuncInfo[uFuncId].fTxnQueueDoneCb = NULL;
+ pTxnQ->aFuncInfo[uFuncId].hCbHandle = NULL;
+ pTxnQ->aFuncInfo[uFuncId].eState = FUNC_STATE_NONE;
+
+ /* Update functions actual range (to optimize Txn selection loops - see txnQ_SelectTxn) */
+ pTxnQ->uMinFuncId = MAX_FUNCTIONS;
+ pTxnQ->uMaxFuncId = 0;
+ for (i = 0; i < MAX_FUNCTIONS; i++)
+ {
+ if (pTxnQ->aFuncInfo[i].eState != FUNC_STATE_NONE)
+ {
+ if (i < pTxnQ->uMinFuncId)
+ {
+ pTxnQ->uMinFuncId = i;
+ }
+ if (i > pTxnQ->uMaxFuncId)
+ {
+ pTxnQ->uMaxFuncId = i;
+ }
+ }
+ }
+
+ context_LeaveCriticalSection (pTxnQ->hContext);
+
+ TRACE1(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, ": Function %d Unregistered\n", uFuncId);
+}
+
+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;
+ }
+ }
+
+ /* Clear the calling function's queues (call function CB with status=RECOVERY) */
+ txnQ_ClearQueues (pTxnQ, uFuncId);
+
+ context_LeaveCriticalSection (pTxnQ->hContext);
+
+ /* Return COMPLETE to indicate that the restart was completed */
+ return TXN_STATUS_COMPLETE;
+}
+
+void txnQ_Run (TI_HANDLE hTxnQ, TI_UINT32 uFuncId)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*) hTxnQ;
+
+#ifdef TI_DBG
+ TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Run()\n");
+ if (pTxnQ->aFuncInfo[uFuncId].eState != FUNC_STATE_STOPPED)
+ {
+ TRACE2(pTxnQ->hReport, REPORT_SEVERITY_WARNING, "txnQ_Run(): Called while func %d state is %d!\n", uFuncId, pTxnQ->aFuncInfo[uFuncId].eState);
+ }
+#endif
+
+ /* Enable function's queues */
+ pTxnQ->aFuncInfo[uFuncId].eState = FUNC_STATE_RUNNING;
+
+ /* Send queued transactions as possible */
+ txnQ_RunScheduler (pTxnQ, NULL);
+}
+
+void txnQ_Stop (TI_HANDLE hTxnQ, TI_UINT32 uFuncId)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*) hTxnQ;
+
+#ifdef TI_DBG
+ TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Stop()\n");
+ if (pTxnQ->aFuncInfo[uFuncId].eState != FUNC_STATE_RUNNING)
+ {
+ TRACE2(pTxnQ->hReport, REPORT_SEVERITY_ERROR, "txnQ_Stop(): Called while func %d state is %d!\n", uFuncId, pTxnQ->aFuncInfo[uFuncId].eState);
+ }
+#endif
+
+ /* Enable function's queues */
+ pTxnQ->aFuncInfo[uFuncId].eState = FUNC_STATE_STOPPED;
+}
+
+ETxnStatus txnQ_Transact (TI_HANDLE hTxnQ, TTxnStruct *pTxn)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*)hTxnQ;
+ TI_UINT32 uFuncId = TXN_PARAM_GET_FUNC_ID(pTxn);
+ ETxnStatus rc;
+
+ if (TXN_PARAM_GET_SINGLE_STEP(pTxn))
+ {
+ pTxnQ->aFuncInfo[uFuncId].pSingleStep = pTxn;
+ TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Transact(): Single step Txn\n");
+ }
+ else
+ {
+ TI_HANDLE hQueue = pTxnQ->aTxnQueues[uFuncId][TXN_PARAM_GET_PRIORITY(pTxn)];
+ context_EnterCriticalSection (pTxnQ->hContext);
+ que_Enqueue (hQueue, (TI_HANDLE)pTxn);
+ context_LeaveCriticalSection (pTxnQ->hContext);
+ TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Transact(): Regular Txn\n");
+ }
+
+ /* Send queued transactions as possible */
+ rc = txnQ_RunScheduler (pTxnQ, pTxn);
+
+ return rc;
+}
+
+
+/**
+ * \fn txnQ_ConnectCB
+ * \brief Pending Connection completion CB
+ *
+ * txnQ_ConnectBus CB
+ *
+ * \note
+ * \param hTxnQ - The module's object
+ * \param pTxn - The completed transaction object
+ * \return void
+ * \sa
+ */
+static void txnQ_ConnectCB (TI_HANDLE hTxnQ, void *hTxn)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*)hTxnQ;
+
+ /* Call the Client Connect CB */
+ pTxnQ->fConnectCb (pTxnQ->hConnectCb, NULL);
+}
+
+
+/**
+ * \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 */
+ context_EnterCriticalSection (pTxnQ->hContext);
+ txnQ_ClearQueues (pTxnQ, uFuncId);
+ context_LeaveCriticalSection (pTxnQ->hContext);
+
+ /* 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
+ {
+ context_EnterCriticalSection (pTxnQ->hContext);
+ 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 txnQ_RunScheduler
+ * \brief Send queued transactions
+ *
+ * Run the scheduler, which issues transactions as long as possible.
+ * Since this function is called from either internal or external (TxnDone) context,
+ * it handles reentry by setting a bSchedulerPend flag, and running the scheduler again
+ * when its current iteration is finished.
+ *
+ * \note
+ * \param pTxnQ - The module's object
+ * \param pInputTxn - The transaction inserted in the current context (NULL if none)
+ * \return COMPLETE if pCurrTxn completed in this context, PENDING if not, ERROR if failed
+ * \sa
+ */
+static ETxnStatus txnQ_RunScheduler (TTxnQObj *pTxnQ, TTxnStruct *pInputTxn)
+{
+ TI_BOOL bFirstIteration;
+
+ TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_RunScheduler()\n");
+
+ context_EnterCriticalSection (pTxnQ->hContext);
+
+ /* If the scheduler is currently busy, set bSchedulerPend flag and exit */
+ if (pTxnQ->bSchedulerBusy)
+ {
+ TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_RunScheduler(): Scheduler is busy\n");
+ pTxnQ->bSchedulerPend = TI_TRUE;
+ context_LeaveCriticalSection (pTxnQ->hContext);
+ return TXN_STATUS_PENDING;
+ }
+
+ /* Indicate that the scheduler is currently busy */
+ pTxnQ->bSchedulerBusy = TI_TRUE;
+
+ context_LeaveCriticalSection (pTxnQ->hContext);
+
+ bFirstIteration = TI_TRUE;
+
+ /*
+ * Run the scheduler while it has work to do
+ */
+ while (1)
+ {
+ ETxnStatus eStatus;
+
+ /* If first scheduler iteration, save its return code to return the original Txn result */
+ if (bFirstIteration)
+ {
+ eStatus = txnQ_Scheduler (pTxnQ, pInputTxn);
+ bFirstIteration = TI_FALSE;
+ }
+ /* This is for handling pending calls when the scheduler was busy (see above) */
+ else
+ {
+ TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_RunScheduler(): Handle pending scheduler call\n");
+ txnQ_Scheduler (pTxnQ, NULL);
+ }
+
+ context_EnterCriticalSection (pTxnQ->hContext);
+
+ /* If no pending calls, clear the busy flag and return the original caller Txn status */
+ if (!pTxnQ->bSchedulerPend)
+ {
+ pTxnQ->bSchedulerBusy = TI_FALSE;
+ context_LeaveCriticalSection (pTxnQ->hContext);
+ return eStatus;
+ }
+ pTxnQ->bSchedulerPend = TI_FALSE;
+
+ context_LeaveCriticalSection (pTxnQ->hContext);
+ }
+}
+
+
+/**
+ * \fn txnQ_Scheduler
+ * \brief Send queued transactions
+ *
+ * Issue transactions as long as they are available and the bus is not occupied.
+ * Call CBs of completed transactions, except completion of pInputTxn (covered by the return value).
+ * Note that this function is called from either internal or external (TxnDone) context.
+ * However, the txnQ_RunScheduler which calls it, prevents scheduler reentry.
+ *
+ * \note
+ * \param pTxnQ - The module's object
+ * \param pInputTxn - The transaction inserted in the current context (NULL if none)
+ * \return COMPLETE if pInputTxn completed in this context, PENDING if not, ERROR if failed
+ * \sa txnQ_RunScheduler
+ */
+static ETxnStatus txnQ_Scheduler (TTxnQObj *pTxnQ, TTxnStruct *pInputTxn)
+{
+ ETxnStatus eInputTxnStatus;
+
+ /* Use as return value the status of the input transaction (PENDING unless sent and completed here) */
+ eInputTxnStatus = TXN_STATUS_PENDING;
+
+ /* if a previous transaction is in progress, return PENDING */
+ if (pTxnQ->pCurrTxn)
+ {
+ TRACE1(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Scheduler(): pCurrTxn isn't null (0x%x) so exit\n", pTxnQ->pCurrTxn);
+ return TXN_STATUS_PENDING;
+ }
+
+ /* Loop while transactions are available and can be sent to bus driver */
+ while (1)
+ {
+ TTxnStruct *pSelectedTxn;
+ ETxnStatus eStatus;
+
+ /* Get next enabled transaction by priority. If none, exit loop. */
+ context_EnterCriticalSection (pTxnQ->hContext);
+ pSelectedTxn = txnQ_SelectTxn (pTxnQ);
+ context_LeaveCriticalSection (pTxnQ->hContext);
+ if (pSelectedTxn == NULL)
+ {
+ break;
+ }
+
+ /* Save transaction in case it will be async (to indicate that the bus driver is busy) */
+ pTxnQ->pCurrTxn = pSelectedTxn;
+
+ /* Send selected transaction to bus driver */
+ eStatus = busDrv_Transact (pTxnQ->hBusDrv, pSelectedTxn);
+
+ /* If we've just sent the input transaction, use the status as the return value */
+ if (pSelectedTxn == pInputTxn)
+ {
+ eInputTxnStatus = eStatus;
+ }
+
+ TRACE3(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Scheduler(): Txn 0x%x sent, status = %d, eInputTxnStatus = %d\n", pSelectedTxn, eStatus, eInputTxnStatus);
+
+ /* If transaction completed */
+ if (eStatus != TXN_STATUS_PENDING)
+ {
+ pTxnQ->pCurrTxn = NULL;
+
+ /* If it's not the input transaction, enqueue it in TxnDone queue */
+ if (pSelectedTxn != pInputTxn)
+ {
+ context_EnterCriticalSection (pTxnQ->hContext);
+ que_Enqueue (pTxnQ->hTxnDoneQueue, (TI_HANDLE)pSelectedTxn);
+ context_LeaveCriticalSection (pTxnQ->hContext);
+ }
+ }
+
+ /* If pending Exit loop! */
+ else
+ {
+ break;
+ }
+ }
+
+ /* Dequeue completed transactions and call their functional driver CB */
+ /* Note that it's the functional driver CB and not the specific CB in the Txn! */
+ while (1)
+ {
+ TTxnStruct *pCompletedTxn;
+ TI_UINT32 uFuncId;
+ TTxnQueueDoneCb fTxnQueueDoneCb;
+ TI_HANDLE hCbHandle;
+
+ context_EnterCriticalSection (pTxnQ->hContext);
+ pCompletedTxn = (TTxnStruct *) que_Dequeue (pTxnQ->hTxnDoneQueue);
+ context_LeaveCriticalSection (pTxnQ->hContext);
+ if (pCompletedTxn == NULL)
+ {
+ /* Return the status of the input transaction (PENDING unless sent and completed here) */
+ return eInputTxnStatus;
+ }
+
+ TRACE1(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Scheduler(): Calling TxnDone for Txn 0x%x\n", pCompletedTxn);
+
+ uFuncId = TXN_PARAM_GET_FUNC_ID(pCompletedTxn);
+ fTxnQueueDoneCb = pTxnQ->aFuncInfo[uFuncId].fTxnQueueDoneCb;
+ hCbHandle = pTxnQ->aFuncInfo[uFuncId].hCbHandle;
+
+ fTxnQueueDoneCb (hCbHandle, pCompletedTxn);
+ }
+}
+
+
+/**
+ * \fn txnQ_SelectTxn
+ * \brief Select transaction to send
+ *
+ * Called from txnQ_RunScheduler() which is protected in critical section.
+ * Select the next enabled transaction by priority.
+ *
+ * \note
+ * \param pTxnQ - The module's object
+ * \return The selected transaction to send (NULL if none available)
+ * \sa
+ */
+static TTxnStruct *txnQ_SelectTxn (TTxnQObj *pTxnQ)
+{
+ TTxnStruct *pSelectedTxn;
+ TI_UINT32 uFunc;
+ TI_UINT32 uPrio;
+
+ /* For all functions, if single-step Txn waiting, return it (sent even if function is stopped) */
+ for (uFunc = pTxnQ->uMinFuncId; uFunc <= pTxnQ->uMaxFuncId; uFunc++)
+ {
+ pSelectedTxn = pTxnQ->aFuncInfo[uFunc].pSingleStep;
+ if (pSelectedTxn != NULL)
+ {
+ pTxnQ->aFuncInfo[uFunc].pSingleStep = NULL;
+ return pSelectedTxn;
+ }
+ }
+
+ /* For all priorities from high to low */
+ for (uPrio = 0; uPrio < MAX_PRIORITY; uPrio++)
+ {
+ /* For all functions */
+ for (uFunc = pTxnQ->uMinFuncId; uFunc <= pTxnQ->uMaxFuncId; uFunc++)
+ {
+ /* If function running and uses this priority */
+ if (pTxnQ->aFuncInfo[uFunc].eState == FUNC_STATE_RUNNING &&
+ pTxnQ->aFuncInfo[uFunc].uNumPrios > uPrio)
+ {
+ /* Dequeue Txn from current func and priority queue, and if not NULL return it */
+ pSelectedTxn = (TTxnStruct *) que_Dequeue (pTxnQ->aTxnQueues[uFunc][uPrio]);
+ if (pSelectedTxn != NULL)
+ {
+ return pSelectedTxn;
+ }
+ }
+ }
+ }
+
+ /* If no transaction was selected, return NULL */
+ return NULL;
+}
+
+
+/**
+ * \fn txnQ_ClearQueues
+ * \brief Clear the function queues
+ *
+ * Clear the specified function queues and call its CB for each Txn with status=RECOVERY.
+ *
+ * \note Called in critical section.
+ * \param pTxnQ - The module's object
+ * \param uFuncId - The calling functional driver
+ * \return void
+ * \sa
+ */
+static void txnQ_ClearQueues (TTxnQObj *pTxnQ, TI_UINT32 uFuncId)
+{
+ TTxnStruct *pTxn;
+ TI_UINT32 uPrio;
+
+ pTxnQ->aFuncInfo[uFuncId].pSingleStep = NULL;
+
+ /* For all function priorities */
+ for (uPrio = 0; uPrio < pTxnQ->aFuncInfo[uFuncId].uNumPrios; uPrio++)
+ {
+ while (1)
+ {
+ /* Dequeue Txn from current priority queue */
+ pTxn = (TTxnStruct *) que_Dequeue (pTxnQ->aTxnQueues[uFuncId][uPrio]);
+
+ /* If NULL Txn (queue empty), exit while loop */
+ if (pTxn == NULL)
+ {
+ break;
+ }
+
+ /*
+ * Drop on Restart
+ * do not call fTxnQueueDoneCb (hCbHandle, pTxn) callback
+ */
+ }
+ }
+
+ /* Clear state - for restart (doesn't call txnQ_Open) */
+ pTxnQ->aFuncInfo[uFuncId].eState = FUNC_STATE_RUNNING;
+}
+
+#ifdef TI_DBG
+void txnQ_PrintQueues (TI_HANDLE hTxnQ)
+{
+ TTxnQObj *pTxnQ = (TTxnQObj*)hTxnQ;
+
+ WLAN_OS_REPORT(("Print TXN queues\n"));
+ WLAN_OS_REPORT(("================\n"));
+ que_Print(pTxnQ->aTxnQueues[TXN_FUNC_ID_WLAN][TXN_LOW_PRIORITY]);
+ que_Print(pTxnQ->aTxnQueues[TXN_FUNC_ID_WLAN][TXN_HIGH_PRIORITY]);
+}
+#endif /* TI_DBG */
+
+
diff --git a/wilink_6_1/Txn/TxnQueue.h b/wilink_6_1/Txn/TxnQueue.h
new file mode 100644
index 0000000..7fce88c
--- /dev/null
+++ b/wilink_6_1/Txn/TxnQueue.h
@@ -0,0 +1,244 @@
+/*
+ * TxnQueue.h
+ *
+ * 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 TxnQueue.h
+ * \brief TxnQueue module API definition
+ *
+ * \see TxnQueue.c
+ */
+
+#ifndef __TXN_QUEUE_API_H__
+#define __TXN_QUEUE_API_H__
+
+
+#include "TxnDefs.h"
+#include "BusDrv.h"
+
+
+
+/************************************************************************
+ * Defines
+ ************************************************************************/
+
+
+/************************************************************************
+ * Macros
+ ************************************************************************/
+
+
+/************************************************************************
+ * Types
+ ************************************************************************/
+
+
+/************************************************************************
+ * Functions
+ ************************************************************************/
+/** \brief Create the TxnQ module
+ *
+ * \param hOs - Handle to Os Abstraction Layer
+ * \return Handle of the allocated object, NULL if allocation failed
+ *
+ * \par Description
+ * Allocate and clear the module's object
+ *
+ * \sa txnQ_Destroy
+ */
+TI_HANDLE txnQ_Create (TI_HANDLE hOs);
+/** \brief Destroy the module
+ *
+ * \param The module's object
+ * \return TI_OK on success or TI_NOK on failure
+ *
+ * \par Description
+ * Destroy bus driver and free the module's object
+ *
+ * \sa txnQ_Create
+ */
+TI_STATUS txnQ_Destroy (TI_HANDLE hTxnQ);
+/** \brief Init module
+ *
+ * \param hTxnQ - The module's object
+ * \param hOs - Handle to Os Abstraction Layer
+ * \param hReport - Handle to report module
+ * \param hContext - Handle to context module
+ * \return void
+ *
+ * \par Description
+ *
+ * \sa
+ */
+void txnQ_Init (TI_HANDLE hTxnQ,
+ TI_HANDLE hOs,
+ TI_HANDLE hReport,
+ TI_HANDLE hContext);
+/** \brief Configure bus driver
+ *
+ * \param hTxnQ - The module's object
+ * \param pBusDrvCfg - A union used for per-bus specific configuration.
+ * \return TI_OK / TI_NOK
+ *
+ * \par Description
+ * Called by DrvMain (future - by Chip-Manager).
+ * Configure the bus driver with its connection configuration (such as baud-rate, bus width etc)
+ * and establish the physical connection. Done once (and not per functional driver startup).
+ *
+ * \sa
+ */
+TI_STATUS txnQ_ConnectBus (TI_HANDLE hTxnQ,
+ TBusDrvCfg *pBusDrvCfg,
+ TTxnDoneCb fConnectCb,
+ TI_HANDLE hConnectCb);
+/** \brief Disconnect bus driver
+ *
+ * \param hTxnQ - The module's object
+ * \return TI_OK / TI_NOK
+ *
+ * \par Description
+ * Called by DrvMain (future - by Chip-Manager).
+ * Disconnect the bus driver.
+ *
+ * \sa
+ */
+TI_STATUS txnQ_DisconnectBus (TI_HANDLE hTxnQ);
+/** \brief Register functional driver to TxnQ
+ *
+ * \param hTxnQ - The module's object
+ * \param uFuncId - The calling functional driver
+ * \param uNumPrios - The number of queues/priorities
+ * \param fTxnQueueDoneCb - The callback to call upon full transaction completion.
+ * \param hCbHandle - The callback handle
+ * \return TI_OK / TI_NOK
+ *
+ * \par Description
+ * Called by each functional driver (WLAN, future-BT) that uses the TxnQ.
+ * Save driver's info and create its queues.
+ * Perform in critical section to prevent preemption from TxnDone.
+ *
+ * \sa txnQ_Close
+ */
+TI_STATUS txnQ_Open (TI_HANDLE hTxnQ,
+ TI_UINT32 uFuncId,
+ TI_UINT32 uNumPrios,
+ TTxnQueueDoneCb fTxnQueueDoneCb,
+ TI_HANDLE hCbHandle);
+/** \brief Unregister functional driver from TxnQ
+ *
+ * \param hTxnQ - The module's object
+ * \param uFuncId - The calling functional driver
+ * \return void
+ * \sa txnQ_Open
+ *
+ * \par Description
+ * Called by registered functional driver that uses the TxnQ to unregister.
+ * Clear the function's data and destroy its queues.
+ * Perform in critical section to prevent preemption from TxnDone.
+ *
+ * \sa txnQ_Open
+ */
+void txnQ_Close (TI_HANDLE hTxnQ, TI_UINT32 uFuncId);
+/** \brief Restart caller's queues
+ *
+ * \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
+ *
+ * \par Description
+ * 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
+ * The Restart applies only to the calling function's queues.
+ *
+ * \sa txnQ_ClearQueues
+ */
+ETxnStatus txnQ_Restart (TI_HANDLE hTxnQ, TI_UINT32 uFuncId);
+/** \brief Run caller's queues
+ *
+ * \param hTxnQ - The module's object
+ * \param uFuncId - The calling functional driver
+ * \return void
+ *
+ * \par Description
+ * Enable TxnQ scheduler to process transactions from the calling function's queues.
+ * Run scheduler to issue transactions as possible.
+ * Run in critical section to protect from preemption by TxnDone.
+ *
+ * \sa txnQ_ClearQueues
+ */
+void txnQ_Run (TI_HANDLE hTxnQ, TI_UINT32 uFuncId);
+/** \brief Stop caller's queues
+ *
+ * \param hTxnQ - The module's object
+ * \param uFuncId - The calling functional driver
+ * \return void
+ *
+ * \par Description
+ * Disable TxnQ scheduler to process transactions from the calling function's queues.
+ *
+ * \sa
+ */
+void txnQ_Stop (TI_HANDLE hTxnQ, TI_UINT32 uFuncId);
+/** \brief Issue a new transaction
+ *
+ * \param hTxnQ - The module's object
+ * \param pTxn - The transaction object
+ * \return COMPLETE if input pTxn completed in this context, PENDING if not, ERROR if failed
+ *
+ * \par Description
+ * Called by the functional driver to initiate a new transaction.
+ * In critical section save transaction and call scheduler.
+ *
+ * \sa
+ */
+ETxnStatus txnQ_Transact (TI_HANDLE hTxnQ, TTxnStruct *pTxn);
+
+#ifdef TI_DBG
+/** \brief Print Txn Queues
+ *
+ * \param hTxnQ - The module's object
+ * \return void
+ *
+ * \par Description
+ *
+ * \sa
+ */
+void txnQ_PrintQueues (TI_HANDLE hTxnQ);
+#endif
+
+
+
+#endif /*__TXN_QUEUE_API_H__*/
diff --git a/wilink_6_1/Txn/WspiBusDrv.c b/wilink_6_1/Txn/WspiBusDrv.c
new file mode 100644
index 0000000..e6db7f7
--- /dev/null
+++ b/wilink_6_1/Txn/WspiBusDrv.c
@@ -0,0 +1,399 @@
+/*
+ * WspiBusDrv.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 WspiBusDrv.c
+ * \brief The WSPI bus driver upper layer. Platform independent.
+ * Uses the SpiAdapter API.
+ * Introduces a generic bus-independent API upwards.
+ *
+ * \see BusDrv.h, SpiAdapter.h, SpiAdapter.c
+ */
+
+#include "tidef.h"
+#include "report.h"
+#include "osApi.h"
+#include "wspi.h"
+#include "BusDrv.h"
+#include "TxnDefs.h"
+#define __FILE_ID__ FILE_ID_124
+
+/************************************************************************
+ * Defines
+ ************************************************************************/
+#define WSPI_FIXED_BUSY_LEN 1
+#define WSPI_INIT_CMD_MASK 0
+
+
+/************************************************************************
+ * Types
+ ************************************************************************/
+
+/* The busDrv module Object */
+typedef struct _TBusDrvObj
+{
+ TI_HANDLE hOs;
+ TI_HANDLE hReport;
+ TI_HANDLE hDriver;
+ TI_HANDLE hWspi;
+
+ TTxnDoneCb fTxnDoneCb; /* The callback to call upon full transaction completion. */
+ TI_HANDLE hCbHandle; /* The callback handle */
+ TTxnStruct * pCurrTxn; /* The transaction currently being processed */
+ TI_STATUS eCurrTxnStatus; /* COMPLETE, PENDING or ERROR */
+ TI_UINT32 uCurrTxnBufsCount;
+ TI_BOOL bPendingByte;
+ TTxnDoneCb fTxnConnectDoneCb; /* The callback to call upon full transaction completion. */
+
+
+} TBusDrvObj;
+
+
+/************************************************************************
+ * Internal functions prototypes
+ ************************************************************************/
+
+static void asyncEnded_CB(TI_HANDLE hBusTxn, int status);
+static void ConnectDone_CB(TI_HANDLE hBusDrv, int status);
+
+/************************************************************************
+ *
+ * Module functions implementation
+ *
+ ************************************************************************/
+
+/**
+ * \fn busDrv_Create
+ * \brief Create the module
+ *
+ * Allocate and clear the module's object.
+ *
+ * \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;
+
+ // addapt to WSPI
+
+ pBusDrv->hWspi= WSPI_Open(hOs);
+
+ return pBusDrv;
+}
+
+
+/**
+ * \fn busDrv_Destroy
+ * \brief Destroy the module.
+ *
+ * Close SPI 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)
+ {
+ // addapt to WSPI
+ WSPI_Close(pBusDrv->hWspi);
+ os_memoryFree (pBusDrv->hOs, pBusDrv, sizeof(TBusDrvObj));
+ }
+ return TI_OK;
+}
+
+
+/****************************************************************************
+ * busDrv_Init
+ ****************************************************************************
+ * DESCRIPTION: config the module.
+ *
+ * INPUTS: hBusDrv - handle to the module context
+ * hReport - handle to report module context that is used when we output debug messages
+ * CBFunc - The callback to call upon transaction complete (calls the tasklet).
+ * CBArg - The handle for the CBFunc.
+ *
+ * OUTPUT: none.
+ *
+ * RETURNS: one of the error codes (0 => TI_OK)
+ ****************************************************************************/
+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;
+ WSPIConfig_t wspi_config;
+ WSPI_CB_T cb;
+
+ /* Save the parameters (TxnQ callback for TxnDone events) */
+ pBusDrv->fTxnDoneCb = fCbFunc;
+ pBusDrv->hCbHandle = hCbArg;
+ pBusDrv->fTxnConnectDoneCb = fConnectCbFunc;
+
+ /* Configure the WSPI driver parameters */
+
+ wspi_config.isFixedAddress = TI_FALSE;
+ wspi_config.fixedBusyLength = WSPI_FIXED_BUSY_LEN;
+ wspi_config.mask = WSPI_INIT_CMD_MASK;
+
+ cb.CBFunc = ConnectDone_CB;/* The BusTxn callback called upon Async transaction end. */
+ cb.CBArg = hBusDrv; /* The handle for the BusDrv. */
+
+ /* Configure the WSPI module */
+ iStatus = WSPI_Configure(pBusDrv->hWspi, pBusDrv->hReport, &wspi_config, &cb);
+
+
+ if ((iStatus == 0) || (iStatus == 1))
+ {
+ TRACE1 (pBusDrv->hReport, REPORT_SEVERITY_INIT, "busDrv_ConnectBus: called Status %d\n",iStatus);
+
+
+ TRACE2 (pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_ConnectBus: Successful Status %d\n",iStatus);
+ return TI_OK;
+ }
+ else
+ {
+ TRACE2(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "busDrv_ConnectBus: Status = %d,\n", iStatus);
+ 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)
+{
+ return TI_OK;
+}
+
+
+/**
+ * \fn busDrv_Transact
+ * \brief Process transaction
+ *
+ * Called by the TxnQ module to initiate a new transaction.
+ * Call either write or read functions according to Txn direction field.
+ *
+ * \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;
+ WSPI_CB_T cb;
+ TI_UINT8 * tempReadBuff;
+ TI_UINT8 * tempWriteBuff;
+ pBusDrv->pCurrTxn = pTxn;
+ pBusDrv->eCurrTxnStatus = TXN_STATUS_COMPLETE; /* The Txn is Sync as long as it continues in this context */
+ cb.CBFunc = asyncEnded_CB; /* The BusTxn callback called upon Async transaction end. */
+ cb.CBArg = hBusDrv; /* The handle for the BusTxnCB. */
+
+ /* If write command */
+ if (TXN_PARAM_GET_DIRECTION(pTxn) == TXN_DIRECTION_WRITE)
+ {
+
+ //WLAN_REPORT_INIT(pBusDrv->hReport, TNETW_DRV_MODULE_LOG,
+ // ("busDrv_Transact: Write to pTxn->uHwAddr %x\n", pTxn->uHwAddr ));
+
+
+ /*WLAN_REPORT_ERROR(pBusDrv->hReport, BUS_DRV_MODULE_LOG,
+ ("busDrv_Transact: Buff= %x, Len=%d\n", pTxn->aBuf[0], pTxn->aLen[0]));*/
+ /*1.write memory*/
+ /* Decrease the data pointer to the beginning of the WSPI padding */
+ tempWriteBuff = pTxn->aBuf[0];
+ tempWriteBuff -= WSPI_PAD_LEN_WRITE;
+
+ /* Write the data to the WSPI in Aync mode (not completed in the current context). */
+ pBusDrv->eCurrTxnStatus = WSPI_WriteAsync(pBusDrv->hWspi, pTxn->uHwAddr,tempWriteBuff,pTxn->aLen[0], &cb, TI_TRUE, TI_TRUE,TXN_PARAM_GET_FIXED_ADDR(pTxn));
+
+ }
+
+ /* If read command */
+ else
+ {
+ //WLAN_REPORT_INIT(pBusDrv->hReport, TNETW_DRV_MODULE_LOG,
+ // ("busDrv_Transact: Read from pTxn->uHwAddr %x pTxn %x \n", pTxn->uHwAddr,pTxn));
+
+ /*1. Read mem */
+ /* Decrease the tempReadBuff pointer to the beginning of the WSPI padding */
+ tempReadBuff = pTxn->aBuf[0];
+ tempReadBuff -= WSPI_PAD_LEN_READ;
+ /* Read the required data from the WSPI in Aync mode (not completed in the current context). */
+ pBusDrv->eCurrTxnStatus = WSPI_ReadAsync(pBusDrv->hWspi, pTxn->uHwAddr,tempReadBuff,pTxn->aLen[0], &cb, TI_TRUE, TI_TRUE,TXN_PARAM_GET_FIXED_ADDR(pTxn));
+
+
+ }
+
+ /* return transaction status - COMPLETE, PENDING or ERROR */
+ return (pBusDrv->eCurrTxnStatus == WSPI_TXN_COMPLETE ? TXN_STATUS_COMPLETE :
+ (pBusDrv->eCurrTxnStatus == WSPI_TXN_PENDING ? TXN_STATUS_PENDING : TXN_STATUS_ERROR));
+
+
+}
+
+
+/****************************************************************************
+ * asyncEnded_CB()
+ ****************************************************************************
+ * DESCRIPTION:
+ * Called back by the WSPI driver from Async transaction end interrupt (ISR context).
+ * Calls the upper layers callback.
+ *
+ * INPUTS: status -
+ *
+ * OUTPUT: None
+ *
+ * RETURNS: None
+ ****************************************************************************/
+static void asyncEnded_CB(TI_HANDLE hBusDrv, int status)
+{
+ TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
+ /* If the last transaction failed, call failure CB and exit. */
+ if (status != 0)
+ {
+ TRACE2(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "asyncEnded_CB : Status = %d, fTxnDoneCb = 0x%x\n", status,pBusDrv->fTxnDoneCb);
+
+ TXN_PARAM_SET_STATUS(pBusDrv->pCurrTxn, TXN_PARAM_STATUS_ERROR);
+ }
+ else
+ {
+ TRACE2(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION,"asyncEnded_CB: Successful async cb done pBusDrv->pCurrTxn %x\n", pBusDrv->pCurrTxn);
+ }
+
+ /* Call the upper layer CB */
+
+ pBusDrv->fTxnDoneCb(pBusDrv->hCbHandle,pBusDrv->pCurrTxn);
+}
+
+
+/****************************************************************************
+ * ConnectDone_CB()
+ ****************************************************************************
+ * DESCRIPTION:
+ * Called back by the WSPI driver from Async transaction end interrupt (ISR context).
+ * Calls the upper layers callback.
+ *
+ * INPUTS: status -
+ *
+ * OUTPUT: None
+ *
+ * RETURNS: None
+ ****************************************************************************/
+static void ConnectDone_CB(TI_HANDLE hBusDrv, int status)
+{
+ TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
+ /* If the last transaction failed, call failure CB and exit. */
+ if (status != 0)
+ {
+ TRACE2(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "ConnectDone_CB : Status = %d, fTxnConnectDoneCb = 0x%x\n", status,pBusDrv->fTxnConnectDoneCb);
+
+ TXN_PARAM_SET_STATUS(pBusDrv->pCurrTxn, TXN_PARAM_STATUS_ERROR);
+ }
+ else
+ {
+ TRACE1 (pBusDrv->hReport, REPORT_SEVERITY_INIT, "ConnectDone_CB: Successful Connect Async cb done \n");
+ }
+
+ /* Call the upper layer CB */
+
+ pBusDrv->fTxnConnectDoneCb(pBusDrv->hCbHandle,pBusDrv->pCurrTxn);
+}
+
+