Home | History | Annotate | Download | only in Data_link
      1 /*
      2  * GeneralUtil.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 #define __FILE_ID__  FILE_ID_52
     35 #include "GeneralUtilApi.h"
     36 #include "GeneralUtil.h"
     37 #include "report.h"
     38 #include "osApi.h"
     39 
     40 /*************************************************************************
     41 *                        LIST OBJ                                        *
     42 **************************************************************************
     43 **************************************************************************
     44 *
     45  *	The list object mange the allocation and deallocation of generic element.
     46  *  The obj create a list of N generic elements and fined a free entry for the Alloc process.
     47  *  And free the entry for dealloc.
     48  *
     49  *
     50 ***************************************************************************/
     51 
     52 
     53 
     54 /*************************************************************************
     55 *                        List_create                                     *
     56 **************************************************************************
     57 * DESCRIPTION:	This function initializes the List data module.
     58 *
     59 * INPUT:		hOs - handle to Os Abstraction Layer
     60 *				MaxNumOfElements - the number of elemnts that will be Managed by the list
     61                 ContainerSize - The size of the basic data type managed by the list
     62 * OUTPUT:
     63 *
     64 *
     65 * RETURN:		Handle to the allocated List data control block
     66 ************************************************************************/
     67 TI_HANDLE List_create(TI_HANDLE hOs,int MaxNumOfElements,int ContainerSize)
     68 {
     69     int index;
     70     List_t *List;
     71 
     72 	if( hOs  == NULL )
     73 	{
     74 	    WLAN_OS_REPORT(("FATAL ERROR:List_create(): OS handle Error - Aborting\n"));
     75 		return NULL;
     76 	}
     77 
     78 	/* alocate List block */
     79 	List = (List_t*)os_memoryAlloc(hOs, sizeof(List_t));
     80 	if(List == NULL)
     81 	    return NULL;
     82 
     83 
     84     /* alocate the List of Elements */
     85     List->ElementList =(ListElement_t*)os_memoryAlloc(hOs, (sizeof(ListElement_t)*MaxNumOfElements));
     86 	if(List->ElementList == NULL)
     87     {
     88         os_memoryFree(List->hOs, List, sizeof(List_t));
     89         return NULL;
     90     }
     91 
     92     /*Allocate the Data containers*/
     93     for(index=0;index<MaxNumOfElements;index++)
     94     {
     95         List->ElementList[index].Container = os_memoryAlloc(hOs,ContainerSize);
     96         if(List->ElementList[index].Container == NULL)
     97             break;
     98         List->ElementList[index].Inuse = TI_FALSE;
     99     }
    100     if (index != MaxNumOfElements)  /*Not all the list element was allocated and*/
    101     {                                /*therefore we free the entire list and rap it up*/
    102        index--;
    103        for(;index>=0;index--)
    104             os_memoryFree(hOs,List->ElementList[index].Container,ContainerSize);
    105        os_memoryFree(List->hOs, List->ElementList, (sizeof(ListElement_t)*MaxNumOfElements));
    106        os_memoryFree(List->hOs,List,(sizeof(List_t)));
    107        return NULL;
    108 
    109     }
    110 
    111     List->MaxNumOfElements = MaxNumOfElements;
    112     List->ContainerSize = ContainerSize;
    113 	return((TI_HANDLE)List);
    114 }
    115 
    116 
    117 /***************************************************************************
    118 *							List_Destroy				                   *
    119 ****************************************************************************
    120 * DESCRIPTION:	This function unload the List data module.
    121 *
    122 * INPUTS:		hCtrlData - the object
    123 *
    124 * OUTPUT:
    125 *
    126 * RETURNS:		TI_OK - Unload succesfull
    127 *				TI_NOK - Unload unsuccesfull
    128 ***************************************************************************/
    129 TI_STATUS List_Destroy(TI_HANDLE hList)
    130 {
    131     List_t* List = (List_t*)hList;
    132     int index;
    133 
    134     if(List!=NULL)
    135     {
    136   	    if(List->ElementList != NULL)
    137         {
    138            for(index=0;index<List->MaxNumOfElements;index++)
    139              os_memoryFree(List->hOs,List->ElementList[index].Container,List->ContainerSize);
    140 
    141            os_memoryFree(List->hOs,List->ElementList,(sizeof(ListElement_t)*List->MaxNumOfElements));
    142         }
    143         os_memoryFree(List->hOs, List, sizeof(List_t));
    144     }
    145     return TI_OK;
    146 }
    147 
    148 /***************************************************************************
    149 *							List_AllocElement   		                   *
    150 ****************************************************************************
    151 *
    152 *
    153 *    Fined an empty entry in the list and returns
    154 *    a pointer to a memory that contains an element that not in use.
    155 *
    156 *    Note in multi Task environment we need to add semaphore to protect the
    157 *    Function.
    158 *
    159 ***************************************************************************/
    160 TI_HANDLE List_AllocElement(TI_HANDLE hList)
    161 {
    162     List_t* List = (List_t*)hList;
    163     int index;
    164 
    165     if (List == NULL)
    166         return NULL;
    167 
    168     for(index=0;index<List->MaxNumOfElements;index++)
    169     {
    170         if(!(List->ElementList[index].Inuse))
    171         {
    172            List->ElementList[index].Inuse = TI_TRUE;
    173            os_memoryZero(List->hOs,List->ElementList[index].Container,List->ContainerSize);
    174            return((TI_HANDLE)List->ElementList[index].Container);
    175         }
    176     }
    177     return NULL;
    178 }
    179 
    180 
    181 /***************************************************************************
    182 *							List_FreeElement				               *
    183 ****************************************************************************
    184 *
    185 *   Marks the entry that was allocated as free.
    186 *   An alloc process can use this space.
    187 *
    188 *
    189 *
    190 ***************************************************************************/
    191 TI_STATUS List_FreeElement(TI_HANDLE hList,TI_HANDLE Container)
    192 {
    193     List_t* List = (List_t*)hList;
    194     int index;
    195 
    196     if (List == NULL)
    197         return TI_NOK;
    198 
    199     for(index=0;index<List->MaxNumOfElements;index++)
    200     {
    201         if(List->ElementList[index].Container == Container)
    202         {
    203             if(!List->ElementList[index].Inuse)
    204                 return TI_NOK;  /*double free not legal*/
    205             List->ElementList[index].Inuse = TI_FALSE;
    206             return TI_OK;
    207         }
    208     }
    209     return TI_NOK;
    210 }
    211 
    212 
    213 /***************************************************************************
    214 *							List_GetFirst				                   *
    215 ****************************************************************************
    216 *
    217 *  For purposes of searching the element list (going over all the element in the list)
    218 *  Get first is used to reset an index for the search.
    219 *  This function is work combined with GetNext.
    220 *
    221 *   Note this function can't be used in multi Task environment.
    222 *
    223 ***************************************************************************/
    224 TI_HANDLE List_GetFirst(TI_HANDLE hList)
    225 {
    226     List_t* List = (List_t*)hList;
    227     int index;
    228 
    229     if (List == NULL)
    230         return NULL;
    231 
    232     for(index=0;index<List->MaxNumOfElements;index++)
    233     {
    234         if(List->ElementList[index].Inuse)
    235         {
    236            List->CurrentIndex = index;
    237            return (List->ElementList[index].Container);
    238         }
    239     }
    240     return NULL;
    241 }
    242 
    243 
    244 /***************************************************************************
    245 *							List_GetNext				                   *
    246 ****************************************************************************
    247 *
    248 *  This function returns the next element in the list till null
    249 *  that indicate that there no more element or we have reached the end of the list.
    250 *  This function is work combined with GetFirst.
    251 *
    252 *  Note this function can't be used in multi Task environment.
    253 *
    254 ***************************************************************************/
    255 TI_HANDLE List_GetNext(TI_HANDLE hList)
    256 {
    257     List_t* List = (List_t*)hList;
    258     int index;
    259 
    260     if (List == NULL)
    261         return NULL;
    262 
    263     /* the code works fine even if the elment is the last*/
    264     for(index=List->CurrentIndex+1;index<List->MaxNumOfElements;index++)
    265     {
    266         if(List->ElementList[index].Inuse)
    267         {
    268            List->CurrentIndex = index;
    269            return (List->ElementList[index].Container);
    270 
    271         }
    272     }
    273     return NULL;
    274 }
    275 
    276 
    277 
    278 
    279 /***************************************************************************
    280 *							DISTRIBUTOR MANAGER				               *
    281 ****************************************************************************
    282 ***************************************************************************
    283 *
    284  *    	PURPOSE:The distributor manger supplies
    285  *       1. Register mechanism that has a callback function and the condition
    286  *       (bit mask format) that will be used to distinguish if to call this callback.
    287  *       2. Event occurrence function that go over all the registered function and compare
    288  *       the input mask to the callback mask condition.
    289  *
    290  *
    291  *
    292 ***************************************************************************/
    293 
    294 
    295 
    296 /***************************************************************************
    297 *							DistributorMgr_Create		                   *
    298 ****************************************************************************
    299 *
    300 ***************************************************************************/
    301 TI_HANDLE DistributorMgr_Create(TI_HANDLE hOs , int MaxNotifReqElment)
    302 {
    303     DistributorMgr_t *DistributorMgr;
    304 
    305 	DistributorMgr = (DistributorMgr_t*)os_memoryAlloc(hOs, sizeof(DistributorMgr_t));
    306 	if(DistributorMgr == NULL)
    307         return NULL;
    308     DistributorMgr->hOs = hOs;
    309     DistributorMgr->DistributionList = (List_t*)List_create(hOs,MaxNotifReqElment,sizeof(NotifReqElment_t));
    310     if (DistributorMgr->DistributionList == NULL)
    311     {
    312         os_memoryFree(hOs, DistributorMgr, sizeof(DistributorMgr_t));
    313         return NULL;
    314     }
    315     return (TI_HANDLE)DistributorMgr;
    316 }
    317 
    318 
    319 
    320 /************************************************************************/
    321 /*               DistributorMgr_Destroy                                 */
    322 /************************************************************************/
    323 TI_STATUS DistributorMgr_Destroy(TI_HANDLE hDistributorMgr)
    324 {
    325     DistributorMgr_t *DistributorMgr =(DistributorMgr_t*)hDistributorMgr;
    326 
    327      if(DistributorMgr == NULL)
    328         return TI_NOK;
    329 
    330     List_Destroy(DistributorMgr->DistributionList);
    331 
    332     os_memoryFree(DistributorMgr->hOs, hDistributorMgr, sizeof(DistributorMgr_t));
    333 
    334     return TI_OK;
    335 
    336 }
    337 
    338 /***************************************************************************
    339 *						DistributorMgr_Reg				                   *
    340 ****************************************************************************
    341 *
    342 *  Use by the client to register a callback function
    343 *  with the mask condition that will trigger the call.
    344 *
    345 * input
    346 *    TI_UINT16 Mask
    347 *    TI_HANDLE CallBack
    348 *    HANDLE Context
    349 *    TI_UINT32 Cookie
    350 *
    351 *
    352 ***************************************************************************/
    353 TI_HANDLE DistributorMgr_Reg(TI_HANDLE hDistributorMgr,TI_UINT16 Mask,TI_HANDLE CallBack,
    354                              TI_HANDLE Context,TI_UINT32 Cookie)
    355 {
    356     DistributorMgr_t *DistributorMgr = (DistributorMgr_t*)hDistributorMgr;
    357     NotifReqElment_t *NotifReqElment;
    358 
    359    	if(DistributorMgr == NULL)
    360         return NULL;
    361 
    362     NotifReqElment = (NotifReqElment_t*)List_AllocElement(DistributorMgr->DistributionList);
    363     if (NotifReqElment == NULL)
    364 		return NULL  ;
    365 
    366     NotifReqElment->CallBack = (GeneralEventCall_t)CallBack;
    367     NotifReqElment->Mask = Mask;
    368     NotifReqElment->Context = Context;
    369     NotifReqElment->Cookie = Cookie;
    370     NotifReqElment->HaltReq = TI_FALSE;
    371     return (TI_HANDLE)NotifReqElment;
    372 }
    373 
    374 
    375 /***************************************************************************
    376 *						DistributorMgr_ReReg				               *
    377 ****************************************************************************
    378 *
    379 ***************************************************************************/
    380 TI_STATUS DistributorMgr_ReReg(TI_HANDLE hDistributorMgr,TI_HANDLE ReqElmenth ,TI_UINT16 Mask,TI_HANDLE CallBack,TI_HANDLE Context,TI_UINT32 Cookie)
    381 {
    382     DistributorMgr_t *DistributorMgr = (DistributorMgr_t*)hDistributorMgr;
    383     NotifReqElment_t *NotifReqElment = (NotifReqElment_t*)ReqElmenth;
    384 
    385    	if(DistributorMgr == NULL)
    386         return TI_NOK;
    387 
    388     if (NotifReqElment == NULL)
    389 		return TI_NOK;
    390 
    391     NotifReqElment->CallBack = (GeneralEventCall_t)CallBack;
    392     NotifReqElment->Mask = Mask;
    393     NotifReqElment->Context = Context;
    394     NotifReqElment->Cookie = Cookie;
    395     return TI_OK;
    396 }
    397 
    398 
    399 /***************************************************************************
    400 *						DistributorMgr_AddToMask			               *
    401 ****************************************************************************
    402 *
    403 * Use this function to add mask bit to the bit mask condition that triggers the Callback
    404 *
    405 *
    406 ***************************************************************************/
    407 TI_STATUS DistributorMgr_AddToMask(TI_HANDLE hDistributorMgr,TI_HANDLE ReqElmenth,TI_UINT16 Mask)
    408 {
    409     DistributorMgr_t *DistributorMgr = (DistributorMgr_t*)hDistributorMgr;
    410     NotifReqElment_t *NotifReqElment = (NotifReqElment_t*)ReqElmenth;
    411 
    412     if(DistributorMgr == NULL)
    413         return TI_NOK;
    414 
    415     if (NotifReqElment == NULL)
    416 		return TI_NOK;
    417 
    418     NotifReqElment->Mask |= Mask;
    419     return TI_OK;
    420 }
    421 
    422 
    423 /***************************************************************************
    424 *						DistributorMgr_HaltNotif			               *
    425 ****************************************************************************
    426 *
    427 * Use this function to add mask bit to the bit mask condition that triggers the Callback
    428 *
    429 *
    430 ***************************************************************************/
    431 void DistributorMgr_HaltNotif(TI_HANDLE ReqElmenth)
    432 {
    433     NotifReqElment_t *NotifReqElment = (NotifReqElment_t*)ReqElmenth;
    434 
    435     if (NotifReqElment == NULL)
    436 	    return;
    437 
    438     NotifReqElment->HaltReq = TI_TRUE;
    439 
    440 }
    441 
    442 
    443 /***************************************************************************
    444 *						DistributorMgr_RestartNotif			               *
    445 ****************************************************************************
    446 *
    447 * Use this function to add mask bit to the bit mask condition that triggers the Callback
    448 *
    449 *
    450 ***************************************************************************/
    451 void DistributorMgr_RestartNotif(TI_HANDLE ReqElmenth)
    452 {
    453     NotifReqElment_t *NotifReqElment = (NotifReqElment_t*)ReqElmenth;
    454 
    455     if (NotifReqElment == NULL)
    456 	    return;
    457 
    458     NotifReqElment->HaltReq = TI_FALSE;
    459 
    460 }
    461 /***************************************************************************
    462 *						DistributorMgr_UnReg				               *
    463 ****************************************************************************
    464 *
    465 *
    466 ***************************************************************************/
    467 TI_STATUS DistributorMgr_UnReg(TI_HANDLE hDistributorMgr,TI_HANDLE RegEventHandle)
    468 {
    469     DistributorMgr_t *DistributorMgr = (DistributorMgr_t*)hDistributorMgr;
    470 
    471   	if(DistributorMgr == NULL)
    472         return TI_NOK;
    473 
    474     return List_FreeElement(DistributorMgr->DistributionList, RegEventHandle);
    475 }
    476 
    477 
    478 /***************************************************************************
    479 *						DistributorMgr_EventCall		                   *
    480 ****************************************************************************
    481 *
    482 * When the client needs to invoke the callback calls function that corresponds
    483 * to a specific event mask it will call this function with the desired mask.
    484 * And event count that can be used to aggregate the events.
    485 * that way calling this function not for every event
    486 *
    487 ***************************************************************************/
    488 void DistributorMgr_EventCall(TI_HANDLE hDistributorMgr,TI_UINT16 Mask,int EventCount)
    489 {
    490     DistributorMgr_t *DistributorMgr = (DistributorMgr_t*)hDistributorMgr;
    491     NotifReqElment_t *NotifReqElment;
    492 
    493     if(DistributorMgr == NULL)
    494         return;
    495 
    496     NotifReqElment = (NotifReqElment_t*)List_GetFirst(DistributorMgr->DistributionList);
    497 
    498     while(NotifReqElment)
    499     {
    500         if((NotifReqElment->Mask & Mask) && !(NotifReqElment->HaltReq))
    501         {
    502             NotifReqElment->CallBack(NotifReqElment->Context,EventCount,Mask,
    503                                      NotifReqElment->Cookie);
    504         }
    505         NotifReqElment = (NotifReqElment_t*)List_GetNext(DistributorMgr->DistributionList);
    506     }
    507 }
    508 
    509 
    510 
    511 /*******************************************************/
    512