Home | History | Annotate | Download | only in Sta_Management
      1 /*
      2  * scr.c
      3  *
      4  * Copyright(c) 1998 - 2009 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 /** \file  scr.c
     35  *  \brief This file include the SCR module implementation
     36  *
     37  *  \see   scr.h, scrApi.h
     38  */
     39 
     40 #define __FILE_ID__  FILE_ID_82
     41 #include "tidef.h"
     42 #include "report.h"
     43 #include "osApi.h"
     44 #include "scr.h"
     45 #include "DrvMainModules.h"
     46 
     47 
     48 /*
     49  ***********************************************************************
     50  *  External data definitions.
     51  ***********************************************************************
     52  */
     53 
     54 /**
     55  * \brief This array holds configuration values for abort others field for different clients.\n
     56  */
     57 static EScrClientId abortOthers[ SCR_RESOURCE_NUM_OF_RESOURCES ][ SCR_CID_NUM_OF_CLIENTS ] =
     58 /* APP_SCAN           DRV_FG             CONT_SCAN          XCC_MSR            BASIC_MSR          CONNECT                IMMED_SCN              SWITCH_CHNL*/
     59 {/* Serving channel resource */
     60  { SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_BASIC_MEASURE, SCR_CID_BASIC_MEASURE, SCR_CID_BASIC_MEASURE },
     61  /* periodic scan resource */
     62  { SCR_CID_NO_CLIENT, SCR_CID_APP_SCAN,  SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_DRIVER_FG_SCAN,SCR_CID_NO_CLIENT,     SCR_CID_NO_CLIENT }
     63 };
     64 
     65 /**
     66  * \brief This array holds configuration values for the client status field for different clients and groups. \n
     67  */
     68 static TI_BOOL clientStatus[ SCR_RESOURCE_NUM_OF_RESOURCES ][ SCR_MID_NUM_OF_MODES ][ SCR_GID_NUM_OF_GROUPS ][ SCR_CID_NUM_OF_CLIENTS ] =
     69             {
     70                 {/* serving channel resource */
     71                     {/* This is the table for Normal mode  */
     72                         /* client status for idle group */
     73                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
     74                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
     75                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
     76                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
     77                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
     78                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
     79                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
     80                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
     81                        /* client status for DRV scan group */
     82                         { TI_TRUE,     /**< client status for SCR_CID_APP_SCAN */
     83                           TI_FALSE,     /**< client status for SCR_CID_DRIVER_FG_SCAN */
     84                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
     85                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
     86                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
     87                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
     88                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
     89                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
     90                        /* client status for APP scan group */
     91                         { TI_TRUE,     /**< client status for SCR_CID_APP_SCAN */
     92                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
     93                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
     94                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
     95                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
     96                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
     97                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
     98                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
     99                        /* client status for connect group */
    100                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    101                           TI_TRUE,     /**< client status for SCR_CID_DRIVER_FG_SCAN */
    102                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    103                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    104                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    105                           TI_TRUE,     /**< client status for SCR_CID_CONNECT */
    106                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    107                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    108                        /* client status for connected group */
    109                         { TI_TRUE,     /**< client status for SCR_CID_APP_SCAN */
    110                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    111                           TI_TRUE,     /**< client status for SCR_CID_CONT_SCAN */
    112                           TI_TRUE,     /**< client status for SCR_CID_XCC_MEASURE */
    113                           TI_TRUE,     /**< client status for SCR_CID_BASIC_MEASURE */
    114                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    115                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    116                           TI_TRUE,     /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    117                        /* client status for roaming group */
    118                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    119                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    120                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    121                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    122                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    123                           TI_TRUE,     /**< client status for SCR_CID_CONNECT */
    124                           TI_TRUE,     /**< client status for SCR_CID_IMMED_SCAN */
    125                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ }
    126                     },
    127 
    128                     /* This is the table for the Soft gemini mode   */
    129 
    130                     { /* client status for idle group */
    131                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    132                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    133                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    134                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    135                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    136                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    137                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    138                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    139                        /* client status for DRV scan group */
    140                         { TI_TRUE,     /**< client status for SCR_CID_APP_SCAN */
    141                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    142                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    143                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    144                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    145                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    146                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    147                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    148                        /* client status for APP scan group */
    149                         { TI_TRUE,     /**< client status for SCR_CID_APP_SCAN */
    150                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    151                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    152                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    153                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    154                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    155                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    156                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    157                        /* client status for connect group */
    158                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    159                           TI_TRUE,     /**< client status for SCR_CID_DRIVER_FG_SCAN */
    160                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    161                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    162                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    163                           TI_TRUE,     /**< client status for SCR_CID_CONNECT */
    164                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    165                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    166                        /* client status for connected group */
    167                         { TI_TRUE,     /**< client status for SCR_CID_APP_SCAN */
    168                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    169                           TI_TRUE,     /**< client status for SCR_CID_CONT_SCAN */
    170                           TI_TRUE,     /**< client status for SCR_CID_XCC_MEASURE */
    171                           TI_TRUE,     /**< client status for SCR_CID_BASIC_MEASURE */
    172                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    173                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    174                           TI_TRUE,     /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    175                        /* client status for roaming group */
    176                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    177                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    178                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    179                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    180                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    181                           TI_TRUE,     /**< client status for SCR_CID_CONNECT */
    182                           TI_TRUE,     /**< client status for SCR_CID_IMMED_SCAN */
    183                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ }
    184                     }
    185                 },
    186                 {/* periodic-scan resource */
    187                     {/* This is the table for Normal mode */
    188                         /* client status for idle group */
    189                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    190                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    191                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    192                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    193                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    194                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    195                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    196                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    197                        /* client status for DRV scan gorup */
    198                         { TI_FALSE,     /**< client status for SCR_CID_APP_SCAN */
    199                           TI_TRUE,     /**< client status for SCR_CID_DRIVER_FG_SCAN */
    200                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    201                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    202                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    203                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    204                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    205                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    206                        /* client status for APP scan gorup */
    207                         { TI_TRUE,     /**< client status for SCR_CID_APP_SCAN */
    208                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    209                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    210                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    211                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    212                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    213                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    214                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    215                        /* client status for connect group */
    216                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    217                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    218                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    219                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    220                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    221                           TI_TRUE,     /**< client status for SCR_CID_CONNECT */
    222                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    223                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    224                        /* client status for connected group */
    225                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    226                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    227                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    228                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    229                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    230                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    231                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    232                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    233                        /* client status for roaming group */
    234                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    235                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    236                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    237                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    238                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    239                           TI_TRUE,     /**< client status for SCR_CID_CONNECT */
    240                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    241                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ }
    242                     },
    243 
    244                     /* This is the table for the Soft gemini mode   */
    245 
    246                     { /* client status for idle group */
    247                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    248                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    249                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    250                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    251                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    252                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    253                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    254                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    255                        /* client status for DRV scan gorup */
    256                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    257                           TI_TRUE,     /**< client status for SCR_CID_DRIVER_FG_SCAN */
    258                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    259                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    260                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    261                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    262                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    263                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    264                        /* client status for APP scan gorup */
    265                         { TI_TRUE,     /**< client status for SCR_CID_APP_SCAN */
    266                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    267                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    268                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    269                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    270                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    271                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    272                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    273                        /* client status for connect group */
    274                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    275                           TI_FALSE,     /**< client status for SCR_CID_DRIVER_FG_SCAN */
    276                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    277                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    278                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    279                           TI_TRUE,     /**< client status for SCR_CID_CONNECT */
    280                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    281                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    282                        /* client status for connected group */
    283                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    284                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    285                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    286                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    287                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    288                           TI_FALSE,    /**< client status for SCR_CID_CONNECT */
    289                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    290                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ },
    291                        /* client status for roaming group */
    292                         { TI_FALSE,    /**< client status for SCR_CID_APP_SCAN */
    293                           TI_FALSE,    /**< client status for SCR_CID_DRIVER_FG_SCAN */
    294                           TI_FALSE,    /**< client status for SCR_CID_CONT_SCAN */
    295                           TI_FALSE,    /**< client status for SCR_CID_XCC_MEASURE */
    296                           TI_FALSE,    /**< client status for SCR_CID_BASIC_MEASURE */
    297                           TI_TRUE,     /**< client status for SCR_CID_CONNECT */
    298                           TI_FALSE,    /**< client status for SCR_CID_IMMED_SCAN */
    299                           TI_FALSE,    /**< client status for SCR_CID_SWITCH_CHANNEL */ }
    300                     }
    301                 }
    302             };
    303 
    304 
    305 /**
    306  * \\n
    307  * \date 01-Dec-2004\n
    308  * \brief Creates the SCR object
    309  *
    310  * Function Scope \e Public.\n
    311  * \param hOS - handle to the OS object.\n
    312  * \return a handle to the SCR object.\n
    313  */
    314 TI_HANDLE scr_create( TI_HANDLE hOS )
    315 {
    316     /* allocate the SCR object */
    317     TScr    *pScr = os_memoryAlloc( hOS, sizeof(TScr));
    318 
    319     if ( NULL == pScr )
    320     {
    321         WLAN_OS_REPORT( ("ERROR: Failed to create SCR module"));
    322         return NULL;
    323     }
    324 
    325     /* store the OS handle */
    326     pScr->hOS = hOS;
    327 
    328     return pScr;
    329 }
    330 
    331 /**
    332  * \\n
    333  * \date 01-Dec-2004\n
    334  * \brief Finalizes the SCR object (freeing memory)
    335  *
    336  * Function Scope \e Public.\n
    337  * \param hScr - handle to the SCR object.\n
    338  */
    339 void scr_release( TI_HANDLE hScr )
    340 {
    341     TScr    *pScr = (TScr*)hScr;
    342 
    343     os_memoryFree( pScr->hOS, hScr, sizeof(TScr));
    344 }
    345 
    346 /**
    347  * \\n
    348  * \date 01-Dec-2004\n
    349  * \brief Initializes the SCR object
    350  *
    351  * \param  pStadHandles  - The driver modules handles
    352  * \return void
    353  */
    354 void scr_init (TStadHandlesList *pStadHandles)
    355 {
    356     TScr        *pScr = (TScr*)(pStadHandles->hSCR);
    357     TI_UINT32   i, j;
    358 
    359     /* store the report object */
    360     pScr->hReport = pStadHandles->hReport;
    361 
    362     /* mark current group as idle */
    363     pScr->currentGroup = SCR_GID_IDLE;
    364 
    365     /* mark current mode as normal */
    366     pScr->currentMode = SCR_MID_NORMAL;
    367 
    368     /* signal not within request process */
    369     pScr->statusNotficationPending = TI_FALSE;
    370 
    371     /* mark that no client is currently running */
    372     for (i = 0; i < SCR_RESOURCE_NUM_OF_RESOURCES; i++)
    373     {
    374         pScr->runningClient[ i ] = SCR_CID_NO_CLIENT;
    375     }
    376 
    377     /* initialize client array */
    378     for (i = 0; i < SCR_CID_NUM_OF_CLIENTS; i++ )
    379     {
    380         for (j = 0; j < SCR_RESOURCE_NUM_OF_RESOURCES; j++)
    381         {
    382             pScr->clientArray[ i ].state[ j ] = SCR_CS_IDLE;
    383             pScr->clientArray[ i ].currentPendingReason[ j ] = SCR_PR_NONE;
    384         }
    385         pScr->clientArray[ i ].clientRequestCB = NULL;
    386         pScr->clientArray[ i ].ClientRequestCBObj = NULL;
    387     }
    388 
    389     TRACE0(pScr->hReport, REPORT_SEVERITY_INIT , ".....SCR configured successfully\n");
    390 }
    391 
    392 /**
    393  * \\n
    394  * \date 01-Dec-2004\n
    395  * \brief Registers the callback function to be used per client.
    396  *
    397  * Function Scope \e Public.\n
    398  * \param hScr - handle to the SCR object.\n
    399  * \param client - the client ID.\n
    400  * \param callbackFunc - the address of the callback function to use.\n
    401  * \param callbackObj - the handle of the object to pass to the callback function (the client object).\n
    402  */
    403 void scr_registerClientCB( TI_HANDLE hScr,
    404                            EScrClientId client,
    405                            TScrCB callbackFunc,
    406                            TI_HANDLE callbackObj )
    407 {
    408     TScr    *pScr = (TScr*)hScr;
    409 
    410 #ifdef TI_DBG
    411     if (client >= SCR_CID_NUM_OF_CLIENTS)
    412     {
    413         TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to register callback for invalid client %d\n", client);
    414         return;
    415     }
    416 #endif
    417     pScr->clientArray[ client ].clientRequestCB = callbackFunc;
    418     pScr->clientArray[ client ].ClientRequestCBObj = callbackObj;
    419 }
    420 
    421 /**
    422  * \\n
    423  * \date 01-Dec-2004\n
    424  * \brief Notifies the running process upon a firmware reset.
    425  *
    426  * Function Scope \e Public.\n
    427  * \param hScr - handle to the SCR object.\n
    428  */
    429 void scr_notifyFWReset( TI_HANDLE hScr )
    430 {
    431     TScr        *pScr = (TScr*)hScr;
    432     TI_UINT32   uResourceIndex;
    433 
    434     /* check both resources */
    435     for (uResourceIndex = 0; uResourceIndex < SCR_RESOURCE_NUM_OF_RESOURCES; uResourceIndex++)
    436     {
    437         /* if a client is currently running, notify it of the recovery event */
    438         if ( SCR_CID_NO_CLIENT != pScr->runningClient[ uResourceIndex ] )
    439         {
    440             TRACE1( pScr->hReport, REPORT_SEVERITY_INFORMATION, "FW reset occured. Client %d Notified.\n", pScr->runningClient[ uResourceIndex ]);
    441             if ( NULL != pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].clientRequestCB )
    442             {
    443                 pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].clientRequestCB( pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].ClientRequestCBObj,
    444                                                                                           SCR_CRS_FW_RESET, uResourceIndex, SCR_PR_NONE );
    445             }
    446             else
    447             {
    448                 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", pScr->runningClient[ uResourceIndex ]);
    449             }
    450         }
    451     #ifdef TI_DBG
    452         else
    453         {
    454             TRACE0( pScr->hReport, REPORT_SEVERITY_INFORMATION, "FW reset occured. No client was running.\n");
    455         }
    456     #endif
    457     }
    458 }
    459 
    460 /**
    461  * \\n
    462  * \date 27-April-2005\n
    463  * \brief Changes the current SCR group.\n
    464  *
    465  * Function Scope \e Public.\n
    466  * \param hScr - handle to the SCR object.\n
    467  * \param newGroup - the new group to use.\n
    468  */
    469 void scr_setGroup( TI_HANDLE hScr, EScrGroupId newGroup )
    470 {
    471     TScr            *pScr = (TScr*)hScr;
    472     TI_UINT32       i, uResourceIndex;
    473     EScrClientId    highestPending;
    474 
    475     TRACE1( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Setting group %d.\n", newGroup);
    476 
    477 #ifdef TI_DBG
    478     if (newGroup >= SCR_GID_NUM_OF_GROUPS)
    479     {
    480         TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to set invalid group to %d\n", newGroup);
    481         return;
    482     }
    483 #endif
    484 
    485     /* keep the new group */
    486     pScr->currentGroup = newGroup;
    487 
    488     /* check both resources */
    489     for (uResourceIndex = 0; uResourceIndex < SCR_RESOURCE_NUM_OF_RESOURCES; uResourceIndex++)
    490     {
    491         /* for all pending clients */
    492         for ( i = 0; i < SCR_CID_NUM_OF_CLIENTS; i++ )
    493         {
    494             /* if the pending reason has escalated */
    495             if ( (pScr->clientArray[ i ].state[ uResourceIndex ] == SCR_CS_PENDING) && /* the client is pending */
    496                  (pScr->clientArray[ i ].currentPendingReason[ uResourceIndex ] < SCR_PR_DIFFERENT_GROUP_RUNNING) && /* the client was enabled in the previous group */
    497                  (TI_FALSE == clientStatus[ uResourceIndex ][ pScr->currentMode ][ newGroup ][ i ])) /* the client is not enabled in the new group */
    498             {
    499                 /* mark the new pending reason */
    500                 pScr->clientArray[ i ].currentPendingReason[ uResourceIndex ] = SCR_PR_DIFFERENT_GROUP_RUNNING;
    501 
    502                 /* notify the client of the change, using its callback */
    503                 if ( NULL != pScr->clientArray[ i ].clientRequestCB )
    504                 {
    505                     pScr->clientArray[ i ].clientRequestCB( pScr->clientArray[ i ].ClientRequestCBObj,
    506                                                             SCR_CRS_PEND, uResourceIndex, SCR_PR_DIFFERENT_GROUP_RUNNING );
    507                 }
    508                 else
    509                 {
    510                     TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", i);
    511                 }
    512             }
    513         }
    514 
    515 
    516         /*
    517          * if no client is running call the highest pending client
    518          * (after group change, previously pending clients may be enabled)
    519          */
    520         if ( SCR_CID_NO_CLIENT == pScr->runningClient[ uResourceIndex ] )
    521         {
    522             highestPending = scrFindHighest( hScr, SCR_CS_PENDING, uResourceIndex,
    523                                              (SCR_CID_NUM_OF_CLIENTS - 1), 0 );
    524             if (SCR_CID_NO_CLIENT != highestPending)
    525             {
    526                 pScr->clientArray[ highestPending ].state[ uResourceIndex ] = SCR_CS_RUNNING;
    527                 pScr->clientArray[ highestPending ].currentPendingReason[ uResourceIndex ] = SCR_PR_NONE;
    528                 pScr->runningClient[ uResourceIndex ] = (EScrClientId)highestPending;
    529                 if ( NULL != pScr->clientArray[ highestPending ].clientRequestCB )
    530                 {
    531                     pScr->clientArray[ highestPending ].clientRequestCB( pScr->clientArray[ highestPending ].ClientRequestCBObj,
    532                                                                          SCR_CRS_RUN, uResourceIndex, SCR_PR_NONE );
    533                 }
    534                 else
    535                 {
    536                     TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", highestPending);
    537                 }
    538             }
    539         }
    540     }
    541 }
    542 
    543 /**
    544  * \\n
    545  * \date 23-Nov-2005\n
    546  * \brief Changes the current SCR mode.\n
    547  *
    548  * Function Scope \e Public.\n
    549  * \param hScr - handle to the SCR object.\n
    550  * \param newMode - the new mode to use.\n
    551  */
    552 void scr_setMode( TI_HANDLE hScr, EScrModeId newMode )
    553 {
    554 	TScr            *pScr = (TScr*)hScr;
    555 #ifdef SCR_ABORT_NOTIFY_ENABLED
    556     TI_UINT32       i, uResourceIndex;
    557     EScrClientId    highestPending;
    558 #endif
    559 
    560     TRACE1( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Setting mode %d.\n", newMode);
    561 
    562 #ifdef TI_DBG
    563     if (newMode >= SCR_MID_NUM_OF_MODES)
    564     {
    565         TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to set invalid mode to %d\n", newMode);
    566         return;
    567     }
    568 #endif
    569 
    570     /* keep the new mode */
    571     pScr->currentMode = newMode;
    572 
    573 #ifdef SCR_ABORT_NOTIFY_ENABLED
    574 
    575     for (uResourceIndex = 0; uResourceIndex < SCR_RESOURCE_NUM_OF_RESOURCES; uResourceIndex++)
    576     {
    577         /* Stage I : if someone is running and shouldn't be running in the new mode - Abort it */
    578         if ( (SCR_CID_NO_CLIENT != pScr->runningClient[ uResourceIndex ]) &&
    579              (TI_FALSE == clientStatus[ uResourceIndex ][ pScr->currentMode ][ pScr->currentGroup ][ pScr->runningClient[ uResourceIndex ] ]))
    580         {
    581             /* abort the running client */
    582             pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].state[ uResourceIndex ] = SCR_CS_ABORTING;
    583             if ( NULL != pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].clientRequestCB )
    584             {
    585                 TRACE2( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Sending abort request to client %d for resource %d\n", pScr->runningClient[ uResourceIndex ], uResourceIndex);
    586                 pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].clientRequestCB( pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].ClientRequestCBObj,
    587                                                                                             SCR_CRS_ABORT,
    588                                                                                             uResourceIndex,
    589                                                                                             SCR_PR_NONE );
    590             }
    591             else
    592             {
    593                 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", pScr->runningClient[ uResourceIndex ]);
    594             }
    595         }
    596 
    597         /* Stage II : notify escalated pending reason */
    598         /* for all pending clients */
    599         for ( i = 0; i < SCR_CID_NUM_OF_CLIENTS; i++ )
    600         {
    601             /* if the pending reason has escalated */
    602             if ( (pScr->clientArray[ i ].state[ uResourceIndex ] == SCR_CS_PENDING) && /* the client is pending */
    603                  (pScr->clientArray[ i ].currentPendingReason[ uResourceIndex ] < SCR_PR_DIFFERENT_GROUP_RUNNING) && /* the client was enabled in the previous group */
    604                  (TI_FALSE == clientStatus[ uResourceIndex ][ pScr->currentMode ][ pScr->currentGroup ][ i ])) /* the client is not enabled in the new group/mode */
    605             {
    606                 /* mark the new pending reason */
    607                 pScr->clientArray[ i ].currentPendingReason[ uResourceIndex ] = SCR_PR_DIFFERENT_GROUP_RUNNING;
    608 
    609                 /* notify the client of the change, using its callback */
    610                 if ( NULL != pScr->clientArray[ i ].clientRequestCB )
    611                 {
    612                     pScr->clientArray[ i ].clientRequestCB( pScr->clientArray[ i ].ClientRequestCBObj,
    613                                                             SCR_CRS_PEND, uResourceIndex,
    614                                                             SCR_PR_DIFFERENT_GROUP_RUNNING );
    615                 }
    616                 else
    617                 {
    618                     TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", i);
    619                 }
    620             }
    621         }
    622 
    623 
    624         /* Stage III : call Highest Pending Client who is enabled in the new mode   */
    625         if ( SCR_CID_NO_CLIENT == pScr->runningClient[ uResourceIndex ] )
    626         {
    627             highestPending = scrFindHighest( hScr, SCR_CS_PENDING, uResourceIndex,
    628                                              (SCR_CID_NUM_OF_CLIENTS - 1), 0 );
    629             if (SCR_CID_NO_CLIENT != highestPending)
    630             {
    631                 pScr->clientArray[ highestPending ].state[ uResourceIndex ] = SCR_CS_RUNNING;
    632                 pScr->clientArray[ highestPending ].currentPendingReason[ uResourceIndex ] = SCR_PR_NONE;
    633                 pScr->runningClient[ uResourceIndex ] = (EScrClientId)highestPending;
    634                 if ( NULL != pScr->clientArray[ highestPending ].clientRequestCB )
    635                 {
    636                     pScr->clientArray[ highestPending ].clientRequestCB( pScr->clientArray[ highestPending ].ClientRequestCBObj,
    637                                                                          SCR_CRS_RUN, uResourceIndex,
    638                                                                          SCR_PR_NONE );
    639                 }
    640                 else
    641                 {
    642                     TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", highestPending);
    643                 }
    644             }
    645         }
    646     }
    647 #endif	/* SCR_ABORT_NOTIFY_ENABLED */
    648 }
    649 
    650 
    651 /**
    652  * \\n
    653  * \date 01-Dec-2004\n
    654  * \brief Request the channel use by a client
    655  *
    656  * Function Scope \e Public.\n
    657  * \param hScr - handle to the SCR object.\n
    658  * \param client - the client ID requesting the channel.\n
    659  * \param resource - the requested resource.\n
    660  * \param pPendReason - the reason for a pend reply.\n
    661  * \return The request status.\n
    662  * \retval SCR_CRS_REJECT the channel cannot be allocated to this client.
    663  * \retval SCR_CRS_PEND the channel is currently busy, and this client had been placed on the waiting list.
    664  * \retval SCR_CRS_RUN the channel is allocated to this client.
    665  */
    666 EScrClientRequestStatus scr_clientRequest( TI_HANDLE hScr, EScrClientId client,
    667                                            EScrResourceId eResource, EScePendReason* pPendReason )
    668 {
    669     TScr    *pScr = (TScr*)hScr;
    670 
    671     TRACE2( pScr->hReport, REPORT_SEVERITY_INFORMATION, "scr_clientRequest: Client %d requesting the channel for resource %d.\n", client, eResource);
    672 
    673 #ifdef TI_DBG
    674     if (client >= SCR_CID_NUM_OF_CLIENTS)
    675     {
    676         TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to request SCR for invalid client %d\n", client);
    677         return SCR_CRS_PEND;
    678     }
    679     if (SCR_RESOURCE_NUM_OF_RESOURCES <= eResource)
    680     {
    681         TRACE2( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to request SCR by client %d for invalid resource %d\n", client, eResource);
    682         return SCR_CRS_PEND;
    683     }
    684 #endif
    685 
    686     *pPendReason = SCR_PR_NONE;
    687 
    688     /* check if already inside a request - shouldn't happen!!! */
    689     if ( TI_TRUE == pScr->statusNotficationPending )
    690     {
    691         TRACE0( pScr->hReport, REPORT_SEVERITY_ERROR, "request call while already in request!\n");
    692         return SCR_CRS_PEND;
    693     }
    694 
    695     /* check if current running client is requesting */
    696     if ( client == pScr->runningClient[ eResource ] )
    697     {
    698         TRACE2( pScr->hReport, REPORT_SEVERITY_WARNING, "Client %d re-requesting SCR for resource %d\n", client, eResource);
    699         return SCR_CRS_RUN;
    700     }
    701 
    702     TRACE5( pScr->hReport, REPORT_SEVERITY_INFORMATION, "scr_clientRequest: is client enabled = %d. eResource=%d,currentMode=%d,currentGroup=%d,client=%d,\n", clientStatus[ eResource ][ pScr->currentMode ][ pScr->currentGroup ][ client ], eResource, pScr->currentMode, pScr->currentGroup, client);
    703 
    704     /* check if the client is enabled in the current group */
    705     if ( TI_TRUE != clientStatus[ eResource ][ pScr->currentMode ][ pScr->currentGroup ][ client ])
    706     {
    707         pScr->clientArray[ client ].state[ eResource ] = SCR_CS_PENDING;
    708         pScr->clientArray[ client ].currentPendingReason[ eResource ]
    709                                                 = *pPendReason = SCR_PR_DIFFERENT_GROUP_RUNNING;
    710         return SCR_CRS_PEND;
    711     }
    712 
    713     /* check if a there's no running client at the moment */
    714     if ( SCR_CID_NO_CLIENT == pScr->runningClient[ eResource ] )
    715     {
    716         /* no running or aborted client - allow access */
    717         TRACE2( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Resource %d allocated to client: %d\n", eResource, client);
    718         pScr->clientArray[ client ].state[ eResource ] = SCR_CS_RUNNING;
    719         pScr->runningClient[ eResource ] = client;
    720         return SCR_CRS_RUN;
    721     }
    722 
    723     /* check if any client is aborting at the moment */
    724     if ( SCR_CS_ABORTING == pScr->clientArray[ pScr->runningClient[ eResource ] ].state[ eResource ] )
    725     {
    726         /* a client is currently aborting, but there still might be a pending client with higher priority
    727            than the client currently requesting the SCR. If such client exists, the requesting client is
    728            notified that it is pending because of this pending client, rather than the one currently aborting.
    729         */
    730         EScrClientId highestPending;
    731         highestPending = scrFindHighest( hScr, SCR_CS_PENDING, eResource,
    732                                          (SCR_CID_NUM_OF_CLIENTS - 1), client );
    733         if ( (SCR_CID_NO_CLIENT == highestPending) ||
    734              (highestPending < client))
    735         {
    736             /* if the requesting client has higher priority than the current highest priority pending client,
    737                the current highest priority pending client should be notified that its pending reason has
    738                changed (it is no longer waiting for current running client to abort, but for the requesting
    739                client to finish, once the current has aborted */
    740             if ( (highestPending != SCR_CID_NO_CLIENT) &&
    741                  (SCR_PR_OTHER_CLIENT_ABORTING == pScr->clientArray[ highestPending ].currentPendingReason[ eResource ]))
    742             {
    743 
    744                 if ( NULL != pScr->clientArray[ highestPending ].clientRequestCB )
    745                 {
    746                     pScr->clientArray[ highestPending ].clientRequestCB( pScr->clientArray[ highestPending ].ClientRequestCBObj,
    747                                                                          SCR_CRS_PEND, eResource, SCR_PR_OTHER_CLIENT_RUNNING );
    748                 }
    749                 else
    750                 {
    751                     TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", highestPending);
    752                 }
    753             }
    754             pScr->clientArray[ client ].currentPendingReason[ eResource ] = *pPendReason = SCR_PR_OTHER_CLIENT_ABORTING;
    755         }
    756         else
    757         {
    758             pScr->clientArray[ client ].currentPendingReason[ eResource ] = *pPendReason = SCR_PR_OTHER_CLIENT_RUNNING;
    759         }
    760         pScr->clientArray[ client ].state[ eResource ] = SCR_CS_PENDING;
    761         return SCR_CRS_PEND;
    762     }
    763 
    764     /* check if a client with higher priority is running */
    765     if (pScr->runningClient[ eResource ] > client)
    766     {
    767         pScr->clientArray[ client ].state[ eResource ] = SCR_CS_PENDING;
    768         pScr->clientArray[ client ].currentPendingReason[ eResource ] = *pPendReason = SCR_PR_OTHER_CLIENT_RUNNING;
    769         return SCR_CRS_PEND;
    770     }
    771 
    772     /* if the client is not supposed to abort lower priority clients */
    773     if ( (SCR_CID_NO_CLIENT == abortOthers[ eResource ][ client ]) || /* client is not supposed to abort any other client */
    774          (pScr->runningClient[ eResource ] > abortOthers[ eResource ][ client ])) /* client is not supposed to abort running client */
    775     {
    776         /* wait for the lower priority client */
    777         pScr->clientArray[ client ].state[ eResource ] = SCR_CS_PENDING;
    778         pScr->clientArray[ client ].currentPendingReason[ eResource ] = *pPendReason = SCR_PR_OTHER_CLIENT_RUNNING;
    779         return SCR_CRS_PEND;
    780     }
    781 
    782     /* at this point, there is a lower priority client running, that should be aborted: */
    783     /* mark the requesting client as pending (until the abort process will be completed) */
    784     pScr->clientArray[ client ].state[ eResource ] = SCR_CS_PENDING;
    785 
    786     /* mark that we are in the middle of a request (if a re-entrance will occur in the complete) */
    787     pScr->statusNotficationPending = TI_TRUE;
    788 
    789     /* abort the running client */
    790     pScr->clientArray[ pScr->runningClient[ eResource ] ].state[ eResource ] = SCR_CS_ABORTING;
    791     if ( NULL != pScr->clientArray[ pScr->runningClient[ eResource ] ].clientRequestCB )
    792     {
    793         TRACE2( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Sending abort request to client %d for resource %d\n", pScr->runningClient[ eResource ], eResource);
    794         pScr->clientArray[ pScr->runningClient[ eResource ] ].clientRequestCB( pScr->clientArray[ pScr->runningClient[ eResource ] ].ClientRequestCBObj,
    795                                                                                SCR_CRS_ABORT, eResource,
    796                                                                                SCR_PR_NONE );
    797     }
    798     else
    799     {
    800         TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", pScr->runningClient[ eResource ]);
    801     }
    802 
    803     /* mark that we have finished the request process */
    804     pScr->statusNotficationPending = TI_FALSE;
    805 
    806     /* return the current status (in case the completion changed the client status to run) */
    807     if ( SCR_CS_RUNNING == pScr->clientArray[ client ].state[ eResource ] )
    808     {
    809         TRACE1( pScr->hReport, REPORT_SEVERITY_INFORMATION, "channel allocated to client: %d\n", client);
    810         return SCR_CRS_RUN;
    811     }
    812     else
    813     {
    814         pScr->clientArray[ client ].currentPendingReason[ eResource ] = *pPendReason = SCR_PR_OTHER_CLIENT_ABORTING;
    815         return SCR_CRS_PEND;
    816     }
    817 }
    818 
    819 /**
    820  * \\n
    821  * \date 01-Dec-2004\n
    822  * \brief Notifies the SCR that the client doe not require the channel any longer
    823  *
    824  * This function can be called both by clients that are in possession of the channel, and by
    825  * clients that are pending to use the channel.\n
    826  * Function Scope \e Public.\n
    827  * \param hScr - handle to the SCR object.\n
    828  * \param client - the client releasing the channel.\n
    829  * \param eResource - the resource being released.\n
    830  * \return TI_OK if successful, TI_NOK otherwise.\n
    831  */
    832 void scr_clientComplete( TI_HANDLE hScr, EScrClientId client, EScrResourceId eResource )
    833 {
    834     TScr            *pScr = (TScr*)hScr;
    835     EScrClientId    highestPending;
    836 
    837     TRACE2( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Client %d releasing resource %d.\n", client, eResource);
    838 
    839 #ifdef TI_DBG
    840     if (client >= SCR_CID_NUM_OF_CLIENTS)
    841     {
    842         TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to release SCR for invalid client %d\n", client);
    843         return;
    844     }
    845     if (SCR_RESOURCE_NUM_OF_RESOURCES <= eResource)
    846     {
    847         TRACE2( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to release invalid resource %d by client %d\n", eResource, client);
    848         return;
    849     }
    850 #endif
    851 
    852     /* mark client state as idle */
    853     pScr->clientArray[ client ].state[ eResource ] = SCR_CS_IDLE;
    854     pScr->clientArray[ client ].currentPendingReason[ eResource ] = SCR_PR_NONE;
    855 
    856     /* if completing client is running (or aborting) */
    857     if ( pScr->runningClient[ eResource ] == client )
    858     {
    859         /* mark no running client */
    860         pScr->runningClient[ eResource ] = SCR_CID_NO_CLIENT;
    861 
    862         /* find the pending client with highest priority */
    863         highestPending = scrFindHighest( hScr, SCR_CS_PENDING, eResource, (SCR_CID_NUM_OF_CLIENTS-1), 0 );
    864 
    865         /* if a pending client exists */
    866         if ( SCR_CID_NO_CLIENT != highestPending )
    867         {
    868             /* mark the client with highest priority as running */
    869             pScr->clientArray[ highestPending ].state[ eResource ] = SCR_CS_RUNNING;
    870             pScr->clientArray[ highestPending ].currentPendingReason[ eResource ] = SCR_PR_NONE;
    871             pScr->runningClient[ eResource ] = highestPending;
    872 
    873             /* if the SCR is not called from within a client request (re-entrance) */
    874             if ( TI_FALSE == pScr->statusNotficationPending )
    875             {
    876                 if ( NULL != pScr->clientArray[ highestPending ].clientRequestCB )
    877                 {
    878                     pScr->clientArray[ highestPending ].clientRequestCB( pScr->clientArray[ highestPending ].ClientRequestCBObj,
    879                                                                          SCR_CRS_RUN, eResource, SCR_PR_NONE );
    880                 }
    881                 else
    882                 {
    883                     TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", highestPending);
    884                 }
    885             }
    886         }
    887     }
    888 }
    889 
    890 /**
    891  * \\n
    892  * \date 01-Dec-2004\n
    893  * \brief Searches the client database for a client with matching state, from startFrom to endAt (inclusive).
    894  * \brief Only searches for clients that are enabled at the current group!!!!\n
    895  *
    896  * Function Scope \e Private.\n
    897  * \param hScr - handle to the SCR object.\n
    898  * \param requiredState - the state to match.\n
    899  * \param eResource - the resource to macth.\n
    900  * \param startFrom - the highest priority to begin searching from.\n
    901  * \param endAt - the lowest priority to include in the search
    902  * \return the client ID if found, SCR_CID_NO_CLIENT if not found.\n
    903  */
    904 EScrClientId scrFindHighest( TI_HANDLE hScr,
    905                              EScrClientState requiredState,
    906                              EScrResourceId  eResource,
    907                              TI_UINT32 startFrom,
    908                              TI_UINT32 endAt )
    909 {
    910     TScr        *pScr = (TScr*)hScr;
    911     TI_INT32    i, iStartFrom, iEndAt;
    912 
    913     /*
    914      * signed indexes are used to avoid an overflow in the for loop when endAt equals zero
    915      * and the unsigned i is "reduced" to overflow to 4 Billion
    916      */
    917     iStartFrom = (TI_INT32)startFrom;
    918     iEndAt = (TI_INT32)endAt;
    919 
    920     /* loop on all clients, from start to end */
    921     for ( i = iStartFrom; i >= iEndAt; i-- )
    922     {
    923         /* check if the client state matches the required state */
    924         if ( (TI_TRUE == clientStatus[ eResource ][ pScr->currentMode ][ pScr->currentGroup ][ i ]) && /* client is enabled in current group */
    925              (requiredState == pScr->clientArray[ i ].state[ eResource ])) /* client is in required state */
    926         {
    927             /* and if so, return the client index */
    928             return i;
    929         }
    930     }
    931 
    932     return SCR_CID_NO_CLIENT;
    933 }
    934