Home | History | Annotate | Download | only in utils
      1 /*
      2  * timer.c
      3  *
      4  * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  *  * Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  *  * Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in
     15  *    the documentation and/or other materials provided with the
     16  *    distribution.
     17  *  * Neither the name Texas Instruments nor the names of its
     18  *    contributors may be used to endorse or promote products derived
     19  *    from this software without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 
     35 /** \file   timer.c
     36  *  \brief  The timers services OS-Independent layer over the OS-API timer services which are OS-Dependent.
     37  *
     38  *  \see    timer.h, osapi.c
     39  */
     40 
     41 #define __FILE_ID__  FILE_ID_0
     42 #include "osApi.h"
     43 #include "report.h"
     44 #include "queue.h"
     45 #include "context.h"
     46 #include "timer.h"
     47 
     48 
     49 #define EXPIRY_QUE_SIZE  QUE_UNLIMITED_SIZE
     50 
     51 /* The timer module structure (common to all timers) */
     52 typedef struct
     53 {
     54     TI_HANDLE   hOs;
     55     TI_HANDLE   hReport;
     56     TI_HANDLE   hContext;
     57     TI_UINT32   uContextId;     /* The ID allocated to this module on registration to context module */
     58     TI_HANDLE   hInitQueue;     /* Handle of the Init-Queue */
     59     TI_HANDLE   hOperQueue;     /* Handle of the Operational-Queue */
     60     TI_BOOL     bOperState;     /* TRUE when the driver is in operational state (not init or recovery) */
     61     TI_UINT32   uTwdInitCount;  /* Increments on each TWD init (i.e. recovery) */
     62     TI_UINT32   uTimersCount;   /* Number of created timers */
     63 } TTimerModule;
     64 
     65 /* Per timer structure */
     66 typedef struct
     67 {
     68     TI_HANDLE    hTimerModule;             /* The timer module handle (see TTimerModule, needed on expiry) */
     69     TI_HANDLE    hOsTimerObj;              /* The OS-API timer object handle */
     70     TQueNodeHdr  tQueNodeHdr;              /* The header used for queueing the timer */
     71     TTimerCbFunc fExpiryCbFunc;            /* The CB-function provided by the timer user for expiration */
     72     TI_HANDLE    hExpiryCbHndl;            /* The CB-function handle */
     73     TI_UINT32    uIntervalMsec;            /* The timer duration in Msec */
     74     TI_BOOL      bPeriodic;                /* If TRUE, restarted after each expiry */
     75     TI_BOOL      bOperStateWhenStarted;    /* The bOperState value when the timer was started */
     76     TI_UINT32    uTwdInitCountWhenStarted; /* The uTwdInitCount value when the timer was started */
     77 } TTimerInfo;
     78 
     79 
     80 
     81 
     82 /**
     83  * \fn     tmr_Create
     84  * \brief  Create the timer module
     85  *
     86  * Allocate and clear the timer module object.
     87  *
     88  * \note   This is NOT a specific timer creation! (see tmr_CreateTimer)
     89  * \param  hOs - Handle to Os Abstraction Layer
     90  * \return Handle of the allocated object
     91  * \sa     tmr_Destroy
     92  */
     93 TI_HANDLE tmr_Create (TI_HANDLE hOs)
     94 {
     95     TI_HANDLE hTimerModule;
     96 
     97     /* allocate module object */
     98     hTimerModule = os_memoryAlloc (hOs, sizeof(TTimerModule));
     99 
    100     if (!hTimerModule)
    101     {
    102         WLAN_OS_REPORT (("tmr_Create():  Allocation failed!!\n"));
    103         return NULL;
    104     }
    105 
    106     os_memoryZero (hOs, hTimerModule, (sizeof(TTimerModule)));
    107 
    108     return (hTimerModule);
    109 }
    110 
    111 
    112 /**
    113  * \fn     tmr_Destroy
    114  * \brief  Destroy the module.
    115  *
    116  * Free the module's queues and object.
    117  *
    118  * \note   This is NOT a specific timer destruction! (see tmr_DestroyTimer)
    119  * \param  hTimerModule - The module object
    120  * \return TI_OK on success or TI_NOK on failure
    121  * \sa     tmr_Create
    122  */
    123 TI_STATUS tmr_Destroy (TI_HANDLE hTimerModule)
    124 {
    125     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
    126 
    127     if (!pTimerModule)
    128     {
    129         WLAN_OS_REPORT (("tmr_Destroy(): ERROR - NULL timer!\n"));
    130         return TI_NOK;
    131     }
    132 
    133     /* Alert if there are still timers that were not destroyed */
    134     if (pTimerModule->uTimersCount)
    135     {
    136         WLAN_OS_REPORT (("tmr_Destroy():  ERROR - Destroying Timer module but not all timers were destroyed!!\n"));
    137     }
    138 
    139     /* Destroy the module's queues (protect in critical section)) */
    140     context_EnterCriticalSection (pTimerModule->hContext);
    141     que_Destroy (pTimerModule->hInitQueue);
    142     que_Destroy (pTimerModule->hOperQueue);
    143     context_LeaveCriticalSection (pTimerModule->hContext);
    144 
    145     /* free module object */
    146     os_memoryFree (pTimerModule->hOs, pTimerModule, sizeof(TTimerModule));
    147 
    148     return TI_OK;
    149 }
    150 /**
    151  * \fn     tmr_Free
    152  * \brief  Free the memory.
    153  *
    154  * Free the module's queues and object.
    155  *
    156  * \param  hTimerModule - The module object
    157  * \return TI_OK on success or TI_NOK on failure
    158  * \sa     tmr_Create
    159  */
    160 TI_STATUS tmr_Free(TI_HANDLE hTimerModule)
    161 {
    162     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
    163 
    164     if (!pTimerModule)
    165     {
    166         WLAN_OS_REPORT (("tmr_Free(): ERROR - NULL timer!\n"));
    167         return TI_NOK;
    168     }
    169 
    170     /* free module object */
    171     os_memoryFree (pTimerModule->hOs, pTimerModule, sizeof(TTimerModule));
    172 
    173     return TI_OK;
    174 }
    175 
    176 
    177 /**
    178  * \fn     tmr_ClearInitQueue & tmr_ClearOperQueue
    179  * \brief  Clear Init/Operationsl queue
    180  *
    181  * Dequeue all queued timers.
    182  *
    183  * \note
    184  * \param  hTimerModule - The object
    185  * \return void
    186  * \sa
    187  */
    188 void tmr_ClearInitQueue (TI_HANDLE hTimerModule)
    189 {
    190     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
    191 
    192     context_EnterCriticalSection (pTimerModule->hContext);
    193     while (que_Dequeue (pTimerModule->hInitQueue) != NULL) {}
    194     context_LeaveCriticalSection (pTimerModule->hContext);
    195 }
    196 
    197 void tmr_ClearOperQueue (TI_HANDLE hTimerModule)
    198 {
    199     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
    200 
    201     context_EnterCriticalSection (pTimerModule->hContext);
    202     while (que_Dequeue (pTimerModule->hOperQueue) != NULL) {}
    203     context_LeaveCriticalSection (pTimerModule->hContext);
    204 }
    205 
    206 
    207 /**
    208  * \fn     tmr_Init
    209  * \brief  Init required handles
    210  *
    211  * Init required handles and module variables, create the init-queue and
    212  *     operational-queue, and register as the context-engine client.
    213  *
    214  * \note
    215  * \param  hTimerModule  - The queue object
    216  * \param  hOs       - Handle to Os Abstraction Layer
    217  * \param  hReport   - Handle to report module
    218  * \param  hContext  - Handle to context module
    219  * \return void
    220  * \sa
    221  */
    222 void tmr_Init (TI_HANDLE hTimerModule, TI_HANDLE hOs, TI_HANDLE hReport, TI_HANDLE hContext)
    223 {
    224     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
    225     TI_UINT32     uNodeHeaderOffset;
    226 
    227     if (!pTimerModule)
    228     {
    229         WLAN_OS_REPORT (("tmr_Init(): ERROR - NULL timer!\n"));
    230         return;
    231     }
    232 
    233     pTimerModule->hOs           = hOs;
    234     pTimerModule->hReport       = hReport;
    235     pTimerModule->hContext      = hContext;
    236 
    237     pTimerModule->bOperState    = TI_FALSE;
    238     pTimerModule->uTimersCount  = 0;
    239     pTimerModule->uTwdInitCount = 0;
    240 
    241     /* The offset of the queue-node-header from timer structure entry is needed by the queue */
    242     uNodeHeaderOffset = TI_FIELD_OFFSET(TTimerInfo, tQueNodeHdr);
    243 
    244     /* Create and initialize the Init and Operational queues (for timers expiry events) */
    245     pTimerModule->hInitQueue = que_Create (pTimerModule->hOs,
    246                                            pTimerModule->hReport,
    247                                            EXPIRY_QUE_SIZE,
    248                                            uNodeHeaderOffset);
    249     pTimerModule->hOperQueue = que_Create (pTimerModule->hOs,
    250                                            pTimerModule->hReport,
    251                                            EXPIRY_QUE_SIZE,
    252                                            uNodeHeaderOffset);
    253 
    254     /* Register to the context engine and get the client ID */
    255     pTimerModule->uContextId = context_RegisterClient (pTimerModule->hContext,
    256                                                        tmr_HandleExpiry,
    257                                                        hTimerModule,
    258                                                        TI_TRUE,
    259                                                        "TIMER",
    260                                                        sizeof("TIMER"));
    261 }
    262 
    263 
    264 /**
    265  * \fn     tmr_UpdateDriverState
    266  * \brief  Update driver state
    267  *
    268  * Under critical section, update driver state (operational or not),
    269  *   and if opertional, clear init queue.
    270  * Leave critical section and if operational state, request schedule for handling
    271  *   timer events in driver context (if any).
    272  *
    273  * \note
    274  * \param  hTimerModule - The timer module object
    275  * \param  bOperState   - TRUE if driver state is now operational, FALSE if not.
    276  * \return void
    277  * \sa
    278  */
    279 void tmr_UpdateDriverState (TI_HANDLE hTimerModule, TI_BOOL bOperState)
    280 {
    281     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
    282 
    283     if (!pTimerModule)
    284     {
    285         WLAN_OS_REPORT (("tmr_UpdateDriverState(): ERROR - NULL timer!\n"));
    286         return;
    287     }
    288 
    289     /* Enter critical section */
    290     context_EnterCriticalSection (pTimerModule->hContext);
    291 
    292     if (bOperState == pTimerModule->bOperState)
    293     {
    294         context_LeaveCriticalSection (pTimerModule->hContext);
    295         TRACE1(pTimerModule->hReport, REPORT_SEVERITY_ERROR, "tmr_UpdateDriverState(): New bOperState (%d) is as current!\n", bOperState);
    296         return;
    297     }
    298 
    299     /* Save new state (TRUE means operational). */
    300     pTimerModule->bOperState = bOperState;
    301 
    302     /* If new state is operational */
    303     if (bOperState)
    304     {
    305         /* Increment the TWD initializations counter (for detecting recovery events). */
    306         pTimerModule->uTwdInitCount++;
    307 
    308         /* Empty the init queue (obsolete). */
    309         while (que_Dequeue (pTimerModule->hInitQueue) != NULL) {}
    310     }
    311 
    312     /* Leave critical section */
    313     context_LeaveCriticalSection (pTimerModule->hContext);
    314 
    315     /* If new state is operational, request switch to driver context for handling timer events */
    316     if (bOperState)
    317     {
    318         context_RequestSchedule (pTimerModule->hContext, pTimerModule->uContextId);
    319     }
    320 }
    321 
    322 
    323 
    324 /**
    325  * \fn     tmr_CreateTimer
    326  * \brief  Create a new timer
    327  *
    328  * Create a new timer object, icluding creating a timer in the OS-API.
    329  *
    330  * \note   This timer creation may be used only after tmr_Create() and tmr_Init() were executed!!
    331  * \param  hTimerModule - The module handle
    332  * \return TI_HANDLE    - The created timer handle
    333  * \sa     tmr_DestroyTimer
    334  */
    335 TI_HANDLE tmr_CreateTimer (TI_HANDLE hTimerModule)
    336 {
    337     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule; /* The timer module handle */
    338     TTimerInfo   *pTimerInfo;  /* The created timer handle */
    339 
    340     if (!pTimerModule)
    341     {
    342         WLAN_OS_REPORT (("tmr_CreateTimer(): ERROR - NULL timer!\n"));
    343         return NULL;
    344     }
    345 
    346     /* Allocate timer object */
    347     pTimerInfo = os_memoryAlloc (pTimerModule->hOs, sizeof(TTimerInfo));
    348     if (!pTimerInfo)
    349     {
    350         WLAN_OS_REPORT (("tmr_CreateTimer():  Timer allocation failed!!\n"));
    351         return NULL;
    352     }
    353     os_memoryZero (pTimerModule->hOs, pTimerInfo, (sizeof(TTimerInfo)));
    354 
    355     /* Allocate OS-API timer, providing the common expiry callback with the current timer handle */
    356     pTimerInfo->hOsTimerObj = os_timerCreate(pTimerModule->hOs, tmr_GetExpiry, (TI_HANDLE)pTimerInfo);
    357     if (!pTimerInfo->hOsTimerObj)
    358     {
    359         TRACE0(pTimerModule->hReport, REPORT_SEVERITY_CONSOLE ,"tmr_CreateTimer():  OS-API Timer allocation failed!!\n");
    360         os_memoryFree (pTimerModule->hOs, pTimerInfo, sizeof(TTimerInfo));
    361         WLAN_OS_REPORT (("tmr_CreateTimer():  OS-API Timer allocation failed!!\n"));
    362         return NULL;
    363     }
    364 
    365     /* Save the timer module handle in the created timer object (needed for the expiry callback) */
    366     pTimerInfo->hTimerModule = hTimerModule;
    367     pTimerModule->uTimersCount++;  /* count created timers */
    368 
    369     /* Return the created timer handle */
    370     return (TI_HANDLE)pTimerInfo;
    371 }
    372 
    373 
    374 /**
    375  * \fn     tmr_DestroyTimer
    376  * \brief  Destroy the specified timer
    377  *
    378  * Destroy the specified timer object, icluding the timer in the OS-API.
    379  *
    380  * \note   This timer destruction function should be used before tmr_Destroy() is executed!!
    381  * \param  hTimerInfo - The timer handle
    382  * \return TI_OK on success or TI_NOK on failure
    383  * \sa     tmr_CreateTimer
    384  */
    385 TI_STATUS tmr_DestroyTimer (TI_HANDLE hTimerInfo)
    386 {
    387     TTimerInfo *pTimerInfo = (TTimerInfo *)hTimerInfo;  /* The timer handle */
    388     TTimerModule *pTimerModule;                  /* The timer module handle */
    389 
    390     if (!pTimerInfo)
    391     {
    392         return TI_NOK;
    393     }
    394     pTimerModule = (TTimerModule *)pTimerInfo->hTimerModule;
    395     if (!pTimerModule)
    396     {
    397         WLAN_OS_REPORT (("tmr_DestroyTimer(): ERROR - NULL timer!\n"));
    398         return TI_NOK;
    399     }
    400 
    401     /* Free the OS-API timer */
    402     if (pTimerInfo->hOsTimerObj) {
    403         os_timerDestroy (pTimerModule->hOs, pTimerInfo->hOsTimerObj);
    404         pTimerModule->uTimersCount--;  /* update created timers number */
    405     }
    406     /* Free the timer object */
    407     os_memoryFree (pTimerModule->hOs, hTimerInfo, sizeof(TTimerInfo));
    408     return TI_OK;
    409 }
    410 
    411 
    412 /**
    413  * \fn     tmr_StartTimer
    414  * \brief  Start a timer
    415  *
    416  * Start the specified timer running.
    417  *
    418  * \note   Periodic-Timer may be used by applications that serve the timer expiry
    419  *           in a single context.
    420  *         If an application can't finish serving the timer expiry in a single context,
    421  *           e.g. periodic scan, then it isn't recommended to use the periodic timer service.
    422  *         If such an application uses the periodic timer then it should protect itself from cases
    423  *            where the timer expires again before the previous timer expiry processing is finished!!
    424  * \param  hTimerInfo    - The specific timer handle
    425  * \param  fExpiryCbFunc - The timer's expiry callback function.
    426  * \param  hExpiryCbHndl - The client's expiry callback function handle.
    427  * \param  uIntervalMsec - The timer's duration in Msec.
    428  * \param  bPeriodic     - If TRUE, the timer is restarted after expiry.
    429  * \return void
    430  * \sa     tmr_StopTimer, tmr_GetExpiry
    431  */
    432 void tmr_StartTimer (TI_HANDLE     hTimerInfo,
    433                      TTimerCbFunc  fExpiryCbFunc,
    434                      TI_HANDLE     hExpiryCbHndl,
    435                      TI_UINT32     uIntervalMsec,
    436                      TI_BOOL       bPeriodic)
    437 {
    438     TTimerInfo   *pTimerInfo   = (TTimerInfo *)hTimerInfo;                 /* The timer handle */
    439     TTimerModule *pTimerModule = (TTimerModule *)pTimerInfo->hTimerModule; /* The timer module handle */
    440 
    441     if (!pTimerModule)
    442     {
    443         WLAN_OS_REPORT (("tmr_StartTimer(): ERROR - NULL timer!\n"));
    444         return;
    445     }
    446 
    447     /* Save the timer parameters. */
    448     pTimerInfo->fExpiryCbFunc            = fExpiryCbFunc;
    449     pTimerInfo->hExpiryCbHndl            = hExpiryCbHndl;
    450     pTimerInfo->uIntervalMsec            = uIntervalMsec;
    451     pTimerInfo->bPeriodic                = bPeriodic;
    452     pTimerInfo->bOperStateWhenStarted    = pTimerModule->bOperState;
    453     pTimerInfo->uTwdInitCountWhenStarted = pTimerModule->uTwdInitCount;
    454 
    455     /* Start OS-API timer running */
    456     os_timerStart(pTimerModule->hOs, pTimerInfo->hOsTimerObj, uIntervalMsec);
    457 }
    458 
    459 
    460 /**
    461  * \fn     tmr_StopTimer
    462  * \brief  Stop a running timer
    463  *
    464  * Stop the specified timer.
    465  *
    466  * \note   When using this function, it must be considered that timer expiry may happen
    467  *           right before the timer is stopped, so it can't be assumed that this completely
    468  *           prevents the timer expiry event!
    469  * \param  hTimerInfo - The specific timer handle
    470  * \return void
    471  * \sa     tmr_StartTimer
    472  */
    473 void tmr_StopTimer (TI_HANDLE hTimerInfo)
    474 {
    475     TTimerInfo   *pTimerInfo   = (TTimerInfo *)hTimerInfo;                 /* The timer handle */
    476     TTimerModule *pTimerModule = (TTimerModule *)pTimerInfo->hTimerModule; /* The timer module handle */
    477 
    478     if (!pTimerModule)
    479     {
    480         WLAN_OS_REPORT (("tmr_StopTimer(): ERROR - NULL timer!\n"));
    481         return;
    482     }
    483 
    484     /* Stop OS-API timer running */
    485     os_timerStop(pTimerModule->hOs, pTimerInfo->hOsTimerObj);
    486 
    487     /* Clear periodic flag to prevent timer restart if we are in tmr_HandleExpiry context. */
    488     pTimerInfo->bPeriodic = TI_FALSE;
    489 }
    490 
    491 
    492 /**
    493  * \fn     tmr_GetExpiry
    494  * \brief  Called by OS-API upon any timer expiry
    495  *
    496  * This is the common callback function called upon expiartion of any timer.
    497  * It is called by the OS-API in timer expiry context and handles the transition
    498  *   to the driver's context for handling the expiry event.
    499  *
    500  * \note
    501  * \param  hTimerInfo - The specific timer handle
    502  * \return void
    503  * \sa     tmr_HandleExpiry
    504  */
    505 void tmr_GetExpiry (TI_HANDLE hTimerInfo)
    506 {
    507     TTimerInfo   *pTimerInfo   = (TTimerInfo *)hTimerInfo;                 /* The timer handle */
    508     TTimerModule *pTimerModule = (TTimerModule *)pTimerInfo->hTimerModule; /* The timer module handle */
    509 
    510     if (!pTimerModule)
    511     {
    512         WLAN_OS_REPORT (("tmr_GetExpiry(): ERROR - NULL timer!\n"));
    513         return;
    514     }
    515 
    516     /* Enter critical section */
    517     context_EnterCriticalSection (pTimerModule->hContext);
    518 
    519     /*
    520      * If the expired timer was started when the driver's state was Operational,
    521      *   insert it to the Operational-queue
    522      */
    523     if (pTimerInfo->bOperStateWhenStarted)
    524     {
    525         que_Enqueue (pTimerModule->hOperQueue, hTimerInfo);
    526     }
    527 
    528     /*
    529      * Else (started when driver's state was NOT-Operational), if now the state is still
    530      *   NOT Operational insert it to the Init-queue.
    531      *   (If state changed from non-operational to operational the event is ignored)
    532      */
    533     else if (!pTimerModule->bOperState)
    534     {
    535         que_Enqueue (pTimerModule->hInitQueue, hTimerInfo);
    536     }
    537 
    538     /* Leave critical section */
    539     context_LeaveCriticalSection (pTimerModule->hContext);
    540 
    541     /* Request switch to driver context for handling timer events */
    542     context_RequestSchedule (pTimerModule->hContext, pTimerModule->uContextId);
    543 }
    544 
    545 
    546 /**
    547  * \fn     tmr_HandleExpiry
    548  * \brief  Handles queued expiry events in driver context
    549  *
    550  * This is the Timer module's callback that is registered to the ContextEngine module to be invoked
    551  *   from the driver task (after requested by tmr_GetExpiry through context_RequestSchedule ()).
    552  * It dequeues all expiry events from the queue that correlates to the current driver state,
    553  *   and calls their users callbacks.
    554  *
    555  * \note
    556  * \param  hTimerModule - The module object
    557  * \return void
    558  * \sa     tmr_GetExpiry
    559  */
    560 void tmr_HandleExpiry (TI_HANDLE hTimerModule)
    561 {
    562     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule; /* The timer module handle */
    563     TTimerInfo   *pTimerInfo;      /* The timer handle */
    564     TI_BOOL       bTwdInitOccured; /* Indicates if TWD init occured since timer start */
    565 
    566     if (!pTimerModule)
    567     {
    568         WLAN_OS_REPORT (("tmr_HandleExpiry(): ERROR - NULL timer!\n"));
    569         return;
    570     }
    571 
    572     while (1)
    573     {
    574         /* Enter critical section */
    575         context_EnterCriticalSection (pTimerModule->hContext);
    576 
    577         /* If current driver state is Operational, dequeue timer object from Operational-queue */
    578         if (pTimerModule->bOperState)
    579         {
    580             pTimerInfo = (TTimerInfo *) que_Dequeue (pTimerModule->hOperQueue);
    581         }
    582 
    583         /* Else (driver state is NOT-Operational), dequeue timer object from Init-queue */
    584         else
    585         {
    586             pTimerInfo = (TTimerInfo *) que_Dequeue (pTimerModule->hInitQueue);
    587         }
    588 
    589         /* Leave critical section */
    590         context_LeaveCriticalSection (pTimerModule->hContext);
    591 
    592         /* If no more objects in queue, exit */
    593         if (!pTimerInfo)
    594         {
    595             return;  /** EXIT Point **/
    596         }
    597 
    598         /* If current TWD-Init-Count is different than when the timer was started, Init occured. */
    599         bTwdInitOccured = (pTimerModule->uTwdInitCount != pTimerInfo->uTwdInitCountWhenStarted);
    600 
    601         /* Call specific timer callback function */
    602         pTimerInfo->fExpiryCbFunc (pTimerInfo->hExpiryCbHndl, bTwdInitOccured);
    603 
    604         /* If the expired timer is periodic, start it again. */
    605         if (pTimerInfo->bPeriodic)
    606         {
    607             tmr_StartTimer ((TI_HANDLE)pTimerInfo,
    608                             pTimerInfo->fExpiryCbFunc,
    609                             pTimerInfo->hExpiryCbHndl,
    610                             pTimerInfo->uIntervalMsec,
    611                             pTimerInfo->bPeriodic);
    612         }
    613     }
    614 }
    615 
    616 
    617 /**
    618  * \fn     tmr_PrintModule / tmr_PrintTimer
    619  * \brief  Print module / timer information
    620  *
    621  * Print the module's information / a specific timer information.
    622  *
    623  * \note
    624  * \param  The module / timer handle
    625  * \return void
    626  * \sa
    627  */
    628 
    629 #ifdef TI_DBG
    630 
    631 void tmr_PrintModule (TI_HANDLE hTimerModule)
    632 {
    633     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
    634 
    635     if (!pTimerModule)
    636     {
    637         WLAN_OS_REPORT (("tmr_PrintModule(): ERROR - NULL timer!\n"));
    638         return;
    639     }
    640 
    641     /* Print module parameters */
    642     WLAN_OS_REPORT(("tmr_PrintModule(): uContextId=%d, bOperState=%d, uTwdInitCount=%d, uTimersCount=%d\n",
    643     pTimerModule->uContextId, pTimerModule->bOperState,
    644     pTimerModule->uTwdInitCount, pTimerModule->uTimersCount));
    645 
    646     /* Print Init Queue Info */
    647     WLAN_OS_REPORT(("tmr_PrintModule(): Init-Queue:\n"));
    648     que_Print(pTimerModule->hInitQueue);
    649 
    650     /* Print Operational Queue Info */
    651     WLAN_OS_REPORT(("tmr_PrintModule(): Operational-Queue:\n"));
    652     que_Print(pTimerModule->hOperQueue);
    653 }
    654 
    655 void tmr_PrintTimer (TI_HANDLE hTimerInfo)
    656 {
    657 #ifdef REPORT_LOG
    658     TTimerInfo   *pTimerInfo   = (TTimerInfo *)hTimerInfo;                 /* The timer handle */
    659 
    660     WLAN_OS_REPORT(("tmr_PrintTimer(): uIntervalMs=%d, bPeriodic=%d, bOperStateWhenStarted=%d, uTwdInitCountWhenStarted=%d, hOsTimerObj=0x%x, fExpiryCbFunc=0x%x\n",
    661     pTimerInfo->uIntervalMsec, pTimerInfo->bPeriodic, pTimerInfo->bOperStateWhenStarted,
    662     pTimerInfo->uTwdInitCountWhenStarted, pTimerInfo->hOsTimerObj, pTimerInfo->fExpiryCbFunc));
    663 #endif
    664 }
    665 
    666 #endif /* TI_DBG */
    667