openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

shr_allocator.c (26090B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * Global resource allocator
      8  */
      9 
     10 #include <shared/bsl.h>
     11 
     12 #include <sal/core/sync.h>
     13 #include <sal/core/libc.h>
     14 #include <shared/shr_allocator.h>
     15 #include <shared/error.h>
     16 
     17 
     18 #include <bcm/types.h>
     19 
     20 /*
     21  * one stucture per unit
     22  */
     23 _shr_res_handle_t _g_shr_res_handles[BCM_LOCAL_UNITS_MAX][SHR_USR_RES_MAX];
     24 
     25 _shr_hw_res_t    *_g_mapped_hw_res[BCM_LOCAL_UNITS_MAX];
     26 
     27 _shr_hw_res_attrs_t *_g_shr_res_attrs[BCM_LOCAL_UNITS_MAX];
     28 
     29 /*
     30  * LOCK related defines
     31  */
     32 sal_mutex_t  _shr_resource_mlock[BCM_MAX_NUM_UNITS];
     33 
     34 #define _SHR_RESOURCE_LOCK_CREATED_ALREADY(unit) \
     35     (_shr_resource_mlock[(unit)] != NULL)
     36 
     37 #define _SHR_RESOURCE_LOCK(unit)                    \
     38     (_SHR_RESOURCE_LOCK_CREATED_ALREADY(unit) ?      \
     39      sal_mutex_take(_shr_resource_mlock[(unit)], sal_mutex_FOREVER)?_SHR_E_UNIT:_SHR_E_NONE: \
     40      _SHR_E_UNIT)
     41 
     42 #define _SHR_RESOURCE_UNLOCK(unit)          \
     43     sal_mutex_give(_shr_resource_mlock[(unit)])
     44 
     45 /*
     46  *   Function
     47  *      _shr_get_resource_handle
     48  *   Purpose
     49  *      Get the internal resource handle based on unit and type.
     50  *   Parameters
     51  *      unit    - (IN)  unit number of the device
     52  *      type    - (IN)  resource type
     53  *                      (one of _shr_usr_res_types_t)
     54  *      handle  - (OUT) resource allocation handle
     55  *   Returns
     56  *     _SHR_E_NONE   if got the handle
     57  *     _SHR_E_*      as appropriate otherwise
     58  */
     59 
     60 STATIC int
     61 _shr_get_resource_handle(int                        unit,
     62                          _shr_usr_res_types_t       type,
     63                          _shr_res_handle_t          *handle)
     64 {
     65     _shr_hw_res_t         hw_res;
     66     _shr_res_handle_t     *res_handle;
     67 
     68     if ((type >= SHR_USR_RES_MAX) || (handle == NULL)) {
     69         return _SHR_E_PARAM;
     70     }
     71     hw_res = _g_mapped_hw_res[unit][type];
     72 
     73     res_handle = &_g_shr_res_handles[unit][hw_res];
     74     if (res_handle->alloc_style == SHR_ALLOC_STYLE_NONE) {
     75         return _SHR_E_PARAM;
     76     }
     77 
     78     *handle = *res_handle;
     79     return _SHR_E_NONE;
     80 }
     81 
     82 /*
     83  *   Function
     84  *      _shr_resource_alloc
     85  *   Purpose
     86  *      Allocate "count" number of resources.
     87  *   Parameters
     88  *      unit    - (IN)  unit number of the device
     89  *      type    - (IN)  resource type
     90  *                      (one of _shr_usr_res_types_t)
     91  *      count   - (IN)  Number of resources required
     92  *      elements- (OUT) Resource Index return by the underlying allocator
     93  *      flags   - (IN)  _SHR_RES_FLAGS_CONTIGOUS
     94  *                      if the resources need to be contigous
     95  *   Returns
     96  *      _SHR_E_NONE if element allocated successfully
     97  *      _SHR_E_RESOURCE if resource is in reserved range and compliant, not 
     98  *                     neccessarily an error.
     99  *      _SHR_E_* as appropriate otherwise
    100  */
    101 int
    102 _shr_resource_alloc(int                        unit,
    103                         _shr_usr_res_types_t   type,
    104                         uint32                     count,
    105                         uint32                    *elements,
    106                         uint32                     flags)
    107 {
    108     _shr_res_handle_t    handle;
    109     _shr_hw_res_attrs_t *res_attrs;
    110     int                       status, res;
    111     uint32                    i, size;
    112     uint32                   *done;
    113     shr_aidxres_element_t     tmp_elem, first, last;    
    114 
    115     if ((count <= 0) || (elements == NULL)) {
    116         return _SHR_E_PARAM;
    117     }
    118 
    119     _SHR_E_IF_ERROR_RETURN(_SHR_RESOURCE_LOCK(unit));
    120 
    121     status = _shr_get_resource_handle(unit,
    122                                           type,
    123                                           &handle);
    124     if (status != _SHR_E_NONE) {
    125         _SHR_RESOURCE_UNLOCK(unit);
    126         return status;
    127     }
    128 
    129     res_attrs =  &_g_shr_res_attrs[unit][_g_mapped_hw_res[unit][type]];
    130 
    131     /*
    132      * if the reserve flag is set, make sure that the elements are
    133      * available
    134      */
    135     if (flags & _SHR_RES_FLAGS_RESERVE) {
    136         int checkVal = _SHR_E_NOT_FOUND;
    137         int inRange = 0;
    138         
    139         if (res_attrs->reservedHigh && res_attrs->reservedLow) {
    140 
    141             for (i = 0; i < count; i++) {
    142                 if (elements[i] >= res_attrs->reservedLow && 
    143                     elements[i] <= res_attrs->reservedHigh) {
    144                     inRange++;
    145                 }
    146             }
    147 
    148             LOG_VERBOSE(BSL_LS_SOC_COMMON,
    149                         (BSL_META_U(unit,
    150                                     "Found a reserved range on resource %d: "
    151                                     "0x%08x-0x%08x count=%d inRange=%d\n"), 
    152                          type, res_attrs->reservedLow, res_attrs->reservedHigh,
    153                          count, inRange));
    154             
    155             if (inRange && inRange != count) {
    156                 /* part some elements are in reserved range, but not all */
    157                 _SHR_RESOURCE_UNLOCK(unit);
    158                 return _SHR_E_PARAM;
    159             }
    160 
    161             /* If these elements are in the reserved range, 
    162              * verify they exist 
    163              */
    164             if (inRange) {
    165                 checkVal = _SHR_E_EXISTS;
    166             }
    167         }
    168 
    169         switch (handle.alloc_style) {
    170             case SHR_ALLOC_STYLE_SINGLE:
    171             case SHR_ALLOC_STYLE_SCALED:
    172                 for (i = 0; i < count; i++) {
    173 
    174                     /* check and apply translator */
    175                     tmp_elem = elements[i];
    176                     if (res_attrs->e2i) {
    177                         tmp_elem = res_attrs->e2i(unit, elements[i]);
    178                     }
    179 
    180                     res = shr_idxres_list_elem_state(handle.idx_handle, 
    181                                                      tmp_elem);
    182                     if (res != checkVal) {
    183                         status = _SHR_E_BUSY;
    184                         break;
    185                     }
    186                     
    187                 }
    188             break;
    189 
    190             case  SHR_ALLOC_STYLE_VERSATILE:
    191                 for (i = 0; i < count; i++) {
    192                     if (flags & _SHR_RES_FLAGS_CONTIGOUS) {
    193                         tmp_elem = (shr_aidxres_element_t) (elements[0] + i);
    194                     } else {
    195                         tmp_elem = (shr_aidxres_element_t)elements[i];
    196                     }
    197                     /* check and apply translator */
    198                     if (res_attrs->e2i) {
    199                         tmp_elem = res_attrs->e2i(unit, elements[i]);
    200                     }
    201 
    202                     res = shr_aidxres_list_elem_state(handle.aidx_handle,
    203                                                       tmp_elem);
    204                     if (res != checkVal) {
    205                         status = _SHR_E_BUSY;
    206                         break;
    207                     }
    208                 }
    209 
    210             break;
    211         }
    212 
    213         /* may not be a real error; informing the caller that the resource
    214          * is in the reserved range, and checks out as OK.
    215          */ 
    216         if (inRange && _SHR_E_SUCCESS(status)) {
    217             status = _SHR_E_RESOURCE;
    218         }
    219     }
    220 
    221     if (status != _SHR_E_NONE) {
    222         _SHR_RESOURCE_UNLOCK(unit);
    223         return status;
    224     }
    225 
    226     done = NULL;
    227     if ( (count > 1) &&
    228          (!(flags & ((_SHR_RES_FLAGS_CONTIGOUS) |
    229                      (_SHR_RES_FLAGS_RESERVE))))) {
    230         size = (sizeof(uint32) * count);
    231         done = (uint32 *)sal_alloc(size, "RES-LIB");
    232         if (done == NULL) {
    233             _SHR_RESOURCE_UNLOCK(unit);
    234             return _SHR_E_MEMORY;
    235         }
    236         sal_memset(done, 0, size);
    237     }
    238 
    239     if ((flags & _SHR_RES_FLAGS_RESERVE) && (res_attrs->e2i)) {
    240         for (i = 0; i < count; i++) {
    241             elements[i] = res_attrs->e2i(unit, elements[i]);
    242         }
    243     }
    244 
    245     switch (handle.alloc_style) {
    246         case SHR_ALLOC_STYLE_SINGLE:
    247             if (count > 1) {
    248                 status = _SHR_E_PARAM;
    249             } else {
    250                 if (flags & _SHR_RES_FLAGS_RESERVE) {
    251                     first  = (shr_aidxres_element_t)elements[0];
    252                     last   = (shr_aidxres_element_t)elements[0];
    253                     status = shr_idxres_list_reserve(handle.idx_handle,
    254                                                      first,
    255                                                      last);
    256                 } else {
    257                     status = shr_idxres_list_alloc(handle.idx_handle,
    258                                                    (shr_aidxres_element_t *)elements);
    259                 }
    260             }
    261         break;
    262 
    263         case  SHR_ALLOC_STYLE_SCALED:
    264             if (flags & _SHR_RES_FLAGS_CONTIGOUS) {
    265                 status = _SHR_E_PARAM;
    266             } else {
    267                 if (flags & _SHR_RES_FLAGS_RESERVE) {
    268                     for (i = 0; i < count; i++) {
    269                         first  = (shr_aidxres_element_t)elements[i];
    270                         last   = (shr_aidxres_element_t)elements[i];
    271                         shr_idxres_list_reserve(handle.idx_handle,
    272                                                 first,
    273                                                 last);
    274                     }
    275                 } else {
    276                     if (count == 1) {
    277                         status = shr_idxres_list_alloc(handle.idx_handle,
    278                                                        (shr_aidxres_element_t *)elements);
    279                     } else {
    280                         status = shr_idxres_list_alloc_set(handle.idx_handle,
    281                                                            (shr_idxres_element_t)   count,
    282                                                            (shr_idxres_element_t *) elements,
    283                                                            (shr_idxres_element_t *) done);
    284                     }
    285                 }
    286             }
    287         break;
    288 
    289         case SHR_ALLOC_STYLE_VERSATILE:
    290             if (flags & _SHR_RES_FLAGS_RESERVE) {
    291                 if ((count == 1) || ((flags & _SHR_RES_FLAGS_CONTIGOUS))) {
    292                     first  = (shr_aidxres_element_t)elements[0];
    293                     last   = (shr_aidxres_element_t)elements[0] + count - 1;
    294                     status = shr_aidxres_list_reserve(handle.aidx_handle,
    295                                                       first,
    296                                                       last);
    297                 } else {
    298                     for (i = 0; i < count; i++) {
    299                         first  = (shr_aidxres_element_t)elements[i];
    300                         last   = (shr_aidxres_element_t)elements[i];
    301                         status = shr_aidxres_list_reserve(handle.aidx_handle,
    302                                                           first,
    303                                                           last);
    304                     }
    305                 }
    306             } else {
    307                 if (count == 1) {
    308                     status = shr_aidxres_list_alloc(handle.aidx_handle,
    309                                                     (shr_aidxres_element_t *) elements);
    310                 } else {
    311                     if (!(flags & _SHR_RES_FLAGS_CONTIGOUS)) {
    312                         status = shr_aidxres_list_alloc_set(handle.aidx_handle,
    313                                                             (shr_aidxres_element_t)   count,
    314                                                             (shr_aidxres_element_t *) elements,
    315                                                             (shr_aidxres_element_t *) done);
    316                     } else {
    317                         status = shr_aidxres_list_alloc_block(handle.aidx_handle,
    318                                                      (shr_aidxres_element_t)  count,
    319                                                      (shr_aidxres_element_t *)elements);
    320                     }
    321                 }
    322             }
    323 
    324         break;
    325     }
    326 
    327     if (done != NULL) {
    328         if (status != _SHR_E_NONE) {
    329             for (i = 0; i < count; i++) {
    330                 if (done[i]) {
    331                     if (handle.alloc_style == SHR_ALLOC_STYLE_VERSATILE) {
    332                         if(shr_aidxres_list_free(handle.aidx_handle,
    333                                                  done[i]) != _SHR_E_NONE) {
    334                             LOG_ERROR(BSL_LS_SOC_COMMON,
    335                                       (BSL_META_U(unit,
    336                                                   "shr_aidxres_list_free failed\n")));
    337                         }
    338                     } else {
    339                         if(shr_idxres_list_free(handle.idx_handle,
    340                                                 done[i]) != _SHR_E_NONE){
    341                             LOG_ERROR(BSL_LS_SOC_COMMON,
    342                                       (BSL_META_U(unit,
    343                                                   "shr_aidxres_list_free failed\n")));
    344                         }
    345                     }
    346                 }
    347             }
    348         }
    349         sal_free(done);
    350     }
    351 
    352     if (status != _SHR_E_NONE) {
    353         _SHR_RESOURCE_UNLOCK(unit);
    354         return status;
    355     }
    356 
    357     /* check and apply translators */
    358     if (res_attrs->i2e) {
    359         for (i = 0; i < count; i++) {
    360             elements[i] = res_attrs->i2e(unit, elements[i]);
    361         }
    362     }
    363 
    364     _SHR_RESOURCE_UNLOCK(unit);
    365     return _SHR_E_NONE;
    366 }
    367 
    368 /*
    369  *   Function
    370  *      _shr_resource_free
    371  *   Purpose
    372  *      Free the resources specified in the array
    373  *   Parameters
    374  *      unit    - (IN)  unit number of the device
    375  *      type    - (IN)  resource type
    376  *                      (one of _shr_usr_res_types_t)
    377  *      count   - (IN)  Number of resources to be freed
    378  *      elements- (IN)  Resource Ids to be freed
    379  *   Returns
    380  *      _SHR_E_NONE if element freed successfully
    381  *      _SHR_E_* as appropriate otherwise
    382  */
    383 
    384 int
    385 _shr_resource_free(int                        unit,
    386                        _shr_usr_res_types_t   type,
    387                        uint32                     count,
    388                        uint32                    *elements,
    389                        uint32                     flags)
    390 {
    391     _shr_res_handle_t     handle;
    392     int                       status;
    393     uint32                    i;
    394     _shr_hw_res_attrs_t *res_attrs;
    395 
    396     if ((count <= 0) || (elements == NULL)) {
    397         return _SHR_E_PARAM;
    398     }
    399 
    400     _SHR_E_IF_ERROR_RETURN(_SHR_RESOURCE_LOCK(unit));
    401 
    402     status = _shr_get_resource_handle(unit,
    403                                           type,
    404                                           &handle);
    405 
    406     if (status != _SHR_E_NONE) {
    407         _SHR_RESOURCE_UNLOCK(unit);
    408         return status;
    409     }
    410 
    411     res_attrs =  &_g_shr_res_attrs[unit][_g_mapped_hw_res[unit][type]];
    412     
    413     if (res_attrs->reservedHigh && res_attrs->reservedLow) {
    414         int inRange = 0;
    415 
    416         for (i = 0; i < count; i++) {
    417             if (elements[i] >= res_attrs->reservedLow && 
    418                 elements[i] <= res_attrs->reservedHigh) {
    419                 inRange++;
    420             }
    421         }
    422 
    423         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    424                     (BSL_META_U(unit,
    425                                 "Found a reserved range on resource %d: "
    426                                 "0x%08x-0x%08x count=%d inRange=%d\n"), 
    427                      type, res_attrs->reservedLow, res_attrs->reservedHigh,
    428                      count, inRange));
    429 
    430         if (inRange && (inRange != count)) {
    431             /* part some elements are in reserved range, but not all */
    432             _SHR_RESOURCE_UNLOCK(unit);
    433             return _SHR_E_PARAM;
    434         }
    435 
    436         /* nothing to do */
    437         if (inRange) {
    438             _SHR_RESOURCE_UNLOCK(unit);
    439             return _SHR_E_NONE;
    440         }
    441     }
    442 
    443     /* check and apply translators */
    444     if (res_attrs->e2i) {
    445         for (i = 0; i < count; i++) {
    446             elements[i] = res_attrs->e2i(unit, elements[i]);
    447         }
    448     }
    449 
    450     if ((handle.alloc_style == SHR_ALLOC_STYLE_VERSATILE) &&
    451         (flags & _SHR_RES_FLAGS_CONTIGOUS)) {
    452         status =  shr_aidxres_list_free(handle.aidx_handle,
    453                                         (shr_aidxres_element_t)elements[0]);
    454     } else {
    455         for (i = 0; i < count; i++) {
    456             if (handle.alloc_style == SHR_ALLOC_STYLE_VERSATILE) {
    457                 status = shr_aidxres_list_free(handle.aidx_handle,
    458                                                (shr_aidxres_element_t)elements[i]);
    459             } else {
    460                 status =  shr_idxres_list_free(handle.idx_handle,
    461                                                (shr_idxres_element_t)elements[i]);
    462             }
    463         }
    464     }
    465 
    466     _SHR_RESOURCE_UNLOCK(unit);
    467     return status;
    468 }
    469 
    470 /*
    471  *   Function
    472  *      _shr_resource_test
    473  *   Purpose
    474  *      Check to see if the specified resource is available
    475  *   Parameters
    476  *      unit    - (IN)  unit number of the device
    477  *      type    - (IN)  resource type
    478  *                      (one of _shr_usr_res_types_t)
    479  *      element - (IN)  Resource Id to be checked
    480  *   Returns
    481  *      _SHR_E_NOT_FOUND if resource is available
    482  *      _SHR_E_EXIST     if resource is in use
    483  *      _SHR_E_*         as appropriate otherwise
    484  */
    485 
    486 int
    487 _shr_resource_test(int                        unit,
    488                        _shr_usr_res_types_t   type,
    489                        uint32                     element)
    490 {
    491     _shr_res_handle_t     handle;
    492     int                       status;
    493     _shr_hw_res_attrs_t  *res_attrs;
    494 
    495     _SHR_E_IF_ERROR_RETURN(_SHR_RESOURCE_LOCK(unit));
    496 
    497     status = _shr_get_resource_handle(unit,
    498                                           type,
    499                                           &handle);
    500     if (status != _SHR_E_NONE) {
    501         _SHR_RESOURCE_UNLOCK(unit);
    502         return status;
    503     }
    504 
    505     res_attrs =  &_g_shr_res_attrs[unit][_g_mapped_hw_res[unit][type]];
    506 
    507     /* check and apply translators */
    508     if (res_attrs->e2i) {
    509         element = res_attrs->e2i(unit, element);
    510     }
    511 
    512     if (handle.alloc_style == SHR_ALLOC_STYLE_VERSATILE) {
    513         status = shr_aidxres_list_elem_state(handle.aidx_handle,
    514                                              (shr_aidxres_element_t)element);
    515     } else {
    516         status = shr_idxres_list_elem_state(handle.idx_handle,
    517                                             (shr_idxres_element_t)element);
    518     }
    519 
    520     _SHR_RESOURCE_UNLOCK(unit);
    521     return status;
    522 }
    523 
    524 /*
    525  *   Function
    526  *      _shr_shr_resource_uninit
    527  *   Purpose
    528  *      Destroy the all the resource managers for this unit
    529  *   Parameters
    530  *      (IN) unit   : unit number of the device
    531  *   Returns
    532  *       _SHR_E_NONE all resources are successfully destroyed
    533  *       _SHR_E_* as appropriate otherwise
    534  *   Notes
    535  *       Returns error is any of the resources cannot be destroyed
    536  */
    537 
    538 int
    539 _shr_resource_uninit(int unit)
    540 {
    541     uint32                     i;
    542     int                        status, ret;
    543     _shr_res_handle_t     *res_handle;
    544 
    545 
    546     _SHR_E_IF_ERROR_RETURN(_SHR_RESOURCE_LOCK(unit));
    547     ret = _SHR_E_NONE;
    548 
    549     for (i = SHR_HW_RES_RES0;
    550          i < SHR_HW_RES_MAX; i++) {
    551          res_handle         = &_g_shr_res_handles[unit][i];
    552          if (res_handle->alloc_style == SHR_ALLOC_STYLE_VERSATILE) {
    553              status = shr_aidxres_list_destroy(res_handle->aidx_handle);
    554          } else {
    555              status = shr_idxres_list_destroy(res_handle->idx_handle);
    556          }
    557          if (status != _SHR_E_NONE) {
    558              ret = status;
    559          }
    560     }
    561     
    562 
    563     _SHR_RESOURCE_UNLOCK(unit);
    564     if (_shr_resource_mlock[unit] != NULL) {
    565         sal_mutex_destroy(_shr_resource_mlock[unit]);
    566         _shr_resource_mlock[unit] = NULL;
    567     }
    568 
    569     /**
    570      * No use send error here.. we have destroyed the lock,
    571      * _init() needs to be done
    572      */
    573     if (ret != _SHR_E_NONE) {
    574         ret = _SHR_E_NONE;
    575     }
    576     return ret;
    577 }
    578 
    579 /*
    580  *   Function
    581  *      _shr_alloc_range_get
    582  *   Purpose
    583  *     Retrieve the range of valid IDs for the given resource
    584  *
    585  *   Parameters
    586  *      (IN)  unit   : unit number of the device
    587  *      (IN)  type   : resource to get
    588  *      (OUT) first  : first valid ID
    589  *      (OUT) last   : last valid ID
    590  *   Returns
    591  *       _SHR_E_NONE - All required resources are allocated
    592  *       _SHR_E_*    - failure
    593  *   Notes
    594  */
    595 int _shr_alloc_range_get(int unit, _shr_usr_res_types_t type,
    596                          uint32 *first, uint32 *last)
    597 {
    598     _shr_res_handle_t      *res_handle;
    599     _shr_hw_res_attrs_t    *res_attrs;
    600     _shr_hw_res_t           res;
    601     int rv = _SHR_E_NONE;
    602     uint32 validLow, validHigh, freeCount, allocCount, junk;
    603 
    604     if (type >= SHR_USR_RES_MAX) {
    605         return _SHR_E_PARAM;
    606     }
    607 
    608     res = _g_mapped_hw_res[unit][type];
    609 
    610     _SHR_E_IF_ERROR_RETURN(_SHR_RESOURCE_LOCK(unit));
    611 
    612     res_handle = &_g_shr_res_handles[unit][res];
    613     res_attrs  =  &_g_shr_res_attrs[unit][res];
    614 
    615     if (res_attrs->alloc_style == SHR_ALLOC_STYLE_VERSATILE) {
    616         rv = shr_aidxres_list_state(res_handle->u.handle_aidx,
    617                                     first, last, 
    618                                     &validLow, &validHigh, 
    619                                     &freeCount, &allocCount, &junk, &junk);
    620         
    621     } else if (res_attrs->alloc_style == SHR_ALLOC_STYLE_SCALED) {
    622         rv = shr_idxres_list_state_scaled(res_handle->u.handle_idx,
    623                                           first, last,
    624                                           &validLow, &validHigh, 
    625                                           &freeCount, &allocCount, &junk);
    626     } else { 
    627         rv = shr_idxres_list_state(res_handle->u.handle_idx,
    628                                    first, last, 
    629                                    &validLow, &validHigh, 
    630                                    &freeCount, &allocCount);
    631         
    632     }
    633 
    634     _SHR_RESOURCE_UNLOCK(unit);
    635     return rv;
    636 }
    637 
    638 
    639 /*
    640  *   Function
    641  *      _shr_range_reserve
    642  *   Purpose
    643  *     Reserve a range of IDs of a given resource
    644  *
    645  *   Parameters
    646  *      (IN)  unit   : unit number of the device
    647  *      (IN) type    : resource to set
    648  *      (IN) highOrLow  : TRUE - set Upper bounds
    649  *                      : FALSE - set lower bounds
    650  *      (IN) val    : inclusive bound to set
    651  *   Returns
    652  *       _SHR_E_NONE - All required resources are allocated
    653  *       _SHR_E_*    - failure
    654  *   Notes
    655  */
    656 int _shr_range_reserve(int unit, _shr_usr_res_types_t type,
    657                        int highOrLow, uint32 val)
    658 {
    659     _shr_res_handle_t      *res_handle;
    660     _shr_hw_res_attrs_t    *res_attrs;
    661     _shr_hw_res_t           res;
    662     int rv = _SHR_E_NONE;
    663     int clearIt = 0, reserveIt = 0;
    664     uint32 first, last;
    665 
    666     if (type >=  SHR_USR_RES_MAX) {
    667         return _SHR_E_PARAM;
    668     }
    669 
    670     res = _g_mapped_hw_res[unit][type];
    671     
    672     _SHR_E_IF_ERROR_RETURN(_SHR_RESOURCE_LOCK(unit));
    673 
    674     res_handle = &_g_shr_res_handles[unit][res];
    675     res_attrs  =  &_g_shr_res_attrs[unit][res];
    676 
    677     first = res_attrs->reservedLow;
    678     last = res_attrs->reservedHigh;
    679 
    680     /* Zero for any value, high or low, will clear the known range */
    681     if (val == 0) {
    682         clearIt = 1;
    683         res_attrs->reservedLow = 0;
    684         res_attrs->reservedHigh = 0;
    685     } else {
    686         if (highOrLow) {
    687             res_attrs->reservedHigh = val; 
    688         } else {
    689             res_attrs->reservedLow = val;
    690         }
    691 
    692         if (res_attrs->reservedHigh && res_attrs->reservedLow) {
    693             if (res_attrs->reservedHigh < res_attrs->reservedLow) {
    694                 LOG_ERROR(BSL_LS_SOC_COMMON,
    695                           (BSL_META_U(unit,
    696                                       "Upper bounds is set less than lower"
    697                                       " bounds: 0x%x < 0x%x\n"),
    698                            res_attrs->reservedHigh, res_attrs->reservedLow));
    699 
    700                 rv = _SHR_E_PARAM;
    701             } else {
    702                 reserveIt = 1;
    703             }
    704         }
    705     }
    706 
    707     if (reserveIt) {
    708         
    709         first = res_attrs->reservedLow;
    710         last = res_attrs->reservedHigh;
    711 
    712         if (res_attrs->alloc_style == SHR_ALLOC_STYLE_VERSATILE) {
    713             rv = shr_aidxres_list_reserve(res_handle->u.handle_aidx, 
    714                                           first, last);
    715         } else if (res_attrs->alloc_style == SHR_ALLOC_STYLE_SCALED) {
    716             rv = shr_idxres_list_reserve(res_handle->u.handle_idx, 
    717                                          first, last);
    718         } else { 
    719             rv = shr_idxres_list_reserve(res_handle->u.handle_idx,
    720                                          first, last);
    721         }
    722 #if 0
    723         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    724                     (BSL_META_U(unit,
    725                                 "Reserved resource %s (%d/%d) : "
    726                                 "0x%08x-0x%08x rv=%d %s\n"),
    727                      _shr_resource_to_str(type), type, res, 
    728                      first, last, rv, _SHR_ERRMSG(rv)));
    729 #endif
    730     } else if (clearIt) {
    731 
    732         if (first && last) {
    733             int elt, ignoreRv;
    734 
    735             for (elt = first; elt <= last; elt++) {
    736 
    737                 if (res_attrs->alloc_style == SHR_ALLOC_STYLE_VERSATILE) {
    738                     ignoreRv = 
    739                         shr_aidxres_list_free(res_handle->u.handle_aidx, elt);
    740                     
    741                 } else if (res_attrs->alloc_style == SHR_ALLOC_STYLE_SCALED) {
    742                     ignoreRv =
    743                         shr_idxres_list_free(res_handle->u.handle_idx, elt);
    744                 } else { 
    745                     ignoreRv = shr_idxres_list_free(res_handle->u.handle_idx, 
    746                                                     elt);
    747                 }
    748 
    749                 if (_SHR_E_FAILURE(ignoreRv)) {
    750                     LOG_VERBOSE(BSL_LS_SOC_COMMON,
    751                                 (BSL_META_U(unit,
    752                                             "failed to free element "
    753                                             "0x%08x  rv=%d %s (ignored)\n"),
    754                                  elt, ignoreRv, _SHR_ERRMSG(ignoreRv)));
    755                 }
    756             } 
    757 #if 0
    758             LOG_VERBOSE(BSL_LS_SOC_COMMON,
    759                         (BSL_META_U(unit,
    760                                     "Freed reserved resource %s (%d/%d) ids: "
    761                                     "0x%08x-0x%08x\n"),
    762                          _shr_resource_to_str(type), type, res, 
    763                          first, last));
    764 #endif
    765         }
    766     }
    767     
    768     _SHR_RESOURCE_UNLOCK(unit);
    769     return rv;
    770 }