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 
     20 #include "gki_int.h"
     21 
     22 #ifndef BT_ERROR_TRACE_0
     23 #define BT_ERROR_TRACE_0(l,m)
     24 #endif
     25 
     26 /* Make sure that this has been defined in target.h */
     27 #ifndef GKI_NUM_TIMERS
     28 #error  NO TIMERS: Must define at least 1 timer in the system!
     29 #endif
     30 
     31 
     32 #define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL)   /* Largest signed positive timer count */
     33 #define GKI_UNUSED_LIST_ENTRY   (0x80000000L)   /* Marks an unused timer list entry (initial value) */
     34 #define GKI_MAX_INT32           (0x7fffffffL)
     35 
     36 /*******************************************************************************
     37 **
     38 ** Function         gki_timers_init
     39 **
     40 ** Description      This internal function is called once at startup to initialize
     41 **                  all the timer structures.
     42 **
     43 ** Returns          void
     44 **
     45 *******************************************************************************/
     46 void gki_timers_init(void)
     47 {
     48     UINT8   tt;
     49 
     50     gki_cb.com.OSTicksTilExp = 0;       /* Remaining time (of OSTimeCurTimeout) before next timer expires */
     51     gki_cb.com.OSNumOrigTicks = 0;
     52 #if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
     53     gki_cb.com.OSTicksTilStop = 0;      /* clear inactivity delay timer */
     54 #endif
     55 
     56     for (tt = 0; tt < GKI_MAX_TASKS; tt++)
     57     {
     58         gki_cb.com.OSWaitTmr   [tt] = 0;
     59 
     60 #if (GKI_NUM_TIMERS > 0)
     61         gki_cb.com.OSTaskTmr0  [tt] = 0;
     62         gki_cb.com.OSTaskTmr0R [tt] = 0;
     63 #endif
     64 
     65 #if (GKI_NUM_TIMERS > 1)
     66         gki_cb.com.OSTaskTmr1  [tt] = 0;
     67         gki_cb.com.OSTaskTmr1R [tt] = 0;
     68 #endif
     69 
     70 #if (GKI_NUM_TIMERS > 2)
     71         gki_cb.com.OSTaskTmr2  [tt] = 0;
     72         gki_cb.com.OSTaskTmr2R [tt] = 0;
     73 #endif
     74 
     75 #if (GKI_NUM_TIMERS > 3)
     76         gki_cb.com.OSTaskTmr3  [tt] = 0;
     77         gki_cb.com.OSTaskTmr3R [tt] = 0;
     78 #endif
     79     }
     80 
     81     for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
     82     {
     83         gki_cb.com.timer_queues[tt] = NULL;
     84     }
     85 
     86     gki_cb.com.p_tick_cb = NULL;
     87     gki_cb.com.system_tick_running = FALSE;
     88 
     89     return;
     90 }
     91 
     92 /*******************************************************************************
     93 **
     94 ** Function         gki_timers_is_timer_running
     95 **
     96 ** Description      This internal function is called to test if any gki timer are running
     97 **
     98 **
     99 ** Returns          TRUE if at least one time is running in the system, FALSE else.
    100 **
    101 *******************************************************************************/
    102 BOOLEAN gki_timers_is_timer_running(void)
    103 {
    104     UINT8   tt;
    105     for (tt = 0; tt < GKI_MAX_TASKS; tt++)
    106     {
    107 
    108 #if (GKI_NUM_TIMERS > 0)
    109         if(gki_cb.com.OSTaskTmr0  [tt])
    110         {
    111             return TRUE;
    112         }
    113 #endif
    114 
    115 #if (GKI_NUM_TIMERS > 1)
    116         if(gki_cb.com.OSTaskTmr1  [tt] )
    117         {
    118             return TRUE;
    119         }
    120 #endif
    121 
    122 #if (GKI_NUM_TIMERS > 2)
    123         if(gki_cb.com.OSTaskTmr2  [tt] )
    124         {
    125             return TRUE;
    126         }
    127 #endif
    128 
    129 #if (GKI_NUM_TIMERS > 3)
    130         if(gki_cb.com.OSTaskTmr3  [tt] )
    131         {
    132             return TRUE;
    133         }
    134 #endif
    135     }
    136 
    137     return FALSE;
    138 
    139 }
    140 
    141 /*******************************************************************************
    142 **
    143 ** Function         GKI_get_tick_count
    144 **
    145 ** Description      This function returns the current system ticks
    146 **
    147 ** Returns          The current number of system ticks
    148 **
    149 *******************************************************************************/
    150 UINT32  GKI_get_tick_count(void)
    151 {
    152     return gki_cb.com.OSTicks;
    153 }
    154 
    155 
    156 /*******************************************************************************
    157 **
    158 ** Function         GKI_ready_to_sleep
    159 **
    160 ** Description      This function returns the number of system ticks until the
    161 **                  next timer will expire.  It is typically called by a power
    162 **                  savings manager to find out how long it can have the system
    163 **                  sleep before it needs to service the next entry.
    164 **
    165 ** Parameters:      None
    166 **
    167 ** Returns          Number of ticks til the next timer expires
    168 **                  Note: the value is a signed  value.  This value should be
    169 **                      compared to x > 0, to avoid misinterpreting negative tick
    170 **                      values.
    171 **
    172 *******************************************************************************/
    173 INT32    GKI_ready_to_sleep (void)
    174 {
    175     return (gki_cb.com.OSTicksTilExp);
    176 }
    177 
    178 
    179 /*******************************************************************************
    180 **
    181 ** Function         GKI_start_timer
    182 **
    183 ** Description      An application can call this function to start one of
    184 **                  it's four general purpose timers. Any of the four timers
    185 **                  can be 1-shot or continuous. If a timer is already running,
    186 **                  it will be reset to the new parameters.
    187 **
    188 ** Parameters       tnum            - (input) timer number to be started (TIMER_0,
    189 **                                              TIMER_1, TIMER_2, or TIMER_3)
    190 **                  ticks           - (input) the number of system ticks til the
    191 **                                              timer expires.
    192 **                  is_continuous   - (input) TRUE if timer restarts automatically,
    193 **                                              else FALSE if it is a 'one-shot'.
    194 **
    195 ** Returns          void
    196 **
    197 *******************************************************************************/
    198 void GKI_start_timer (UINT8 tnum, INT32 ticks, BOOLEAN is_continuous)
    199 {
    200     INT32   reload;
    201     INT32   orig_ticks;
    202     UINT8   task_id = GKI_get_taskid();
    203     BOOLEAN bad_timer = FALSE;
    204 
    205     if (ticks <= 0)
    206         ticks = 1;
    207 
    208     orig_ticks = ticks;     /* save the ticks in case adjustment is necessary */
    209 
    210 
    211     /* If continuous timer, set reload, else set it to 0 */
    212     if (is_continuous)
    213         reload = ticks;
    214     else
    215         reload = 0;
    216 
    217     GKI_disable();
    218 
    219     if(gki_timers_is_timer_running() == FALSE)
    220     {
    221 #if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
    222         /* if inactivity delay timer is not running, start system tick */
    223         if(gki_cb.com.OSTicksTilStop == 0)
    224         {
    225 #endif
    226             if(gki_cb.com.p_tick_cb)
    227             {
    228                 /* start system tick */
    229                 gki_cb.com.system_tick_running = TRUE;
    230                 (gki_cb.com.p_tick_cb) (TRUE);
    231             }
    232 #if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
    233         }
    234         else
    235         {
    236             /* clear inactivity delay timer */
    237             gki_cb.com.OSTicksTilStop = 0;
    238         }
    239 #endif
    240     }
    241     /* Add the time since the last task timer update.
    242     ** Note that this works when no timers are active since
    243     ** both OSNumOrigTicks and OSTicksTilExp are 0.
    244     */
    245     if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) > ticks)
    246     {
    247         ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
    248     }
    249     else
    250         ticks = GKI_MAX_INT32;
    251 
    252     switch (tnum)
    253     {
    254 #if (GKI_NUM_TIMERS > 0)
    255         case TIMER_0:
    256             gki_cb.com.OSTaskTmr0R[task_id] = reload;
    257             gki_cb.com.OSTaskTmr0 [task_id] = ticks;
    258             break;
    259 #endif
    260 
    261 #if (GKI_NUM_TIMERS > 1)
    262         case TIMER_1:
    263             gki_cb.com.OSTaskTmr1R[task_id] = reload;
    264             gki_cb.com.OSTaskTmr1 [task_id] = ticks;
    265             break;
    266 #endif
    267 
    268 #if (GKI_NUM_TIMERS > 2)
    269         case TIMER_2:
    270             gki_cb.com.OSTaskTmr2R[task_id] = reload;
    271             gki_cb.com.OSTaskTmr2 [task_id] = ticks;
    272             break;
    273 #endif
    274 
    275 #if (GKI_NUM_TIMERS > 3)
    276         case TIMER_3:
    277             gki_cb.com.OSTaskTmr3R[task_id] = reload;
    278             gki_cb.com.OSTaskTmr3 [task_id] = ticks;
    279             break;
    280 #endif
    281         default:
    282             bad_timer = TRUE;       /* Timer number is bad, so do not use */
    283     }
    284 
    285     /* Update the expiration timeout if a legitimate timer */
    286     if (!bad_timer)
    287     {
    288         /* Only update the timeout value if it is less than any other newly started timers */
    289         gki_adjust_timer_count (orig_ticks);
    290     }
    291 
    292     GKI_enable();
    293 
    294 }
    295 
    296 /*******************************************************************************
    297 **
    298 ** Function         GKI_stop_timer
    299 **
    300 ** Description      An application can call this function to stop one of
    301 **                  it's four general purpose timers. There is no harm in
    302 **                  stopping a timer that is already stopped.
    303 **
    304 ** Parameters       tnum            - (input) timer number to be started (TIMER_0,
    305 **                                              TIMER_1, TIMER_2, or TIMER_3)
    306 ** Returns          void
    307 **
    308 *******************************************************************************/
    309 void GKI_stop_timer (UINT8 tnum)
    310 {
    311     UINT8  task_id = GKI_get_taskid();
    312 
    313     switch (tnum)
    314     {
    315 #if (GKI_NUM_TIMERS > 0)
    316         case TIMER_0:
    317             gki_cb.com.OSTaskTmr0R[task_id] = 0;
    318             gki_cb.com.OSTaskTmr0 [task_id] = 0;
    319             break;
    320 #endif
    321 
    322 #if (GKI_NUM_TIMERS > 1)
    323         case TIMER_1:
    324             gki_cb.com.OSTaskTmr1R[task_id] = 0;
    325             gki_cb.com.OSTaskTmr1 [task_id] = 0;
    326             break;
    327 #endif
    328 
    329 #if (GKI_NUM_TIMERS > 2)
    330         case TIMER_2:
    331             gki_cb.com.OSTaskTmr2R[task_id] = 0;
    332             gki_cb.com.OSTaskTmr2 [task_id] = 0;
    333             break;
    334 #endif
    335 
    336 #if (GKI_NUM_TIMERS > 3)
    337         case TIMER_3:
    338             gki_cb.com.OSTaskTmr3R[task_id] = 0;
    339             gki_cb.com.OSTaskTmr3 [task_id] = 0;
    340             break;
    341 #endif
    342     }
    343 
    344     GKI_disable();
    345 
    346     if (gki_timers_is_timer_running() == FALSE)
    347     {
    348         if (gki_cb.com.p_tick_cb)
    349         {
    350 #if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
    351             /* if inactivity delay timer is not running */
    352             if ((gki_cb.com.system_tick_running)&&(gki_cb.com.OSTicksTilStop == 0))
    353             {
    354                 /* set inactivity delay timer */
    355                 /* when timer expires, system tick will be stopped */
    356                 gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK;
    357             }
    358 #else
    359             gki_cb.com.system_tick_running = FALSE;
    360             gki_cb.com.p_tick_cb(FALSE); /* stop system tick */
    361 #endif
    362         }
    363     }
    364 
    365     GKI_enable();
    366 
    367 
    368 }
    369 
    370 
    371 /*******************************************************************************
    372 **
    373 ** Function         GKI_timer_update
    374 **
    375 ** Description      This function is called by an OS to drive the GKI's timers.
    376 **                  It is typically called at every system tick to
    377 **                  update the timers for all tasks, and check for timeouts.
    378 **
    379 **                  Note: It has been designed to also allow for variable tick updates
    380 **                      so that systems with strict power savings requirements can
    381 **                      have the update occur at variable intervals.
    382 **
    383 ** Parameters:      ticks_since_last_update - (input) This is the number of TICKS that have
    384 **                          occurred since the last time GKI_timer_update was called.
    385 **
    386 ** Returns          void
    387 **
    388 *******************************************************************************/
    389 void GKI_timer_update (INT32 ticks_since_last_update)
    390 {
    391     UINT8   task_id;
    392     long    next_expiration;        /* Holds the next soonest expiration time after this update */
    393 
    394     /* Increment the number of ticks used for time stamps */
    395     gki_cb.com.OSTicks += ticks_since_last_update;
    396 
    397     /* If any timers are running in any tasks, decrement the remaining time til
    398      * the timer updates need to take place (next expiration occurs)
    399      */
    400     gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
    401 
    402     /* Don't allow timer interrupt nesting */
    403     if (gki_cb.com.timer_nesting)
    404         return;
    405 
    406     gki_cb.com.timer_nesting = 1;
    407 
    408 #if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
    409     /* if inactivity delay timer is set and expired */
    410     if (gki_cb.com.OSTicksTilStop)
    411     {
    412         if( gki_cb.com.OSTicksTilStop <= (UINT32)ticks_since_last_update )
    413         {
    414             if(gki_cb.com.p_tick_cb)
    415             {
    416                 gki_cb.com.system_tick_running = FALSE;
    417                 (gki_cb.com.p_tick_cb) (FALSE); /* stop system tick */
    418             }
    419             gki_cb.com.OSTicksTilStop = 0;      /* clear inactivity delay timer */
    420             gki_cb.com.timer_nesting = 0;
    421             return;
    422         }
    423         else
    424             gki_cb.com.OSTicksTilStop -= ticks_since_last_update;
    425     }
    426 #endif
    427 
    428     /* No need to update the ticks if no timeout has occurred */
    429     if (gki_cb.com.OSTicksTilExp > 0)
    430     {
    431         gki_cb.com.timer_nesting = 0;
    432         return;
    433     }
    434 
    435     next_expiration = GKI_NO_NEW_TMRS_STARTED;
    436 
    437     /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase gki_cb.com.OSNumOrigTicks
    438        to account for the difference so timer updates below are decremented by the full number
    439        of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function so changing this
    440        value only affects the timer updates below
    441      */
    442     gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
    443 
    444 #if GKI_TIMER_LIST_NOPREEMPT == TRUE
    445     /* Protect this section because if a GKI_timer_stop happens between:
    446      *   - gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
    447      *   - gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
    448      * then the timer may appear stopped while it is about to be reloaded.
    449      * Note: Not needed if this function cannot be preempted (typical).
    450      */
    451     GKI_disable();
    452 #endif
    453 
    454     /* Check for OS Task Timers */
    455     for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
    456     {
    457         if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
    458         {
    459             gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
    460             if (gki_cb.com.OSWaitTmr[task_id] <= 0)
    461             {
    462                 /* Timer Expired */
    463                 gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
    464             }
    465         }
    466 
    467 #if (GKI_NUM_TIMERS > 0)
    468          /* If any timer is running, decrement */
    469         if (gki_cb.com.OSTaskTmr0[task_id] > 0)
    470         {
    471             gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
    472 
    473             if (gki_cb.com.OSTaskTmr0[task_id] <= 0)
    474             {
    475                 /* Reload timer and set Timer 0 Expired event mask */
    476                 gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
    477 
    478 #if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
    479                 GKI_isend_event (task_id, TIMER_0_EVT_MASK);
    480 #else
    481                 GKI_send_event (task_id, TIMER_0_EVT_MASK);
    482 #endif
    483             }
    484         }
    485 
    486         /* Check to see if this timer is the next one to expire */
    487         if (gki_cb.com.OSTaskTmr0[task_id] > 0 && gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
    488             next_expiration = gki_cb.com.OSTaskTmr0[task_id];
    489 #endif
    490 
    491 #if (GKI_NUM_TIMERS > 1)
    492          /* If any timer is running, decrement */
    493         if (gki_cb.com.OSTaskTmr1[task_id] > 0)
    494         {
    495             gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
    496 
    497             if (gki_cb.com.OSTaskTmr1[task_id] <= 0)
    498             {
    499                 /* Reload timer and set Timer 1 Expired event mask */
    500                 gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
    501 
    502 #if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
    503                 GKI_isend_event (task_id, TIMER_1_EVT_MASK);
    504 #else
    505                 GKI_send_event (task_id, TIMER_1_EVT_MASK);
    506 #endif
    507             }
    508         }
    509 
    510         /* Check to see if this timer is the next one to expire */
    511         if (gki_cb.com.OSTaskTmr1[task_id] > 0 && gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
    512             next_expiration = gki_cb.com.OSTaskTmr1[task_id];
    513 #endif
    514 
    515 #if (GKI_NUM_TIMERS > 2)
    516          /* If any timer is running, decrement */
    517         if (gki_cb.com.OSTaskTmr2[task_id] > 0)
    518         {
    519             gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
    520 
    521             if (gki_cb.com.OSTaskTmr2[task_id] <= 0)
    522             {
    523                 /* Reload timer and set Timer 2 Expired event mask */
    524                 gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
    525 
    526 #if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
    527                 GKI_isend_event (task_id, TIMER_2_EVT_MASK);
    528 #else
    529                 GKI_send_event (task_id, TIMER_2_EVT_MASK);
    530 #endif
    531             }
    532         }
    533 
    534         /* Check to see if this timer is the next one to expire */
    535         if (gki_cb.com.OSTaskTmr2[task_id] > 0 && gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
    536             next_expiration = gki_cb.com.OSTaskTmr2[task_id];
    537 #endif
    538 
    539 #if (GKI_NUM_TIMERS > 3)
    540          /* If any timer is running, decrement */
    541         if (gki_cb.com.OSTaskTmr3[task_id] > 0)
    542         {
    543             gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
    544 
    545             if (gki_cb.com.OSTaskTmr3[task_id] <= 0)
    546             {
    547                 /* Reload timer and set Timer 3 Expired event mask */
    548                 gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
    549 
    550 #if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
    551                 GKI_isend_event (task_id, TIMER_3_EVT_MASK);
    552 #else
    553                 GKI_send_event (task_id, TIMER_3_EVT_MASK);
    554 #endif
    555             }
    556         }
    557 
    558         /* Check to see if this timer is the next one to expire */
    559         if (gki_cb.com.OSTaskTmr3[task_id] > 0 && gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
    560             next_expiration = gki_cb.com.OSTaskTmr3[task_id];
    561 #endif
    562 
    563     }
    564 
    565 #if GKI_TIMER_LIST_NOPREEMPT == TRUE
    566     /* End the critical section */
    567     GKI_enable();
    568 #endif
    569 
    570     /* Set the next timer experation value if there is one to start */
    571     if (next_expiration < GKI_NO_NEW_TMRS_STARTED)
    572     {
    573         gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
    574     }
    575     else
    576     {
    577         gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
    578     }
    579 
    580     gki_cb.com.timer_nesting = 0;
    581 
    582     return;
    583 }
    584 
    585 
    586 /*******************************************************************************
    587 **
    588 ** Function         GKI_timer_queue_empty
    589 **
    590 ** Description      This function is called by applications to see whether the timer
    591 **                  queue is empty
    592 **
    593 ** Parameters
    594 **
    595 ** Returns          BOOLEAN
    596 **
    597 *******************************************************************************/
    598 BOOLEAN GKI_timer_queue_empty (void)
    599 {
    600     UINT8 tt;
    601 
    602     for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
    603     {
    604         if (gki_cb.com.timer_queues[tt])
    605             return FALSE;
    606     }
    607 
    608     return TRUE;
    609 }
    610 
    611 /*******************************************************************************
    612 **
    613 ** Function         GKI_timer_queue_register_callback
    614 **
    615 ** Description      This function is called by applications to register system tick
    616 **                  start/stop callback for time queues
    617 **
    618 **
    619 ** Parameters       p_callback - (input) pointer to the system tick callback
    620 **
    621 ** Returns          BOOLEAN
    622 **
    623 *******************************************************************************/
    624 void GKI_timer_queue_register_callback (SYSTEM_TICK_CBACK *p_callback)
    625 {
    626     gki_cb.com.p_tick_cb = p_callback;
    627 
    628     return;
    629 }
    630 
    631 /*******************************************************************************
    632 **
    633 ** Function         GKI_init_timer_list
    634 **
    635 ** Description      This function is called by applications when they
    636 **                  want to initialize a timer list.
    637 **
    638 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
    639 **
    640 ** Returns          void
    641 **
    642 *******************************************************************************/
    643 void GKI_init_timer_list (TIMER_LIST_Q *p_timer_listq)
    644 {
    645     p_timer_listq->p_first    = NULL;
    646     p_timer_listq->p_last     = NULL;
    647     p_timer_listq->last_ticks = 0;
    648 
    649     return;
    650 }
    651 
    652 /*******************************************************************************
    653 **
    654 ** Function         GKI_init_timer_list_entry
    655 **
    656 ** Description      This function is called by the applications when they
    657 **                  want to initialize a timer list entry. This must be
    658 **                  done prior to first use of the entry.
    659 **
    660 ** Parameters       p_tle           - (input) pointer to a timer list queue entry
    661 **
    662 ** Returns          void
    663 **
    664 *******************************************************************************/
    665 void GKI_init_timer_list_entry (TIMER_LIST_ENT  *p_tle)
    666 {
    667     p_tle->p_next  = NULL;
    668     p_tle->p_prev  = NULL;
    669     p_tle->ticks   = GKI_UNUSED_LIST_ENTRY;
    670     p_tle->in_use  = FALSE;
    671 }
    672 
    673 
    674 /*******************************************************************************
    675 **
    676 ** Function         GKI_update_timer_list
    677 **
    678 ** Description      This function is called by the applications when they
    679 **                  want to update a timer list. This should be at every
    680 **                  timer list unit tick, e.g. once per sec, once per minute etc.
    681 **
    682 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
    683 **                  num_units_since_last_update - (input) number of units since the last update
    684 **                                  (allows for variable unit update)
    685 **
    686 **      NOTE: The following timer list update routines should not be used for exact time
    687 **            critical purposes.  The timer tasks should be used when exact timing is needed.
    688 **
    689 ** Returns          the number of timers that have expired
    690 **
    691 *******************************************************************************/
    692 UINT16 GKI_update_timer_list (TIMER_LIST_Q *p_timer_listq, INT32 num_units_since_last_update)
    693 {
    694     TIMER_LIST_ENT  *p_tle;
    695     UINT16           num_time_out = 0;
    696     INT32            rem_ticks;
    697     INT32            temp_ticks;
    698 
    699     p_tle = p_timer_listq->p_first;
    700 
    701     /* First, get the guys who have previously timed out */
    702     /* Note that the tick value of the timers should always be '0' */
    703     while ((p_tle) && (p_tle->ticks <= 0))
    704     {
    705         num_time_out++;
    706         p_tle = p_tle->p_next;
    707     }
    708 
    709     /* Timer entriy tick values are relative to the preceeding entry */
    710     rem_ticks = num_units_since_last_update;
    711 
    712     /* Now, adjust remaining timer entries */
    713     while ((p_tle != NULL) && (rem_ticks > 0))
    714     {
    715         temp_ticks = p_tle->ticks;
    716         p_tle->ticks -= rem_ticks;
    717 
    718         /* See if this timer has just timed out */
    719         if (p_tle->ticks <= 0)
    720         {
    721             /* We set the number of ticks to '0' so that the legacy code
    722              * that assumes a '0' or nonzero value will still work as coded. */
    723             p_tle->ticks = 0;
    724 
    725             num_time_out++;
    726         }
    727 
    728         rem_ticks -= temp_ticks;  /* Decrement the remaining ticks to process */
    729         p_tle = p_tle->p_next;
    730     }
    731 
    732     if (p_timer_listq->last_ticks > 0)
    733     {
    734         p_timer_listq->last_ticks -= num_units_since_last_update;
    735 
    736         /* If the last timer has expired set last_ticks to 0 so that other list update
    737         * functions will calculate correctly
    738         */
    739         if (p_timer_listq->last_ticks < 0)
    740             p_timer_listq->last_ticks = 0;
    741     }
    742 
    743     return (num_time_out);
    744 }
    745 
    746 /*******************************************************************************
    747 **
    748 ** Function         GKI_get_remaining_ticks
    749 **
    750 ** Description      This function is called by an application to get remaining
    751 **                  ticks to expire
    752 **
    753 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
    754 **                  p_target_tle    - (input) pointer to a timer list queue entry
    755 **
    756 ** Returns          0 if timer is not used or timer is not in the list
    757 **                  remaining ticks if success
    758 **
    759 *******************************************************************************/
    760 UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_target_tle)
    761 {
    762     TIMER_LIST_ENT  *p_tle;
    763     UINT32           rem_ticks = 0;
    764 
    765     if (p_target_tle->in_use)
    766     {
    767         p_tle = p_timer_listq->p_first;
    768 
    769         /* adding up all of ticks in previous entries */
    770         while ((p_tle)&&(p_tle != p_target_tle))
    771         {
    772             rem_ticks += p_tle->ticks;
    773             p_tle = p_tle->p_next;
    774         }
    775 
    776         /* if found target entry */
    777         if (p_tle == p_target_tle)
    778         {
    779             rem_ticks += p_tle->ticks;
    780         }
    781         else
    782         {
    783             BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: No timer entry in the list");
    784             return(0);
    785         }
    786     }
    787     else
    788     {
    789         BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: timer entry is not active");
    790     }
    791 
    792     return (rem_ticks);
    793 }
    794 
    795 /*******************************************************************************
    796 **
    797 ** Function         GKI_add_to_timer_list
    798 **
    799 ** Description      This function is called by an application to add a timer
    800 **                  entry to a timer list.
    801 **
    802 **                  Note: A timer value of '0' will effectively insert an already
    803 **                      expired event.  Negative tick values will be ignored.
    804 **
    805 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
    806 **                  p_tle           - (input) pointer to a timer list queue entry
    807 **
    808 ** Returns          void
    809 **
    810 *******************************************************************************/
    811 void GKI_add_to_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
    812 {
    813     UINT32           nr_ticks_total;
    814     UINT8 tt;
    815     TIMER_LIST_ENT  *p_temp;
    816 
    817     /* Only process valid tick values */
    818     if (p_tle->ticks >= 0)
    819     {
    820         /* If this entry is the last in the list */
    821         if (p_tle->ticks >= p_timer_listq->last_ticks)
    822         {
    823             /* If this entry is the only entry in the list */
    824             if (p_timer_listq->p_first == NULL)
    825                 p_timer_listq->p_first = p_tle;
    826             else
    827             {
    828                 /* Insert the entry onto the end of the list */
    829                 if (p_timer_listq->p_last != NULL)
    830                     p_timer_listq->p_last->p_next = p_tle;
    831 
    832                 p_tle->p_prev = p_timer_listq->p_last;
    833             }
    834 
    835             p_tle->p_next = NULL;
    836             p_timer_listq->p_last = p_tle;
    837             nr_ticks_total = p_tle->ticks;
    838             p_tle->ticks -= p_timer_listq->last_ticks;
    839 
    840             p_timer_listq->last_ticks = nr_ticks_total;
    841         }
    842         else    /* This entry needs to be inserted before the last entry */
    843         {
    844             /* Find the entry that the new one needs to be inserted in front of */
    845             p_temp = p_timer_listq->p_first;
    846             while (p_tle->ticks > p_temp->ticks)
    847             {
    848                 /* Update the tick value if looking at an unexpired entry */
    849                 if (p_temp->ticks > 0)
    850                     p_tle->ticks -= p_temp->ticks;
    851 
    852                 p_temp = p_temp->p_next;
    853             }
    854 
    855             /* The new entry is the first in the list */
    856             if (p_temp == p_timer_listq->p_first)
    857             {
    858                 p_tle->p_next = p_timer_listq->p_first;
    859                 p_timer_listq->p_first->p_prev = p_tle;
    860                 p_timer_listq->p_first = p_tle;
    861             }
    862             else
    863             {
    864                 p_temp->p_prev->p_next = p_tle;
    865                 p_tle->p_prev = p_temp->p_prev;
    866                 p_temp->p_prev = p_tle;
    867                 p_tle->p_next = p_temp;
    868             }
    869             p_temp->ticks -= p_tle->ticks;
    870         }
    871 
    872         p_tle->in_use = TRUE;
    873 
    874         /* if we already add this timer queue to the array */
    875         for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
    876         {
    877              if (gki_cb.com.timer_queues[tt] == p_timer_listq)
    878                  return;
    879         }
    880         /* add this timer queue to the array */
    881         for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
    882         {
    883              if (gki_cb.com.timer_queues[tt] == NULL)
    884                  break;
    885         }
    886         if (tt < GKI_MAX_TIMER_QUEUES)
    887         {
    888             gki_cb.com.timer_queues[tt] = p_timer_listq;
    889         }
    890     }
    891 
    892     return;
    893 }
    894 
    895 
    896 /*******************************************************************************
    897 **
    898 ** Function         GKI_remove_from_timer_list
    899 **
    900 ** Description      This function is called by an application to remove a timer
    901 **                  entry from a timer list.
    902 **
    903 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
    904 **                  p_tle           - (input) pointer to a timer list queue entry
    905 **
    906 ** Returns          void
    907 **
    908 *******************************************************************************/
    909 void GKI_remove_from_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
    910 {
    911     UINT8 tt;
    912 
    913     /* Verify that the entry is valid */
    914     if (p_tle == NULL || p_tle->in_use == FALSE || p_timer_listq->p_first == NULL)
    915     {
    916         return;
    917     }
    918 
    919     /* Add the ticks remaining in this timer (if any) to the next guy in the list.
    920     ** Note: Expired timers have a tick value of '0'.
    921     */
    922     if (p_tle->p_next != NULL)
    923     {
    924         p_tle->p_next->ticks += p_tle->ticks;
    925     }
    926     else
    927     {
    928         p_timer_listq->last_ticks -= p_tle->ticks;
    929     }
    930 
    931     /* Unlink timer from the list.
    932     */
    933     if (p_timer_listq->p_first == p_tle)
    934     {
    935         p_timer_listq->p_first = p_tle->p_next;
    936 
    937         if (p_timer_listq->p_first != NULL)
    938             p_timer_listq->p_first->p_prev = NULL;
    939 
    940         if (p_timer_listq->p_last == p_tle)
    941             p_timer_listq->p_last = NULL;
    942     }
    943     else
    944     {
    945         if (p_timer_listq->p_last == p_tle)
    946         {
    947             p_timer_listq->p_last = p_tle->p_prev;
    948 
    949             if (p_timer_listq->p_last != NULL)
    950                 p_timer_listq->p_last->p_next = NULL;
    951         }
    952         else
    953         {
    954             if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle)
    955                 p_tle->p_next->p_prev = p_tle->p_prev;
    956             else
    957             {
    958                 /* Error case - chain messed up ?? */
    959                 return;
    960             }
    961 
    962             if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle)
    963                 p_tle->p_prev->p_next = p_tle->p_next;
    964             else
    965             {
    966                 /* Error case - chain messed up ?? */
    967                 return;
    968             }
    969         }
    970     }
    971 
    972     p_tle->p_next = p_tle->p_prev = NULL;
    973     p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
    974     p_tle->in_use = FALSE;
    975 
    976     /* if timer queue is empty */
    977     if (p_timer_listq->p_first == NULL && p_timer_listq->p_last == NULL)
    978     {
    979         for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
    980         {
    981             if (gki_cb.com.timer_queues[tt] == p_timer_listq)
    982             {
    983                 gki_cb.com.timer_queues[tt] = NULL;
    984                 break;
    985             }
    986         }
    987     }
    988 
    989     return;
    990 }
    991 
    992 
    993 /*******************************************************************************
    994 **
    995 ** Function         gki_adjust_timer_count
    996 **
    997 ** Description      This function is called whenever a new timer or GKI_wait occurs
    998 **                  to adjust (if necessary) the current time til the first expiration.
    999 **                  This only needs to make an adjustment if the new timer (in ticks) is
   1000 **                  less than the number of ticks remaining on the current timer.
   1001 **
   1002 ** Parameters:      ticks - (input) number of system ticks of the new timer entry
   1003 **
   1004 **                  NOTE:  This routine MUST be called while interrupts are disabled to
   1005 **                          avoid updates while adjusting the timer variables.
   1006 **
   1007 ** Returns          void
   1008 **
   1009 *******************************************************************************/
   1010 void gki_adjust_timer_count (INT32 ticks)
   1011 {
   1012     if (ticks > 0)
   1013     {
   1014         /* See if the new timer expires before the current first expiration */
   1015         if (gki_cb.com.OSNumOrigTicks == 0 || (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0))
   1016         {
   1017             gki_cb.com.OSNumOrigTicks = (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
   1018             gki_cb.com.OSTicksTilExp = ticks;
   1019         }
   1020     }
   1021 
   1022     return;
   1023 }
   1024