Home | History | Annotate | Download | only in common
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 1999-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #include <assert.h>
     20 #include <utils/Log.h>
     21 #include "gki_int.h"
     22 
     23 /* Make sure that this has been defined in target.h */
     24 #ifndef GKI_NUM_TIMERS
     25 #error  NO TIMERS: Must define at least 1 timer in the system!
     26 #endif
     27 
     28 
     29 #define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL)   /* Largest signed positive timer count */
     30 
     31 // Used for controlling alarms from AlarmService.
     32 extern void alarm_service_reschedule(void);
     33 
     34 /*******************************************************************************
     35 **
     36 ** Function         gki_timers_init
     37 **
     38 ** Description      This internal function is called once at startup to initialize
     39 **                  all the timer structures.
     40 **
     41 ** Returns          void
     42 **
     43 *******************************************************************************/
     44 void gki_timers_init(void)
     45 {
     46     UINT8   tt;
     47 
     48     gki_cb.com.OSTicksTilExp = 0;       /* Remaining time (of OSTimeCurTimeout) before next timer expires */
     49     gki_cb.com.OSNumOrigTicks = 0;
     50 
     51     for (tt = 0; tt < GKI_MAX_TASKS; tt++)
     52     {
     53         gki_cb.com.OSWaitTmr   [tt] = 0;
     54 
     55 #if (GKI_NUM_TIMERS > 0)
     56         gki_cb.com.OSTaskTmr0  [tt] = 0;
     57         gki_cb.com.OSTaskTmr0R [tt] = 0;
     58 #endif
     59 
     60 #if (GKI_NUM_TIMERS > 1)
     61         gki_cb.com.OSTaskTmr1  [tt] = 0;
     62         gki_cb.com.OSTaskTmr1R [tt] = 0;
     63 #endif
     64 
     65 #if (GKI_NUM_TIMERS > 2)
     66         gki_cb.com.OSTaskTmr2  [tt] = 0;
     67         gki_cb.com.OSTaskTmr2R [tt] = 0;
     68 #endif
     69 
     70 #if (GKI_NUM_TIMERS > 3)
     71         gki_cb.com.OSTaskTmr3  [tt] = 0;
     72         gki_cb.com.OSTaskTmr3R [tt] = 0;
     73 #endif
     74     }
     75 
     76     return;
     77 }
     78 
     79 /*******************************************************************************
     80 **
     81 ** Function         gki_timers_is_timer_running
     82 **
     83 ** Description      This internal function is called to test if any gki timer are running
     84 **
     85 **
     86 ** Returns          TRUE if at least one time is running in the system, FALSE else.
     87 **
     88 *******************************************************************************/
     89 BOOLEAN gki_timers_is_timer_running(void)
     90 {
     91     UINT8   tt;
     92     for (tt = 0; tt < GKI_MAX_TASKS; tt++)
     93     {
     94 
     95 #if (GKI_NUM_TIMERS > 0)
     96         if(gki_cb.com.OSTaskTmr0  [tt])
     97         {
     98             return TRUE;
     99         }
    100 #endif
    101 
    102 #if (GKI_NUM_TIMERS > 1)
    103         if(gki_cb.com.OSTaskTmr1  [tt] )
    104         {
    105             return TRUE;
    106         }
    107 #endif
    108 
    109 #if (GKI_NUM_TIMERS > 2)
    110         if(gki_cb.com.OSTaskTmr2  [tt] )
    111         {
    112             return TRUE;
    113         }
    114 #endif
    115 
    116 #if (GKI_NUM_TIMERS > 3)
    117         if(gki_cb.com.OSTaskTmr3  [tt] )
    118         {
    119             return TRUE;
    120         }
    121 #endif
    122     }
    123 
    124     return FALSE;
    125 
    126 }
    127 
    128 /*******************************************************************************
    129 **
    130 ** Function         GKI_get_tick_count
    131 **
    132 ** Description      This function returns the current system ticks
    133 **
    134 ** Returns          The current number of system ticks
    135 **
    136 *******************************************************************************/
    137 UINT32  GKI_get_tick_count(void)
    138 {
    139     return gki_cb.com.OSTicks;
    140 }
    141 
    142 
    143 /*******************************************************************************
    144 **
    145 ** Function         GKI_ready_to_sleep
    146 **
    147 ** Description      This function returns the number of system ticks until the
    148 **                  next timer will expire.  It is typically called by a power
    149 **                  savings manager to find out how long it can have the system
    150 **                  sleep before it needs to service the next entry.
    151 **
    152 ** Parameters:      None
    153 **
    154 ** Returns          Number of ticks til the next timer expires
    155 **                  Note: the value is a signed  value.  This value should be
    156 **                      compared to x > 0, to avoid misinterpreting negative tick
    157 **                      values.
    158 **
    159 *******************************************************************************/
    160 INT32    GKI_ready_to_sleep (void)
    161 {
    162     return (gki_cb.com.OSTicksTilExp);
    163 }
    164 
    165 
    166 /*******************************************************************************
    167 **
    168 ** Function         GKI_start_timer
    169 **
    170 ** Description      An application can call this function to start one of
    171 **                  it's four general purpose timers. Any of the four timers
    172 **                  can be 1-shot or continuous. If a timer is already running,
    173 **                  it will be reset to the new parameters.
    174 **
    175 ** Parameters       tnum            - (input) timer number to be started (TIMER_0,
    176 **                                              TIMER_1, TIMER_2, or TIMER_3)
    177 **                  ticks           - (input) the number of system ticks til the
    178 **                                              timer expires.
    179 **                  is_continuous   - (input) TRUE if timer restarts automatically,
    180 **                                              else FALSE if it is a 'one-shot'.
    181 **
    182 ** Returns          void
    183 **
    184 *******************************************************************************/
    185 void GKI_start_timer (UINT8 tnum, INT32 ticks, BOOLEAN is_continuous)
    186 {
    187     INT32   reload;
    188     INT32   orig_ticks;
    189     UINT8   task_id = GKI_get_taskid();
    190     BOOLEAN bad_timer = FALSE;
    191 
    192     if (ticks <= 0)
    193         ticks = 1;
    194 
    195     orig_ticks = ticks;     /* save the ticks in case adjustment is necessary */
    196 
    197 
    198     /* If continuous timer, set reload, else set it to 0 */
    199     if (is_continuous)
    200         reload = ticks;
    201     else
    202         reload = 0;
    203 
    204     GKI_disable();
    205 
    206     /* Add the time since the last task timer update.
    207     ** Note that this works when no timers are active since
    208     ** both OSNumOrigTicks and OSTicksTilExp are 0.
    209     */
    210     if (INT32_MAX - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) > ticks)
    211     {
    212         ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
    213     }
    214     else
    215         ticks = INT32_MAX;
    216 
    217     switch (tnum)
    218     {
    219 #if (GKI_NUM_TIMERS > 0)
    220         case TIMER_0:
    221             gki_cb.com.OSTaskTmr0R[task_id] = reload;
    222             gki_cb.com.OSTaskTmr0 [task_id] = ticks;
    223             break;
    224 #endif
    225 
    226 #if (GKI_NUM_TIMERS > 1)
    227         case TIMER_1:
    228             gki_cb.com.OSTaskTmr1R[task_id] = reload;
    229             gki_cb.com.OSTaskTmr1 [task_id] = ticks;
    230             break;
    231 #endif
    232 
    233 #if (GKI_NUM_TIMERS > 2)
    234         case TIMER_2:
    235             gki_cb.com.OSTaskTmr2R[task_id] = reload;
    236             gki_cb.com.OSTaskTmr2 [task_id] = ticks;
    237             break;
    238 #endif
    239 
    240 #if (GKI_NUM_TIMERS > 3)
    241         case TIMER_3:
    242             gki_cb.com.OSTaskTmr3R[task_id] = reload;
    243             gki_cb.com.OSTaskTmr3 [task_id] = ticks;
    244             break;
    245 #endif
    246         default:
    247             bad_timer = TRUE;       /* Timer number is bad, so do not use */
    248     }
    249 
    250     /* Update the expiration timeout if a legitimate timer */
    251     if (!bad_timer)
    252     {
    253         /* Only update the timeout value if it is less than any other newly started timers */
    254         gki_adjust_timer_count (orig_ticks);
    255     }
    256 
    257     GKI_enable();
    258 
    259 }
    260 
    261 /*******************************************************************************
    262 **
    263 ** Function         GKI_stop_timer
    264 **
    265 ** Description      An application can call this function to stop one of
    266 **                  it's four general purpose timers. There is no harm in
    267 **                  stopping a timer that is already stopped.
    268 **
    269 ** Parameters       tnum            - (input) timer number to be started (TIMER_0,
    270 **                                              TIMER_1, TIMER_2, or TIMER_3)
    271 ** Returns          void
    272 **
    273 *******************************************************************************/
    274 void GKI_stop_timer (UINT8 tnum)
    275 {
    276     UINT8  task_id = GKI_get_taskid();
    277 
    278     switch (tnum)
    279     {
    280 #if (GKI_NUM_TIMERS > 0)
    281         case TIMER_0:
    282             gki_cb.com.OSTaskTmr0R[task_id] = 0;
    283             gki_cb.com.OSTaskTmr0 [task_id] = 0;
    284             break;
    285 #endif
    286 
    287 #if (GKI_NUM_TIMERS > 1)
    288         case TIMER_1:
    289             gki_cb.com.OSTaskTmr1R[task_id] = 0;
    290             gki_cb.com.OSTaskTmr1 [task_id] = 0;
    291             break;
    292 #endif
    293 
    294 #if (GKI_NUM_TIMERS > 2)
    295         case TIMER_2:
    296             gki_cb.com.OSTaskTmr2R[task_id] = 0;
    297             gki_cb.com.OSTaskTmr2 [task_id] = 0;
    298             break;
    299 #endif
    300 
    301 #if (GKI_NUM_TIMERS > 3)
    302         case TIMER_3:
    303             gki_cb.com.OSTaskTmr3R[task_id] = 0;
    304             gki_cb.com.OSTaskTmr3 [task_id] = 0;
    305             break;
    306 #endif
    307     }
    308 }
    309 
    310 
    311 /*******************************************************************************
    312 **
    313 ** Function         GKI_timer_update
    314 **
    315 ** Description      This function is called by an OS to drive the GKI's timers.
    316 **                  It is typically called at every system tick to
    317 **                  update the timers for all tasks, and check for timeouts.
    318 **
    319 **                  Note: It has been designed to also allow for variable tick updates
    320 **                      so that systems with strict power savings requirements can
    321 **                      have the update occur at variable intervals.
    322 **
    323 ** Parameters:      ticks_since_last_update - (input) This is the number of TICKS that have
    324 **                          occurred since the last time GKI_timer_update was called.
    325 **
    326 ** Returns          void
    327 **
    328 *******************************************************************************/
    329 void GKI_timer_update (INT32 ticks_since_last_update)
    330 {
    331     UINT8   task_id;
    332     long    next_expiration;        /* Holds the next soonest expiration time after this update */
    333 
    334     /* Increment the number of ticks used for time stamps */
    335     gki_cb.com.OSTicks += ticks_since_last_update;
    336 
    337     /* If any timers are running in any tasks, decrement the remaining time til
    338      * the timer updates need to take place (next expiration occurs)
    339      */
    340     gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
    341 
    342     /* Don't allow timer interrupt nesting */
    343     if (gki_cb.com.timer_nesting)
    344         return;
    345 
    346     gki_cb.com.timer_nesting = 1;
    347 
    348     /* No need to update the ticks if no timeout has occurred */
    349     if (gki_cb.com.OSTicksTilExp > 0)
    350     {
    351         // When using alarms from AlarmService we should
    352         // always have work to be done here.
    353         ALOGE("%s no work to be done when expected work", __func__);
    354         gki_cb.com.timer_nesting = 0;
    355         return;
    356     }
    357 
    358     next_expiration = GKI_NO_NEW_TMRS_STARTED;
    359 
    360     /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase gki_cb.com.OSNumOrigTicks
    361        to account for the difference so timer updates below are decremented by the full number
    362        of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function so changing this
    363        value only affects the timer updates below
    364      */
    365     gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
    366 
    367     /* Protect this section because if a GKI_timer_stop happens between:
    368      *   - gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
    369      *   - gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
    370      * then the timer may appear stopped while it is about to be reloaded.
    371      */
    372     GKI_disable();
    373 
    374     /* Check for OS Task Timers */
    375     for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
    376     {
    377         if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
    378         {
    379             gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
    380             if (gki_cb.com.OSWaitTmr[task_id] <= 0)
    381             {
    382                 /* Timer Expired */
    383                 gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
    384             }
    385         }
    386 
    387 #if (GKI_NUM_TIMERS > 0)
    388          /* If any timer is running, decrement */
    389         if (gki_cb.com.OSTaskTmr0[task_id] > 0)
    390         {
    391             gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
    392 
    393             if (gki_cb.com.OSTaskTmr0[task_id] <= 0)
    394             {
    395                 /* Reload timer and set Timer 0 Expired event mask */
    396                 gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
    397                 GKI_send_event (task_id, TIMER_0_EVT_MASK);
    398             }
    399         }
    400 
    401         /* Check to see if this timer is the next one to expire */
    402         if (gki_cb.com.OSTaskTmr0[task_id] > 0 && gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
    403             next_expiration = gki_cb.com.OSTaskTmr0[task_id];
    404 #endif
    405 
    406 #if (GKI_NUM_TIMERS > 1)
    407          /* If any timer is running, decrement */
    408         if (gki_cb.com.OSTaskTmr1[task_id] > 0)
    409         {
    410             gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
    411 
    412             if (gki_cb.com.OSTaskTmr1[task_id] <= 0)
    413             {
    414                 /* Reload timer and set Timer 1 Expired event mask */
    415                 gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
    416                 GKI_send_event (task_id, TIMER_1_EVT_MASK);
    417             }
    418         }
    419 
    420         /* Check to see if this timer is the next one to expire */
    421         if (gki_cb.com.OSTaskTmr1[task_id] > 0 && gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
    422             next_expiration = gki_cb.com.OSTaskTmr1[task_id];
    423 #endif
    424 
    425 #if (GKI_NUM_TIMERS > 2)
    426          /* If any timer is running, decrement */
    427         if (gki_cb.com.OSTaskTmr2[task_id] > 0)
    428         {
    429             gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
    430 
    431             if (gki_cb.com.OSTaskTmr2[task_id] <= 0)
    432             {
    433                 /* Reload timer and set Timer 2 Expired event mask */
    434                 gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
    435                 GKI_send_event (task_id, TIMER_2_EVT_MASK);
    436             }
    437         }
    438 
    439         /* Check to see if this timer is the next one to expire */
    440         if (gki_cb.com.OSTaskTmr2[task_id] > 0 && gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
    441             next_expiration = gki_cb.com.OSTaskTmr2[task_id];
    442 #endif
    443 
    444 #if (GKI_NUM_TIMERS > 3)
    445          /* If any timer is running, decrement */
    446         if (gki_cb.com.OSTaskTmr3[task_id] > 0)
    447         {
    448             gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
    449 
    450             if (gki_cb.com.OSTaskTmr3[task_id] <= 0)
    451             {
    452                 /* Reload timer and set Timer 3 Expired event mask */
    453                 gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
    454                 GKI_send_event (task_id, TIMER_3_EVT_MASK);
    455             }
    456         }
    457 
    458         /* Check to see if this timer is the next one to expire */
    459         if (gki_cb.com.OSTaskTmr3[task_id] > 0 && gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
    460             next_expiration = gki_cb.com.OSTaskTmr3[task_id];
    461 #endif
    462 
    463     }
    464     /* Set the next timer experation value if there is one to start */
    465     if (next_expiration < GKI_NO_NEW_TMRS_STARTED)
    466     {
    467         gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
    468     }
    469     else
    470     {
    471         gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
    472     }
    473 
    474     // Set alarm service for next alarm.
    475     alarm_service_reschedule();
    476 
    477     GKI_enable();
    478 
    479     gki_cb.com.timer_nesting = 0;
    480 
    481     return;
    482 }
    483 
    484 /*******************************************************************************
    485 **
    486 ** Function         GKI_init_timer_list
    487 **
    488 ** Description      This function is called by applications when they
    489 **                  want to initialize a timer list.
    490 **
    491 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
    492 **
    493 ** Returns          void
    494 **
    495 *******************************************************************************/
    496 void GKI_init_timer_list(TIMER_LIST_Q *timer_q) {
    497     timer_q->p_first    = NULL;
    498     timer_q->p_last     = NULL;
    499 }
    500 
    501 bool GKI_timer_queue_is_empty(const TIMER_LIST_Q *timer_q) {
    502     assert(timer_q != NULL);
    503     return (timer_q->p_first == NULL);
    504 }
    505 
    506 TIMER_LIST_ENT *GKI_timer_getfirst(const TIMER_LIST_Q *timer_q) {
    507     assert(timer_q != NULL);
    508     return timer_q->p_first;
    509 }
    510 
    511 /* Returns the initial number of ticks for this timer entry. */
    512 INT32 GKI_timer_ticks_getinitial(const TIMER_LIST_ENT *tle) {
    513     assert(tle != NULL);
    514     return tle->ticks_initial;
    515 }
    516 
    517 /*******************************************************************************
    518 **
    519 ** Function         GKI_update_timer_list
    520 **
    521 ** Description      This function is called by the applications when they
    522 **                  want to update a timer list. This should be at every
    523 **                  timer list unit tick, e.g. once per sec, once per minute etc.
    524 **
    525 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
    526 **                  num_units_since_last_update - (input) number of units since the last update
    527 **                                  (allows for variable unit update)
    528 **
    529 **      NOTE: The following timer list update routines should not be used for exact time
    530 **            critical purposes.  The timer tasks should be used when exact timing is needed.
    531 **
    532 ** Returns          the number of timers that have expired
    533 **
    534 *******************************************************************************/
    535 UINT16 GKI_update_timer_list (TIMER_LIST_Q *p_timer_listq, INT32 num_units_since_last_update)
    536 {
    537     TIMER_LIST_ENT  *p_tle;
    538     UINT16           num_time_out = 0;
    539     INT32            rem_ticks;
    540     INT32            temp_ticks;
    541 
    542     p_tle = p_timer_listq->p_first;
    543 
    544     /* First, get the guys who have previously timed out */
    545     /* Note that the tick value of the timers should always be '0' */
    546     while ((p_tle) && (p_tle->ticks <= 0))
    547     {
    548         num_time_out++;
    549         p_tle = p_tle->p_next;
    550     }
    551 
    552     /* Timer entriy tick values are relative to the preceeding entry */
    553     rem_ticks = num_units_since_last_update;
    554 
    555     /* Now, adjust remaining timer entries */
    556     while ((p_tle != NULL) && (rem_ticks > 0))
    557     {
    558         temp_ticks = p_tle->ticks;
    559         p_tle->ticks -= rem_ticks;
    560 
    561         /* See if this timer has just timed out */
    562         if (p_tle->ticks <= 0)
    563         {
    564             /* We set the number of ticks to '0' so that the legacy code
    565              * that assumes a '0' or nonzero value will still work as coded. */
    566             p_tle->ticks = 0;
    567 
    568             num_time_out++;
    569         }
    570 
    571         rem_ticks -= temp_ticks;  /* Decrement the remaining ticks to process */
    572         p_tle = p_tle->p_next;
    573     }
    574 
    575     return (num_time_out);
    576 }
    577 
    578 /*******************************************************************************
    579 **
    580 ** Function         GKI_get_remaining_ticks
    581 **
    582 ** Description      This function is called by an application to get remaining
    583 **                  ticks to expire
    584 **
    585 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
    586 **                  p_target_tle    - (input) pointer to a timer list queue entry
    587 **
    588 ** Returns          0 if timer is not used or timer is not in the list
    589 **                  remaining ticks if success
    590 **
    591 *******************************************************************************/
    592 UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_target_tle)
    593 {
    594     TIMER_LIST_ENT  *p_tle;
    595     UINT32           rem_ticks = 0;
    596 
    597     if (p_target_tle->in_use)
    598     {
    599         p_tle = p_timer_listq->p_first;
    600 
    601         /* adding up all of ticks in previous entries */
    602         while ((p_tle)&&(p_tle != p_target_tle))
    603         {
    604             rem_ticks += p_tle->ticks;
    605             p_tle = p_tle->p_next;
    606         }
    607 
    608         /* if found target entry */
    609         if (p_tle == p_target_tle)
    610         {
    611             rem_ticks += p_tle->ticks;
    612         }
    613         else
    614         {
    615             return(0);
    616         }
    617     }
    618 
    619     return (rem_ticks);
    620 }
    621 
    622 /*******************************************************************************
    623 **
    624 ** Function         GKI_add_to_timer_list
    625 **
    626 ** Description      This function is called by an application to add a timer
    627 **                  entry to a timer list.
    628 **
    629 **                  Note: A timer value of '0' will effectively insert an already
    630 **                      expired event.  Negative tick values will be ignored.
    631 **
    632 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
    633 **                  p_tle           - (input) pointer to a timer list queue entry
    634 **
    635 ** Returns          void
    636 **
    637 *******************************************************************************/
    638 void GKI_add_to_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
    639 {
    640     /* Only process valid tick values. */
    641     if (p_tle->ticks < 0)
    642         return;
    643 
    644     p_tle->p_prev = NULL;
    645     p_tle->p_next = NULL;
    646     p_tle->in_use = true;
    647 
    648     /* Insert at head. */
    649     if (p_timer_listq->p_first == NULL)
    650     {
    651         p_timer_listq->p_first = p_tle;
    652         p_timer_listq->p_last = p_tle;
    653         return;
    654     }
    655 
    656     /* Find the node before which we need to insert p_tle. */
    657     TIMER_LIST_ENT *i = p_timer_listq->p_first;
    658     while (i && p_tle->ticks > i->ticks)
    659     {
    660         if (i->ticks > 0)
    661             p_tle->ticks -= i->ticks;
    662         i = i->p_next;
    663     }
    664 
    665     /* Insert at tail. */
    666     if (!i)
    667     {
    668         p_timer_listq->p_last->p_next = p_tle;
    669         p_tle->p_prev = p_timer_listq->p_last;
    670         p_timer_listq->p_last = p_tle;
    671         return;
    672     }
    673 
    674     p_tle->p_prev = i->p_prev;
    675     if (p_tle->p_prev)
    676         p_tle->p_prev->p_next = p_tle;
    677     p_tle->p_next = i;
    678     i->p_prev = p_tle;
    679     i->ticks -= p_tle->ticks;
    680 
    681     if (p_timer_listq->p_first == i)
    682         p_timer_listq->p_first = p_tle;
    683 }
    684 
    685 
    686 /*******************************************************************************
    687 **
    688 ** Function         GKI_remove_from_timer_list
    689 **
    690 ** Description      This function is called by an application to remove a timer
    691 **                  entry from a timer list.
    692 **
    693 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
    694 **                  p_tle           - (input) pointer to a timer list queue entry
    695 **
    696 ** Returns          TRUE if the entry has been unlinked successfully
    697 **
    698 *******************************************************************************/
    699 BOOLEAN GKI_remove_from_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
    700 {
    701     UINT8 tt;
    702 
    703     /* Verify that the entry is valid */
    704     if (p_tle == NULL || p_timer_listq->p_first == NULL)
    705         return FALSE;
    706 
    707     /* Add the ticks remaining in this timer (if any) to the next guy in the list.
    708     ** Note: Expired timers have a tick value of '0'.
    709     */
    710     if (p_tle->p_next != NULL)
    711     {
    712         p_tle->p_next->ticks += p_tle->ticks;
    713     }
    714 
    715     p_tle->ticks = 0;
    716     p_tle->in_use = FALSE;
    717 
    718     /* Unlink timer from the list.
    719     */
    720     if (p_timer_listq->p_first == p_tle)
    721     {
    722         p_timer_listq->p_first = p_tle->p_next;
    723 
    724         if (p_timer_listq->p_first != NULL)
    725             p_timer_listq->p_first->p_prev = NULL;
    726 
    727         if (p_timer_listq->p_last == p_tle)
    728             p_timer_listq->p_last = NULL;
    729     }
    730     else
    731     {
    732         if (p_timer_listq->p_last == p_tle)
    733         {
    734             p_timer_listq->p_last = p_tle->p_prev;
    735 
    736             if (p_timer_listq->p_last != NULL)
    737                 p_timer_listq->p_last->p_next = NULL;
    738         }
    739         else
    740         {
    741             if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle)
    742                 p_tle->p_next->p_prev = p_tle->p_prev;
    743             else
    744                 return FALSE; // Timer list broken?!
    745 
    746             if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle)
    747                 p_tle->p_prev->p_next = p_tle->p_next;
    748             else
    749                 return FALSE; // Timer list broken?!
    750         }
    751     }
    752 
    753     p_tle->p_next = p_tle->p_prev = NULL;
    754     return TRUE;
    755 }
    756 
    757 
    758 /*******************************************************************************
    759 **
    760 ** Function         gki_adjust_timer_count
    761 **
    762 ** Description      This function is called whenever a new timer or GKI_wait occurs
    763 **                  to adjust (if necessary) the current time til the first expiration.
    764 **                  This only needs to make an adjustment if the new timer (in ticks) is
    765 **                  less than the number of ticks remaining on the current timer.
    766 **
    767 ** Parameters:      ticks - (input) number of system ticks of the new timer entry
    768 **
    769 **                  NOTE:  This routine MUST be called while interrupts are disabled to
    770 **                          avoid updates while adjusting the timer variables.
    771 **
    772 ** Returns          void
    773 **
    774 *******************************************************************************/
    775 void gki_adjust_timer_count (INT32 ticks)
    776 {
    777     if (ticks > 0)
    778     {
    779         /* See if the new timer expires before the current first expiration */
    780         if (gki_cb.com.OSNumOrigTicks == 0 || (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0))
    781         {
    782             gki_cb.com.OSNumOrigTicks = (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
    783             gki_cb.com.OSTicksTilExp = ticks;
    784             alarm_service_reschedule();
    785         }
    786     }
    787 
    788     return;
    789 }
    790