1981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/* 2981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * SdioBusDrv.c 3981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 4981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * All rights reserved. 6981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 7981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Redistribution and use in source and binary forms, with or without 8981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * modification, are permitted provided that the following conditions 9981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * are met: 10981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 11981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * * Redistributions of source code must retain the above copyright 12981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * notice, this list of conditions and the following disclaimer. 13981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * * Redistributions in binary form must reproduce the above copyright 14981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * notice, this list of conditions and the following disclaimer in 15981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * the documentation and/or other materials provided with the 16981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * distribution. 17981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * * Neither the name Texas Instruments nor the names of its 18981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * contributors may be used to endorse or promote products derived 19981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * from this software without specific prior written permission. 20981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 21981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 33981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 34981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 35981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/** \file SdioBusDrv.c 36981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \brief The SDIO bus driver upper layer. Platform independent. 37981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Uses the SdioAdapter API. 38981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Introduces a generic bus-independent API upwards. 39981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 40981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \see BusDrv.h, SdioAdapter.h, SdioAdapter.c 41981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 42981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 43981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt#define __FILE_ID__ FILE_ID_122 44981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt#include "tidef.h" 45981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt#include "report.h" 46981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt#include "osApi.h" 47981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt#include "TxnDefs.h" 48981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt#include "SdioAdapter.h" 49981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt#include "BusDrv.h" 50981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt#include "bmtrace_api.h" 51981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 52981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 53981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/* remove the chipID check when WL6-PG1.0 becomes obsolete (temporary global variable!!) */ 54981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidtextern TI_BOOL bChipIs1273Pg10; 55981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 56981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 57981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/************************************************************************ 58981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Defines 59981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt ************************************************************************/ 60981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt#define MAX_TXN_PARTS MAX_XFER_BUFS * 2 /* Max number of txn parts derived from one TxnStruct */ 61981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 62981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 63981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/************************************************************************ 64981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Types 65981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt ************************************************************************/ 66981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 67981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/* A single SDIO bus transaction which is a part of a complete transaction (TTxnStruct) */ 68981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidttypedef struct 69981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 70981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_BOOL bBlkMode; /* If TRUE this is a block-mode SDIO transaction */ 71981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uLength; /* Length in byte */ 72981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uHwAddr; /* The device address to write to or read from */ 73981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt void * pHostAddr; /* The host buffer address to write from or read into */ 74981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_BOOL bMore; /* If TRUE, indicates the lower driver to keep awake for more transactions */ 75981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} TTxnPart; 76981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 77981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 78981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/* The busDrv module Object */ 79981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidttypedef struct _TBusDrvObj 80981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 81981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_HANDLE hOs; 82981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_HANDLE hReport; 83981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 84981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvTxnDoneCb fTxnDoneCb; /* The callback to call upon full transaction completion. */ 85981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_HANDLE hCbHandle; /* The callback handle */ 86981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TTxnStruct * pCurrTxn; /* The transaction currently being processed */ 87981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt ETxnStatus eCurrTxnStatus; /* COMPLETE, PENDING or ERROR */ 88981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TTxnPart aTxnParts[MAX_TXN_PARTS]; /* The actual bus transactions of current transaction */ 89981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uCurrTxnPartsNum; /* Number of transaction parts composing the current transaction */ 90981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uCurrTxnPartsCount; /* Number of transaction parts already executed */ 91981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uCurrTxnPartsCountSync; /* Number of transaction parts completed in Sync mode (returned COMPLETE) */ 92981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uBlkSizeShift; /* In block-mode: uBlkSize = (1 << uBlkSizeShift) = 512 bytes */ 93981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uBlkSize; /* In block-mode: uBlkSize = (1 << uBlkSizeShift) = 512 bytes */ 94981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uBlkSizeMask; /* In block-mode: uBlkSizeMask = uBlkSize - 1 = 0x1FF*/ 95653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TI_UINT8 * pDmaBuffer; /* DMA-able buffer for buffering all write transactions */ 96981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 97981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} TBusDrvObj; 98981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 99981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 100981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/************************************************************************ 101981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Internal functions prototypes 102981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt ************************************************************************/ 103981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidtstatic void busDrv_PrepareTxnParts (TBusDrvObj *pBusDrv, TTxnStruct *pTxn); 104981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidtstatic void busDrv_SendTxnParts (TBusDrvObj *pBusDrv); 105981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidtstatic void busDrv_TxnDoneCb (TI_HANDLE hBusDrv, TI_INT32 status); 106981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 107981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 108981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 109981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/************************************************************************ 110981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 111981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Module functions implementation 112981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 113981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt ************************************************************************/ 114981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 115981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/** 116981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \fn busDrv_Create 117981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \brief Create the module 118981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 119981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Create and clear the bus driver's object, and the SDIO-adapter. 120981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 121981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \note 122981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param hOs - Handle to Os Abstraction Layer 123981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \return Handle of the allocated object, NULL if allocation failed 124981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \sa busDrv_Destroy 125981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 126981801b95b81e6d1c7a2085967406e86af0f08fcDmitry ShmidtTI_HANDLE busDrv_Create (TI_HANDLE hOs) 127981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 128981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_HANDLE hBusDrv; 129981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvObj *pBusDrv; 130981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 131981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt hBusDrv = os_memoryAlloc(hOs, sizeof(TBusDrvObj)); 132981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (hBusDrv == NULL) 133981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 134981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt return NULL; 135981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 136981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 137981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv = (TBusDrvObj *)hBusDrv; 138981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 139981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt os_memoryZero(hOs, hBusDrv, sizeof(TBusDrvObj)); 140981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 141981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->hOs = hOs; 142981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 143981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt return pBusDrv; 144981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} 145981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 146981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 147981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/** 148981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \fn busDrv_Destroy 149981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \brief Destroy the module. 150981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 151981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Close SDIO lower bus driver and free the module's object. 152981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 153981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \note 154981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param The module's object 155981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \return TI_OK on success or TI_NOK on failure 156981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \sa busDrv_Create 157981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 158981801b95b81e6d1c7a2085967406e86af0f08fcDmitry ShmidtTI_STATUS busDrv_Destroy (TI_HANDLE hBusDrv) 159981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 160981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv; 161981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 162981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (pBusDrv) 163981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 164981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt os_memoryFree (pBusDrv->hOs, pBusDrv, sizeof(TBusDrvObj)); 165981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 166981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt return TI_OK; 167981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} 168981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 169981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 170981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/** 171981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \fn busDrv_Init 172981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \brief Init bus driver 173981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 174981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Init module parameters. 175981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 176981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \note 177981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param hBusDrv - The module's handle 178981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param hReport - report module handle 179981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \return void 180981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \sa 181981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 182981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidtvoid busDrv_Init (TI_HANDLE hBusDrv, TI_HANDLE hReport) 183981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 184981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvObj *pBusDrv = (TBusDrvObj*) hBusDrv; 185981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 186981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->hReport = hReport; 187981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} 188981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 189981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 190981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/** 191981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \fn busDrv_ConnectBus 192981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \brief Configure bus driver 193981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 194981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Called by TxnQ. 195981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Configure the bus driver with its connection configuration (such as baud-rate, bus width etc) 196981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * and establish the physical connection. 197981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Done once upon init (and not per functional driver startup). 198981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 199981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \note 200981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param hBusDrv - The module's object 201981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param pBusDrvCfg - A union used for per-bus specific configuration. 202981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param fCbFunc - CB function for Async transaction completion (after all txn parts are completed). 203981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param hCbArg - The CB function handle 204981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \return TI_OK / TI_NOK 205981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \sa 206981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 207981801b95b81e6d1c7a2085967406e86af0f08fcDmitry ShmidtTI_STATUS busDrv_ConnectBus (TI_HANDLE hBusDrv, 208981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvCfg *pBusDrvCfg, 209981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvTxnDoneCb fCbFunc, 210981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_HANDLE hCbArg, 211981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvTxnDoneCb fConnectCbFunc) 212981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 213981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv; 214981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt int iStatus; 215981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 216981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* Save the parameters (TxnQ callback for TxnDone events, and block-size) */ 217981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->fTxnDoneCb = fCbFunc; 218981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->hCbHandle = hCbArg; 219981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uBlkSizeShift = pBusDrvCfg->tSdioCfg.uBlkSizeShift; 220981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uBlkSize = 1 << pBusDrv->uBlkSizeShift; 221981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uBlkSizeMask = pBusDrv->uBlkSize - 1; 222981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* This should cover stop send Txn parts in recovery */ 223981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uCurrTxnPartsCount = 0; 224981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uCurrTxnPartsNum = 0; 225981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uCurrTxnPartsCountSync = 0; 226981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 227981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 228653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt /* 229653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt * Configure the SDIO driver parameters and handle SDIO enumeration. 230653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt * 231653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt * Note: The DMA-able buffer address to use for write transactions is provided from the 232653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt * SDIO driver into pBusDrv->pDmaBuffer. 233653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt */ 234981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt iStatus = sdioAdapt_ConnectBus (busDrv_TxnDoneCb, 235981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt hBusDrv, 236981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uBlkSizeShift, 237653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt pBusDrvCfg->tSdioCfg.uBusDrvThreadPriority, 238653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt &pBusDrv->pDmaBuffer); 239653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 240653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt if (pBusDrv->pDmaBuffer == NULL) 241653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt { 242653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TRACE0(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "busDrv_ConnectBus: Didn't get DMA buffer from SDIO driver!!"); 243653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt return TI_NOK; 244653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt } 245653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 246981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 247981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (iStatus == 0) 248981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 249981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt return TI_OK; 250981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 251981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt else 252981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 253981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TRACE2(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "busDrv_ConnectBus: Status = 0x%x, BlkSize = %d\n", iStatus, pBusDrv->uBlkSize); 254981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt return TI_NOK; 255981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 256981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} 257981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 258981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 259981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/** 260981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \fn busDrv_DisconnectBus 261981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \brief Disconnect SDIO driver 262981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 263981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Called by TxnQ. Disconnect the SDIO driver. 264981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 265981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \note 266981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param hBusDrv - The module's object 267981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \return TI_OK / TI_NOK 268981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \sa 269981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 270981801b95b81e6d1c7a2085967406e86af0f08fcDmitry ShmidtTI_STATUS busDrv_DisconnectBus (TI_HANDLE hBusDrv) 271981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 272981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv; 273981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 274981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TRACE0(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_DisconnectBus()\n"); 275981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 276981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* Disconnect SDIO driver */ 277981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt return sdioAdapt_DisconnectBus (); 278981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} 279981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 280981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 281981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/** 282981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \fn busDrv_Transact 283981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \brief Process transaction 284981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 285981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Called by the TxnQ module to initiate a new transaction. 286981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Prepare the transaction parts (lower layer single transactions), 287981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * and send them one by one to the lower layer. 288981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 289981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \note It's assumed that this function is called only when idle (i.e. previous Txn is done). 290981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param hBusDrv - The module's object 291981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param pTxn - The transaction object 292981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \return COMPLETE if Txn completed in this context, PENDING if not, ERROR if failed 293981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \sa busDrv_PrepareTxnParts, busDrv_SendTxnParts 294981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 295981801b95b81e6d1c7a2085967406e86af0f08fcDmitry ShmidtETxnStatus busDrv_Transact (TI_HANDLE hBusDrv, TTxnStruct *pTxn) 296981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 297981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv; 298981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt CL_TRACE_START_L4(); 299981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 300981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->pCurrTxn = pTxn; 301981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uCurrTxnPartsCount = 0; 302981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uCurrTxnPartsCountSync = 0; 303981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 304981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* Prepare the transaction parts in a table. */ 305981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt busDrv_PrepareTxnParts (pBusDrv, pTxn); 306981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 307981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* Send the prepared transaction parts. */ 308981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt busDrv_SendTxnParts (pBusDrv); 309981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 310981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TRACE1(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_Transact: Status = %d\n", pBusDrv->eCurrTxnStatus); 311981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 312981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt CL_TRACE_END_L4("tiwlan_drv.ko", "INHERIT", "TXN", ".Transact"); 313981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 314981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* return transaction status - COMPLETE, PENDING or ERROR */ 315981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* The status is updated in busDrv_SendTxnParts(). It is Async (pending) if not completed in this context */ 316981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt return pBusDrv->eCurrTxnStatus; 317981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} 318981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 319981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 320981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/** 321981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \fn busDrv_PrepareTxnParts 322981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \brief Prepare write or read transaction parts 323981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 324981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Called by busDrv_Transact(). 325981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Prepares the actual sequence of SDIO bus transactions in a table. 326653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt * Use a DMA-able buffer for the bus transaction, so all data is copied 327653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt * to it from the host buffer(s) before write transactions, 328653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt * or copied from it to the host buffers after read transactions. 329981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 330981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \note 331981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param pBusDrv - The module's object 332981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param pTxn - The transaction object 333981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \return void 334981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \sa busDrv_Transact, busDrv_SendTxnParts, 335981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 336981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidtstatic void busDrv_PrepareTxnParts (TBusDrvObj *pBusDrv, TTxnStruct *pTxn) 337981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 338981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uPartNum = 0; 339653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TI_UINT32 uTxnLength = 0; 340653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TI_UINT8 *pHostBuf = pBusDrv->pDmaBuffer; /* Host buffer to use for actual transaction is the DMA buffer */ 341981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uCurrHwAddr = pTxn->uHwAddr; 342981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_BOOL bFixedHwAddr = TXN_PARAM_GET_FIXED_ADDR(pTxn); 343653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TI_UINT32 uBufNum; 344653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TI_UINT32 uBufLen; 345653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TI_UINT32 uRemainderLen; 346981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 347653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt /* Go over the transaction buffers */ 348981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt for (uBufNum = 0; uBufNum < MAX_XFER_BUFS; uBufNum++) 349981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 350653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt uBufLen = pTxn->aLen[uBufNum]; 351653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 352653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt /* If no more buffers, exit the loop */ 353653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt if (uBufLen == 0) 354981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 355981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt break; 356981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 357981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 358653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt /* For write transaction, copy the data to the DMA buffer */ 359653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt if (TXN_PARAM_GET_DIRECTION(pTxn) == TXN_DIRECTION_WRITE) 360653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt { 361653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt os_memoryCopy (pBusDrv->hOs, pHostBuf + uTxnLength, pTxn->aBuf[uBufNum], uBufLen); 362653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt } 363653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 364653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt /* Add buffer length to total transaction length */ 365653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt uTxnLength += uBufLen; 366653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt } 367653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 368981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* If current buffer has a remainder, prepare its transaction part */ 369653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt uRemainderLen = uTxnLength & pBusDrv->uBlkSizeMask; 370981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (uRemainderLen > 0) 371981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 372981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].bBlkMode = TI_FALSE; 373981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].uLength = uRemainderLen; 374981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].uHwAddr = uCurrHwAddr; 375653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt pBusDrv->aTxnParts[uPartNum].pHostAddr = (void *)pHostBuf; 376981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].bMore = TI_TRUE; 377981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 378981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* If not fixed HW address, increment it by this part's size */ 379981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (!bFixedHwAddr) 380981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 381981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt uCurrHwAddr += uRemainderLen; 382981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 383981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 384981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt uPartNum++; 385981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 386981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 387981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* SDIO block-mode doesn't work on PG1.0 so split to 512 bytes blocks! 388981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt Remove when PG1.0 is obsolete! */ 389981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (bChipIs1273Pg10) 390981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 391981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TI_UINT32 uLen; 392981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 393653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt for (uLen = uRemainderLen; uLen < uTxnLength; uLen += pBusDrv->uBlkSize) 394981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 395981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].bBlkMode = TI_FALSE; 396981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].uLength = pBusDrv->uBlkSize; 397981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].uHwAddr = uCurrHwAddr; 398653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt pBusDrv->aTxnParts[uPartNum].pHostAddr = (void *)(pHostBuf + uLen); 399981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].bMore = TI_TRUE; 400981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 401981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* If not fixed HW address, increment it by this part's size */ 402981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (!bFixedHwAddr) 403981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 404981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt uCurrHwAddr += pBusDrv->uBlkSize; 405981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 406981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 407981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt uPartNum++; 408981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 409981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 410981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 411981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 412981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* For PG2.0, use SDIO block mode */ 413981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt else 414981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 415981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* If current buffer has full SDIO blocks, prepare a block-mode transaction part */ 416653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt if (uTxnLength >= pBusDrv->uBlkSize) 417981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 418981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].bBlkMode = TI_TRUE; 419653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt pBusDrv->aTxnParts[uPartNum].uLength = uTxnLength - uRemainderLen; 420981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].uHwAddr = uCurrHwAddr; 421653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt pBusDrv->aTxnParts[uPartNum].pHostAddr = (void *)(pHostBuf + uRemainderLen); 422981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum].bMore = TI_TRUE; 423981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 424981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt uPartNum++; 425981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 426981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 427981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 428981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* Set last More flag as specified for the whole Txn */ 429981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->aTxnParts[uPartNum - 1].bMore = TXN_PARAM_GET_MORE(pTxn); 430981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uCurrTxnPartsNum = uPartNum; 431981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} 432981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 433981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 434981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/** 435981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \fn busDrv_SendTxnParts 436981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \brief Send prepared transaction parts 437981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 438981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Called first by busDrv_Transact(), and also from TxnDone CB after Async completion. 439981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Sends the prepared transaction parts in a loop. 440981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * If a transaction part is Async, the loop continues later in the TxnDone ISR context. 441981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * When all parts are done, the upper layer TxnDone CB is called. 442981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 443981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \note 444981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param pBusDrv - The module's object 445981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \return void 446981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \sa busDrv_Transact, busDrv_PrepareTxnParts 447981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 448981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidtstatic void busDrv_SendTxnParts (TBusDrvObj *pBusDrv) 449981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 450981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt ETxnStatus eStatus; 451981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TTxnPart *pTxnPart; 452653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TTxnStruct *pTxn = pBusDrv->pCurrTxn; 453981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 454981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* While there are transaction parts to send */ 455981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt while (pBusDrv->uCurrTxnPartsCount < pBusDrv->uCurrTxnPartsNum) 456981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 457981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pTxnPart = &(pBusDrv->aTxnParts[pBusDrv->uCurrTxnPartsCount]); 458981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uCurrTxnPartsCount++; 459653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 460981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* Assume pending to be ready in case we are preempted by the TxnDon CB !! */ 461981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->eCurrTxnStatus = TXN_STATUS_PENDING; 462981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 463981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* If single step, send ELP byte */ 464653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt if (TXN_PARAM_GET_SINGLE_STEP(pTxn)) 465981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 466981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* Overwrite the function id with function 0 - for ELP register !!!! */ 467981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt eStatus = sdioAdapt_TransactBytes (TXN_FUNC_ID_CTRL, 468981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pTxnPart->uHwAddr, 469981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pTxnPart->pHostAddr, 470981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pTxnPart->uLength, 471653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TXN_PARAM_GET_DIRECTION(pTxn), 472981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pTxnPart->bMore); 4736c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt 4746c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt /* If first write failed try once again (may happen once upon chip wakeup) */ 4756c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt if (eStatus == TXN_STATUS_ERROR) 4766c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt { 4776c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt /* Overwrite the function id with function 0 - for ELP register !!!! */ 4786c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt eStatus = sdioAdapt_TransactBytes (TXN_FUNC_ID_CTRL, 4796c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt pTxnPart->uHwAddr, 4806c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt pTxnPart->pHostAddr, 4816c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt pTxnPart->uLength, 4826c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt TXN_PARAM_GET_DIRECTION(pTxn), 4836c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt pTxnPart->bMore); 4846c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt TRACE0(pBusDrv->hReport, REPORT_SEVERITY_WARNING, "busDrv_SendTxnParts: SDIO Single-Step transaction failed once so try again"); 4856c3e7f5dcb9c7319a5541993c0516594dfffb916Dmitry Shmidt } 486981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 487981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt else 488981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 489653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt eStatus = sdioAdapt_Transact (TXN_PARAM_GET_FUNC_ID(pTxn), 490981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pTxnPart->uHwAddr, 491981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pTxnPart->pHostAddr, 492981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pTxnPart->uLength, 493653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TXN_PARAM_GET_DIRECTION(pTxn), 494981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pTxnPart->bBlkMode, 495653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt ((TXN_PARAM_GET_FIXED_ADDR(pTxn) == 1) ? 0 : 1), 496981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pTxnPart->bMore); 497981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 498981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 499653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 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); 500981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 501981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* If pending TxnDone (Async), continue this loop in the next TxnDone interrupt */ 502981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (eStatus == TXN_STATUS_PENDING) 503981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 504981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt return; 505981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 506981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 507981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* Update current transaction status to deduce if it is all finished in the original context (Sync) or not. */ 508981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->eCurrTxnStatus = eStatus; 509981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->uCurrTxnPartsCountSync++; 510653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 511981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* If error, set error in Txn struct, call TxnDone CB if not fully sync, and exit */ 512981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (eStatus == TXN_STATUS_ERROR) 513981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 514653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TXN_PARAM_SET_STATUS(pTxn, TXN_PARAM_STATUS_ERROR); 515981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (pBusDrv->uCurrTxnPartsCountSync != pBusDrv->uCurrTxnPartsCount) 516981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 517653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt pBusDrv->fTxnDoneCb (pBusDrv->hCbHandle, pTxn); 518981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 519981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt return; 520981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 521981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 522981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 523981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* If we got here we sent all buffers and we don't pend transaction end */ 524981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TRACE3(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_SendTxnParts: Txn finished successfully, Status = %d, PartsCount = %d, SyncCount = %d\n", pBusDrv->eCurrTxnStatus, pBusDrv->uCurrTxnPartsCount, pBusDrv->uCurrTxnPartsCountSync); 525981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 526653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt /* For read transaction, copy the data from the DMA-able buffer to the host buffer(s) */ 527653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt if (TXN_PARAM_GET_DIRECTION(pTxn) == TXN_DIRECTION_READ) 528653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt { 529653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TI_UINT32 uBufNum; 530653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TI_UINT32 uBufLen; 531653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TI_UINT8 *pDmaBuf = pBusDrv->pDmaBuffer; /* After the read transaction the data is in the DMA buffer */ 532653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 533653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt for (uBufNum = 0; uBufNum < MAX_XFER_BUFS; uBufNum++) 534653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt { 535653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt uBufLen = pTxn->aLen[uBufNum]; 536653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 537653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt /* If no more buffers, exit the loop */ 538653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt if (uBufLen == 0) 539653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt { 540653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt break; 541653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt } 542653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 543653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt os_memoryCopy (pBusDrv->hOs, pTxn->aBuf[uBufNum], pDmaBuf, uBufLen); 544653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt pDmaBuf += uBufLen; 545653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt } 546653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt } 547653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt 548981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* Set status OK in Txn struct, and call TxnDone CB if not fully sync */ 549653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt TXN_PARAM_SET_STATUS(pTxn, TXN_PARAM_STATUS_OK); 550981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (pBusDrv->uCurrTxnPartsCountSync != pBusDrv->uCurrTxnPartsCount) 551981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 552653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt pBusDrv->fTxnDoneCb (pBusDrv->hCbHandle, pTxn); 553981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 554981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} 555981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 556981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 557981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt/** 558981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \fn busDrv_TxnDoneCb 559981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \brief Continue async transaction processing (CB) 560981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 561981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Called back by the lower (BSP) bus-driver upon Async transaction completion (TxnDone ISR). 562981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * Call busDrv_SendTxnParts to continue sending the remained transaction parts. 563981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * 564981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \note 565981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param hBusDrv - The module's object 566981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \param status - The last transaction result - 0 = OK, else Error 567981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \return void 568981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt * \sa busDrv_SendTxnParts 569981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt */ 570981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidtstatic void busDrv_TxnDoneCb (TI_HANDLE hBusDrv, int iStatus) 571981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt{ 572981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv; 573981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt CL_TRACE_START_L1(); 574981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 575981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* If last transaction part failed, set error in Txn struct, call TxnDone CB and exit. */ 576981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt if (iStatus != 0) 577981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt { 578981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TRACE1(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "busDrv_TxnDoneCb: Status = 0x%x\n", iStatus); 579981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 580981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TXN_PARAM_SET_STATUS(pBusDrv->pCurrTxn, TXN_PARAM_STATUS_ERROR); 581981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt pBusDrv->fTxnDoneCb (pBusDrv->hCbHandle, pBusDrv->pCurrTxn); 582981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt CL_TRACE_END_L1("tiwlan_drv.ko", "TXN_DONE", "BusDrvCB", ""); 583981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt return; 584981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt } 585981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 586981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt TRACE0(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_TxnDoneCb()\n"); 587981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 588981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt /* Continue sending the remained transaction parts. */ 589981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt busDrv_SendTxnParts (pBusDrv); 590981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt 591981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt CL_TRACE_END_L1("tiwlan_drv.ko", "TXN_DONE", "BusDrvCB", ""); 592981801b95b81e6d1c7a2085967406e86af0f08fcDmitry Shmidt} 593