LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - utdelete.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 125 213 58.7 %
Date: 2022-04-01 14:17:54 Functions: 6 6 100.0 %
Branches: 55 113 48.7 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /*******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: utdelete - object deletion and reference count utilities
       5                 :            :  *
       6                 :            :  ******************************************************************************/
       7                 :            : 
       8                 :            : #include <acpi/acpi.h>
       9                 :            : #include "accommon.h"
      10                 :            : #include "acinterp.h"
      11                 :            : #include "acnamesp.h"
      12                 :            : #include "acevents.h"
      13                 :            : 
      14                 :            : #define _COMPONENT          ACPI_UTILITIES
      15                 :            : ACPI_MODULE_NAME("utdelete")
      16                 :            : 
      17                 :            : /* Local prototypes */
      18                 :            : static void acpi_ut_delete_internal_obj(union acpi_operand_object *object);
      19                 :            : 
      20                 :            : static void
      21                 :            : acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action);
      22                 :            : 
      23                 :            : /*******************************************************************************
      24                 :            :  *
      25                 :            :  * FUNCTION:    acpi_ut_delete_internal_obj
      26                 :            :  *
      27                 :            :  * PARAMETERS:  object         - Object to be deleted
      28                 :            :  *
      29                 :            :  * RETURN:      None
      30                 :            :  *
      31                 :            :  * DESCRIPTION: Low level object deletion, after reference counts have been
      32                 :            :  *              updated (All reference counts, including sub-objects!)
      33                 :            :  *
      34                 :            :  ******************************************************************************/
      35                 :            : 
      36                 :     221309 : static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
      37                 :            : {
      38                 :     221309 :         void *obj_pointer = NULL;
      39                 :     221309 :         union acpi_operand_object *handler_desc;
      40                 :     221309 :         union acpi_operand_object *second_desc;
      41                 :     221309 :         union acpi_operand_object *next_desc;
      42                 :     221309 :         union acpi_operand_object *start_desc;
      43                 :     221309 :         union acpi_operand_object **last_obj_ptr;
      44                 :            : 
      45                 :     221309 :         ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object);
      46                 :            : 
      47         [ +  - ]:     221309 :         if (!object) {
      48                 :            :                 return_VOID;
      49                 :            :         }
      50                 :            : 
      51                 :            :         /*
      52                 :            :          * Must delete or free any pointers within the object that are not
      53                 :            :          * actual ACPI objects (for example, a raw buffer pointer).
      54                 :            :          */
      55   [ +  +  +  -  :     221309 :         switch (object->common.type) {
          -  -  -  +  -  
                +  -  + ]
      56                 :        220 :         case ACPI_TYPE_STRING:
      57                 :            : 
      58                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
      59                 :            :                                   "**** String %p, ptr %p\n", object,
      60                 :        220 :                                   object->string.pointer));
      61                 :            : 
      62                 :            :                 /* Free the actual string buffer */
      63                 :            : 
      64         [ +  - ]:        220 :                 if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
      65                 :            : 
      66                 :            :                         /* But only if it is NOT a pointer into an ACPI table */
      67                 :            : 
      68                 :        220 :                         obj_pointer = object->string.pointer;
      69                 :            :                 }
      70                 :            :                 break;
      71                 :            : 
      72                 :        308 :         case ACPI_TYPE_BUFFER:
      73                 :            : 
      74                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
      75                 :            :                                   "**** Buffer %p, ptr %p\n", object,
      76                 :        308 :                                   object->buffer.pointer));
      77                 :            : 
      78                 :            :                 /* Free the actual buffer */
      79                 :            : 
      80         [ +  - ]:        308 :                 if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
      81                 :            : 
      82                 :            :                         /* But only if it is NOT a pointer into an ACPI table */
      83                 :            : 
      84                 :        308 :                         obj_pointer = object->buffer.pointer;
      85                 :            :                 }
      86                 :            :                 break;
      87                 :            : 
      88                 :       8646 :         case ACPI_TYPE_PACKAGE:
      89                 :            : 
      90                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
      91                 :            :                                   " **** Package of count %X\n",
      92                 :       8646 :                                   object->package.count));
      93                 :            : 
      94                 :            :                 /*
      95                 :            :                  * Elements of the package are not handled here, they are deleted
      96                 :            :                  * separately
      97                 :            :                  */
      98                 :            : 
      99                 :            :                 /* Free the (variable length) element pointer array */
     100                 :            : 
     101                 :       8646 :                 obj_pointer = object->package.elements;
     102                 :       8646 :                 break;
     103                 :            : 
     104                 :            :                 /*
     105                 :            :                  * These objects have a possible list of notify handlers.
     106                 :            :                  * Device object also may have a GPE block.
     107                 :            :                  */
     108                 :          0 :         case ACPI_TYPE_DEVICE:
     109                 :            : 
     110         [ #  # ]:          0 :                 if (object->device.gpe_block) {
     111                 :          0 :                         (void)acpi_ev_delete_gpe_block(object->device.
     112                 :            :                                                        gpe_block);
     113                 :            :                 }
     114                 :            : 
     115                 :            :                 /*lint -fallthrough */
     116                 :            : 
     117                 :            :         case ACPI_TYPE_PROCESSOR:
     118                 :            :         case ACPI_TYPE_THERMAL:
     119                 :            : 
     120                 :            :                 /* Walk the address handler list for this object */
     121                 :            : 
     122                 :          0 :                 handler_desc = object->common_notify.handler;
     123         [ #  # ]:          0 :                 while (handler_desc) {
     124                 :          0 :                         next_desc = handler_desc->address_space.next;
     125                 :          0 :                         acpi_ut_remove_reference(handler_desc);
     126                 :          0 :                         handler_desc = next_desc;
     127                 :            :                 }
     128                 :            :                 break;
     129                 :            : 
     130                 :          0 :         case ACPI_TYPE_MUTEX:
     131                 :            : 
     132                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
     133                 :            :                                   "***** Mutex %p, OS Mutex %p\n",
     134                 :          0 :                                   object, object->mutex.os_mutex));
     135                 :            : 
     136         [ #  # ]:          0 :                 if (object == acpi_gbl_global_lock_mutex) {
     137                 :            : 
     138                 :            :                         /* Global Lock has extra semaphore */
     139                 :            : 
     140                 :          0 :                         (void)
     141                 :          0 :                             acpi_os_delete_semaphore
     142                 :            :                             (acpi_gbl_global_lock_semaphore);
     143                 :          0 :                         acpi_gbl_global_lock_semaphore = NULL;
     144                 :            : 
     145                 :          0 :                         acpi_os_delete_mutex(object->mutex.os_mutex);
     146                 :          0 :                         acpi_gbl_global_lock_mutex = NULL;
     147                 :            :                 } else {
     148                 :          0 :                         acpi_ex_unlink_mutex(object);
     149                 :          0 :                         acpi_os_delete_mutex(object->mutex.os_mutex);
     150                 :            :                 }
     151                 :            :                 break;
     152                 :            : 
     153                 :          0 :         case ACPI_TYPE_EVENT:
     154                 :            : 
     155                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
     156                 :            :                                   "***** Event %p, OS Semaphore %p\n",
     157                 :          0 :                                   object, object->event.os_semaphore));
     158                 :            : 
     159                 :          0 :                 (void)acpi_os_delete_semaphore(object->event.os_semaphore);
     160                 :          0 :                 object->event.os_semaphore = NULL;
     161                 :          0 :                 break;
     162                 :            : 
     163                 :         11 :         case ACPI_TYPE_METHOD:
     164                 :            : 
     165                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
     166                 :         11 :                                   "***** Method %p\n", object));
     167                 :            : 
     168                 :            :                 /* Delete the method mutex if it exists */
     169                 :            : 
     170         [ -  + ]:         11 :                 if (object->method.mutex) {
     171                 :          0 :                         acpi_os_delete_mutex(object->method.mutex->mutex.
     172                 :            :                                              os_mutex);
     173                 :          0 :                         acpi_ut_delete_object_desc(object->method.mutex);
     174                 :          0 :                         object->method.mutex = NULL;
     175                 :            :                 }
     176                 :            : 
     177         [ -  + ]:         11 :                 if (object->method.node) {
     178                 :          0 :                         object->method.node = NULL;
     179                 :            :                 }
     180                 :            :                 break;
     181                 :            : 
     182                 :          0 :         case ACPI_TYPE_REGION:
     183                 :            : 
     184                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
     185                 :          0 :                                   "***** Region %p\n", object));
     186                 :            : 
     187                 :            :                 /*
     188                 :            :                  * Update address_range list. However, only permanent regions
     189                 :            :                  * are installed in this list. (Not created within a method)
     190                 :            :                  */
     191         [ #  # ]:          0 :                 if (!(object->region.node->flags & ANOBJ_TEMPORARY)) {
     192                 :          0 :                         acpi_ut_remove_address_range(object->region.space_id,
     193                 :            :                                                      object->region.node);
     194                 :            :                 }
     195                 :            : 
     196                 :          0 :                 second_desc = acpi_ns_get_secondary_object(object);
     197         [ #  # ]:          0 :                 if (second_desc) {
     198                 :            :                         /*
     199                 :            :                          * Free the region_context if and only if the handler is one of the
     200                 :            :                          * default handlers -- and therefore, we created the context object
     201                 :            :                          * locally, it was not created by an external caller.
     202                 :            :                          */
     203                 :          0 :                         handler_desc = object->region.handler;
     204         [ #  # ]:          0 :                         if (handler_desc) {
     205                 :          0 :                                 next_desc =
     206                 :            :                                     handler_desc->address_space.region_list;
     207                 :          0 :                                 start_desc = next_desc;
     208                 :          0 :                                 last_obj_ptr =
     209                 :            :                                     &handler_desc->address_space.region_list;
     210                 :            : 
     211                 :            :                                 /* Remove the region object from the handler list */
     212                 :            : 
     213         [ #  # ]:          0 :                                 while (next_desc) {
     214         [ #  # ]:          0 :                                         if (next_desc == object) {
     215                 :          0 :                                                 *last_obj_ptr =
     216                 :          0 :                                                     next_desc->region.next;
     217                 :          0 :                                                 break;
     218                 :            :                                         }
     219                 :            : 
     220                 :            :                                         /* Walk the linked list of handlers */
     221                 :            : 
     222                 :          0 :                                         last_obj_ptr = &next_desc->region.next;
     223                 :          0 :                                         next_desc = next_desc->region.next;
     224                 :            : 
     225                 :            :                                         /* Prevent infinite loop if list is corrupted */
     226                 :            : 
     227         [ #  # ]:          0 :                                         if (next_desc == start_desc) {
     228                 :          0 :                                                 ACPI_ERROR((AE_INFO,
     229                 :            :                                                             "Circular region list in address handler object %p",
     230                 :            :                                                             handler_desc));
     231                 :          0 :                                                 return_VOID;
     232                 :            :                                         }
     233                 :            :                                 }
     234                 :            : 
     235         [ #  # ]:          0 :                                 if (handler_desc->address_space.handler_flags &
     236                 :            :                                     ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
     237                 :            : 
     238                 :            :                                         /* Deactivate region and free region context */
     239                 :            : 
     240         [ #  # ]:          0 :                                         if (handler_desc->address_space.setup) {
     241                 :          0 :                                                 (void)handler_desc->
     242                 :            :                                                     address_space.setup(object,
     243                 :            :                                                                         ACPI_REGION_DEACTIVATE,
     244                 :            :                                                                         handler_desc->
     245                 :            :                                                                         address_space.
     246                 :            :                                                                         context,
     247                 :            :                                                                         &second_desc->
     248                 :            :                                                                         extra.
     249                 :            :                                                                         region_context);
     250                 :            :                                         }
     251                 :            :                                 }
     252                 :            : 
     253                 :          0 :                                 acpi_ut_remove_reference(handler_desc);
     254                 :            :                         }
     255                 :            : 
     256                 :            :                         /* Now we can free the Extra object */
     257                 :            : 
     258                 :          0 :                         acpi_ut_delete_object_desc(second_desc);
     259                 :            :                 }
     260         [ #  # ]:          0 :                 if (object->field.internal_pcc_buffer) {
     261                 :          0 :                         ACPI_FREE(object->field.internal_pcc_buffer);
     262                 :            :                 }
     263                 :            : 
     264                 :            :                 break;
     265                 :            : 
     266                 :        110 :         case ACPI_TYPE_BUFFER_FIELD:
     267                 :            : 
     268                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
     269                 :        110 :                                   "***** Buffer Field %p\n", object));
     270                 :            : 
     271                 :        110 :                 second_desc = acpi_ns_get_secondary_object(object);
     272         [ +  - ]:        110 :                 if (second_desc) {
     273                 :        110 :                         acpi_ut_delete_object_desc(second_desc);
     274                 :            :                 }
     275                 :            :                 break;
     276                 :            : 
     277                 :          0 :         case ACPI_TYPE_LOCAL_BANK_FIELD:
     278                 :            : 
     279                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
     280                 :          0 :                                   "***** Bank Field %p\n", object));
     281                 :            : 
     282                 :          0 :                 second_desc = acpi_ns_get_secondary_object(object);
     283         [ #  # ]:          0 :                 if (second_desc) {
     284                 :          0 :                         acpi_ut_delete_object_desc(second_desc);
     285                 :            :                 }
     286                 :            :                 break;
     287                 :            : 
     288                 :            :         default:
     289                 :            : 
     290                 :            :                 break;
     291                 :            :         }
     292                 :            : 
     293                 :            :         /* Free any allocated memory (pointer within the object) found above */
     294                 :            : 
     295         [ +  - ]:       9284 :         if (obj_pointer) {
     296                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
     297                 :       9174 :                                   "Deleting Object Subptr %p\n", obj_pointer));
     298                 :       9174 :                 ACPI_FREE(obj_pointer);
     299                 :            :         }
     300                 :            : 
     301                 :            :         /* Now the object can be safely deleted */
     302                 :            : 
     303                 :            :         ACPI_DEBUG_PRINT_RAW((ACPI_DB_ALLOCATIONS,
     304                 :            :                               "%s: Deleting Object %p [%s]\n",
     305                 :            :                               ACPI_GET_FUNCTION_NAME, object,
     306                 :     221309 :                               acpi_ut_get_object_type_name(object)));
     307                 :            : 
     308                 :     221309 :         acpi_ut_delete_object_desc(object);
     309                 :     221309 :         return_VOID;
     310                 :            : }
     311                 :            : 
     312                 :            : /*******************************************************************************
     313                 :            :  *
     314                 :            :  * FUNCTION:    acpi_ut_delete_internal_object_list
     315                 :            :  *
     316                 :            :  * PARAMETERS:  obj_list        - Pointer to the list to be deleted
     317                 :            :  *
     318                 :            :  * RETURN:      None
     319                 :            :  *
     320                 :            :  * DESCRIPTION: This function deletes an internal object list, including both
     321                 :            :  *              simple objects and package objects
     322                 :            :  *
     323                 :            :  ******************************************************************************/
     324                 :            : 
     325                 :        187 : void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list)
     326                 :            : {
     327                 :        187 :         union acpi_operand_object **internal_obj;
     328                 :            : 
     329                 :        187 :         ACPI_FUNCTION_ENTRY();
     330                 :            : 
     331                 :            :         /* Walk the null-terminated internal list */
     332                 :            : 
     333         [ +  + ]:        902 :         for (internal_obj = obj_list; *internal_obj; internal_obj++) {
     334                 :        715 :                 acpi_ut_remove_reference(*internal_obj);
     335                 :            :         }
     336                 :            : 
     337                 :            :         /* Free the combined parameter pointer list and object array */
     338                 :            : 
     339                 :        187 :         ACPI_FREE(obj_list);
     340                 :        187 :         return;
     341                 :            : }
     342                 :            : 
     343                 :            : /*******************************************************************************
     344                 :            :  *
     345                 :            :  * FUNCTION:    acpi_ut_update_ref_count
     346                 :            :  *
     347                 :            :  * PARAMETERS:  object          - Object whose ref count is to be updated
     348                 :            :  *              action          - What to do (REF_INCREMENT or REF_DECREMENT)
     349                 :            :  *
     350                 :            :  * RETURN:      None. Sets new reference count within the object
     351                 :            :  *
     352                 :            :  * DESCRIPTION: Modify the reference count for an internal acpi object
     353                 :            :  *
     354                 :            :  ******************************************************************************/
     355                 :            : 
     356                 :            : static void
     357                 :    6206200 : acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
     358                 :            : {
     359                 :    6206200 :         u16 original_count;
     360                 :    6206200 :         u16 new_count = 0;
     361                 :    6206200 :         acpi_cpu_flags lock_flags;
     362                 :    6206200 :         char *message;
     363                 :            : 
     364                 :    6206200 :         ACPI_FUNCTION_NAME(ut_update_ref_count);
     365                 :            : 
     366         [ +  - ]:    6206200 :         if (!object) {
     367                 :            :                 return;
     368                 :            :         }
     369                 :            : 
     370                 :            :         /*
     371                 :            :          * Always get the reference count lock. Note: Interpreter and/or
     372                 :            :          * Namespace is not always locked when this function is called.
     373                 :            :          */
     374                 :    6206200 :         lock_flags = acpi_os_acquire_lock(acpi_gbl_reference_count_lock);
     375                 :    6206200 :         original_count = object->common.reference_count;
     376                 :            : 
     377                 :            :         /* Perform the reference count action (increment, decrement) */
     378                 :            : 
     379      [ +  +  - ]:    6206200 :         switch (action) {
     380                 :    2992550 :         case REF_INCREMENT:
     381                 :            : 
     382                 :    2992550 :                 new_count = original_count + 1;
     383                 :    2992550 :                 object->common.reference_count = new_count;
     384                 :    2992550 :                 acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);
     385                 :            : 
     386                 :            :                 /* The current reference count should never be zero here */
     387                 :            : 
     388         [ -  + ]:    2992550 :                 if (!original_count) {
     389                 :          0 :                         ACPI_WARNING((AE_INFO,
     390                 :            :                                       "Obj %p, Reference Count was zero before increment\n",
     391                 :            :                                       object));
     392                 :            :                 }
     393                 :            : 
     394                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
     395                 :            :                                   "Obj %p Type %.2X [%s] Refs %.2X [Incremented]\n",
     396                 :            :                                   object, object->common.type,
     397                 :            :                                   acpi_ut_get_object_type_name(object),
     398                 :            :                                   new_count));
     399                 :            :                 message = "Incremement";
     400                 :            :                 break;
     401                 :            : 
     402                 :    3213650 :         case REF_DECREMENT:
     403                 :            : 
     404                 :            :                 /* The current reference count must be non-zero */
     405                 :            : 
     406         [ +  - ]:    3213650 :                 if (original_count) {
     407                 :    3213650 :                         new_count = original_count - 1;
     408                 :    3213650 :                         object->common.reference_count = new_count;
     409                 :            :                 }
     410                 :            : 
     411                 :    3213650 :                 acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);
     412                 :            : 
     413         [ -  + ]:    3213650 :                 if (!original_count) {
     414                 :          0 :                         ACPI_WARNING((AE_INFO,
     415                 :            :                                       "Obj %p, Reference Count is already zero, cannot decrement\n",
     416                 :            :                                       object));
     417                 :            :                 }
     418                 :            : 
     419                 :            :                 ACPI_DEBUG_PRINT_RAW((ACPI_DB_ALLOCATIONS,
     420                 :            :                                       "%s: Obj %p Type %.2X Refs %.2X [Decremented]\n",
     421                 :            :                                       ACPI_GET_FUNCTION_NAME, object,
     422                 :    3213650 :                                       object->common.type, new_count));
     423                 :            : 
     424                 :            :                 /* Actually delete the object on a reference count of zero */
     425                 :            : 
     426         [ +  + ]:    3213650 :                 if (new_count == 0) {
     427                 :     221309 :                         acpi_ut_delete_internal_obj(object);
     428                 :            :                 }
     429                 :            :                 message = "Decrement";
     430                 :            :                 break;
     431                 :            : 
     432                 :          0 :         default:
     433                 :            : 
     434                 :          0 :                 acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);
     435                 :          0 :                 ACPI_ERROR((AE_INFO, "Unknown Reference Count action (0x%X)",
     436                 :            :                             action));
     437                 :          0 :                 return;
     438                 :            :         }
     439                 :            : 
     440                 :            :         /*
     441                 :            :          * Sanity check the reference count, for debug purposes only.
     442                 :            :          * (A deleted object will have a huge reference count)
     443                 :            :          */
     444         [ -  + ]:    6206200 :         if (new_count > ACPI_MAX_REFERENCE_COUNT) {
     445                 :          0 :                 ACPI_WARNING((AE_INFO,
     446                 :            :                               "Large Reference Count (0x%X) in object %p, Type=0x%.2X Operation=%s",
     447                 :            :                               new_count, object, object->common.type, message));
     448                 :            :         }
     449                 :            : }
     450                 :            : 
     451                 :            : /*******************************************************************************
     452                 :            :  *
     453                 :            :  * FUNCTION:    acpi_ut_update_object_reference
     454                 :            :  *
     455                 :            :  * PARAMETERS:  object              - Increment ref count for this object
     456                 :            :  *                                    and all sub-objects
     457                 :            :  *              action              - Either REF_INCREMENT or REF_DECREMENT
     458                 :            :  *
     459                 :            :  * RETURN:      Status
     460                 :            :  *
     461                 :            :  * DESCRIPTION: Increment the object reference count
     462                 :            :  *
     463                 :            :  * Object references are incremented when:
     464                 :            :  * 1) An object is attached to a Node (namespace object)
     465                 :            :  * 2) An object is copied (all subobjects must be incremented)
     466                 :            :  *
     467                 :            :  * Object references are decremented when:
     468                 :            :  * 1) An object is detached from an Node
     469                 :            :  *
     470                 :            :  ******************************************************************************/
     471                 :            : 
     472                 :            : acpi_status
     473                 :     474804 : acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
     474                 :            : {
     475                 :     474804 :         acpi_status status = AE_OK;
     476                 :     474804 :         union acpi_generic_state *state_list = NULL;
     477                 :     474804 :         union acpi_operand_object *next_object = NULL;
     478                 :     474804 :         union acpi_operand_object *prev_object;
     479                 :     474804 :         union acpi_generic_state *state;
     480                 :     474804 :         u32 i;
     481                 :            : 
     482                 :     474804 :         ACPI_FUNCTION_NAME(ut_update_object_reference);
     483                 :            : 
     484         [ +  - ]:    3217060 :         while (object) {
     485                 :            : 
     486                 :            :                 /* Make sure that this isn't a namespace handle */
     487                 :            : 
     488         [ +  - ]:    2742256 :                 if (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) {
     489                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
     490                 :            :                                           "Object %p is NS handle\n", object));
     491                 :            :                         return (AE_OK);
     492                 :            :                 }
     493                 :            : 
     494                 :            :                 /*
     495                 :            :                  * All sub-objects must have their reference count incremented
     496                 :            :                  * also. Different object types have different subobjects.
     497                 :            :                  */
     498   [ +  +  +  +  :    2742256 :                 switch (object->common.type) {
             -  -  +  + ]
     499                 :            :                 case ACPI_TYPE_DEVICE:
     500                 :            :                 case ACPI_TYPE_PROCESSOR:
     501                 :            :                 case ACPI_TYPE_POWER:
     502                 :            :                 case ACPI_TYPE_THERMAL:
     503                 :            :                         /*
     504                 :            :                          * Update the notify objects for these types (if present)
     505                 :            :                          * Two lists, system and device notify handlers.
     506                 :            :                          */
     507         [ +  + ]:        924 :                         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
     508                 :        616 :                                 prev_object =
     509                 :            :                                     object->common_notify.notify_list[i];
     510         [ -  + ]:        616 :                                 while (prev_object) {
     511                 :          0 :                                         next_object =
     512                 :            :                                             prev_object->notify.next[i];
     513                 :          0 :                                         acpi_ut_update_ref_count(prev_object,
     514                 :            :                                                                  action);
     515                 :          0 :                                         prev_object = next_object;
     516                 :            :                                 }
     517                 :            :                         }
     518                 :            :                         break;
     519                 :            : 
     520                 :            :                 case ACPI_TYPE_PACKAGE:
     521                 :            :                         /*
     522                 :            :                          * We must update all the sub-objects of the package,
     523                 :            :                          * each of whom may have their own sub-objects.
     524                 :            :                          */
     525         [ +  + ]:    7975660 :                         for (i = 0; i < object->package.count; i++) {
     526                 :            :                                 /*
     527                 :            :                                  * Null package elements are legal and can be simply
     528                 :            :                                  * ignored.
     529                 :            :                                  */
     530                 :    6803720 :                                 next_object = object->package.elements[i];
     531         [ +  + ]:    6803720 :                                 if (!next_object) {
     532                 :    1098240 :                                         continue;
     533                 :            :                                 }
     534                 :            : 
     535         [ +  + ]:    5705480 :                                 switch (next_object->common.type) {
     536                 :    3463944 :                                 case ACPI_TYPE_INTEGER:
     537                 :            :                                 case ACPI_TYPE_STRING:
     538                 :            :                                 case ACPI_TYPE_BUFFER:
     539                 :            :                                         /*
     540                 :            :                                          * For these very simple sub-objects, we can just
     541                 :            :                                          * update the reference count here and continue.
     542                 :            :                                          * Greatly increases performance of this operation.
     543                 :            :                                          */
     544                 :    3463944 :                                         acpi_ut_update_ref_count(next_object,
     545                 :            :                                                                  action);
     546                 :    3463944 :                                         break;
     547                 :            : 
     548                 :    2241536 :                                 default:
     549                 :            :                                         /*
     550                 :            :                                          * For complex sub-objects, push them onto the stack
     551                 :            :                                          * for later processing (this eliminates recursion.)
     552                 :            :                                          */
     553                 :    2241536 :                                         status =
     554                 :    2241536 :                                             acpi_ut_create_update_state_and_push
     555                 :            :                                             (next_object, action, &state_list);
     556         [ -  + ]:    2241536 :                                         if (ACPI_FAILURE(status)) {
     557                 :          0 :                                                 goto error_exit;
     558                 :            :                                         }
     559                 :            :                                         break;
     560                 :            :                                 }
     561                 :            :                         }
     562                 :            :                         next_object = NULL;
     563                 :            :                         break;
     564                 :            : 
     565                 :        330 :                 case ACPI_TYPE_BUFFER_FIELD:
     566                 :            : 
     567                 :        330 :                         next_object = object->buffer_field.buffer_obj;
     568                 :        330 :                         break;
     569                 :            : 
     570                 :        462 :                 case ACPI_TYPE_LOCAL_REGION_FIELD:
     571                 :            : 
     572                 :        462 :                         next_object = object->field.region_obj;
     573                 :        462 :                         break;
     574                 :            : 
     575                 :          0 :                 case ACPI_TYPE_LOCAL_BANK_FIELD:
     576                 :            : 
     577                 :          0 :                         next_object = object->bank_field.bank_obj;
     578                 :          0 :                         status =
     579                 :          0 :                             acpi_ut_create_update_state_and_push(object->
     580                 :            :                                                                  bank_field.
     581                 :            :                                                                  region_obj,
     582                 :            :                                                                  action,
     583                 :            :                                                                  &state_list);
     584         [ #  # ]:          0 :                         if (ACPI_FAILURE(status)) {
     585                 :          0 :                                 goto error_exit;
     586                 :            :                         }
     587                 :            :                         break;
     588                 :            : 
     589                 :          0 :                 case ACPI_TYPE_LOCAL_INDEX_FIELD:
     590                 :            : 
     591                 :          0 :                         next_object = object->index_field.index_obj;
     592                 :          0 :                         status =
     593                 :          0 :                             acpi_ut_create_update_state_and_push(object->
     594                 :            :                                                                  index_field.
     595                 :            :                                                                  data_obj,
     596                 :            :                                                                  action,
     597                 :            :                                                                  &state_list);
     598         [ #  # ]:          0 :                         if (ACPI_FAILURE(status)) {
     599                 :          0 :                                 goto error_exit;
     600                 :            :                         }
     601                 :            :                         break;
     602                 :            : 
     603                 :    1240932 :                 case ACPI_TYPE_LOCAL_REFERENCE:
     604                 :            :                         /*
     605                 :            :                          * The target of an Index (a package, string, or buffer) or a named
     606                 :            :                          * reference must track changes to the ref count of the index or
     607                 :            :                          * target object.
     608                 :            :                          */
     609         [ +  + ]:    1240932 :                         if ((object->reference.class == ACPI_REFCLASS_INDEX) ||
     610                 :            :                             (object->reference.class == ACPI_REFCLASS_NAME)) {
     611                 :    1179904 :                                 next_object = object->reference.object;
     612                 :            :                         }
     613                 :            :                         break;
     614                 :            : 
     615                 :            :                 case ACPI_TYPE_REGION:
     616                 :            :                 default:
     617                 :            : 
     618                 :            :                         break;  /* No subobjects for all other types */
     619                 :            :                 }
     620                 :            : 
     621                 :            :                 /*
     622                 :            :                  * Now we can update the count in the main object. This can only
     623                 :            :                  * happen after we update the sub-objects in case this causes the
     624                 :            :                  * main object to be deleted.
     625                 :            :                  */
     626                 :    2742256 :                 acpi_ut_update_ref_count(object, action);
     627                 :    2742256 :                 object = NULL;
     628                 :            : 
     629                 :            :                 /* Move on to the next object to be updated */
     630                 :            : 
     631         [ +  + ]:    2742256 :                 if (next_object) {
     632                 :            :                         object = next_object;
     633                 :            :                         next_object = NULL;
     634         [ +  + ]:    2716340 :                 } else if (state_list) {
     635                 :    2241536 :                         state = acpi_ut_pop_generic_state(&state_list);
     636                 :    2241536 :                         object = state->update.object;
     637                 :    2241536 :                         acpi_ut_delete_generic_state(state);
     638                 :            :                 }
     639                 :            :         }
     640                 :            : 
     641                 :            :         return (AE_OK);
     642                 :            : 
     643                 :          0 : error_exit:
     644                 :            : 
     645                 :          0 :         ACPI_EXCEPTION((AE_INFO, status,
     646                 :            :                         "Could not update object reference count"));
     647                 :            : 
     648                 :            :         /* Free any stacked Update State objects */
     649                 :            : 
     650         [ #  # ]:          0 :         while (state_list) {
     651                 :          0 :                 state = acpi_ut_pop_generic_state(&state_list);
     652                 :          0 :                 acpi_ut_delete_generic_state(state);
     653                 :            :         }
     654                 :            : 
     655                 :            :         return (status);
     656                 :            : }
     657                 :            : 
     658                 :            : /*******************************************************************************
     659                 :            :  *
     660                 :            :  * FUNCTION:    acpi_ut_add_reference
     661                 :            :  *
     662                 :            :  * PARAMETERS:  object          - Object whose reference count is to be
     663                 :            :  *                                incremented
     664                 :            :  *
     665                 :            :  * RETURN:      None
     666                 :            :  *
     667                 :            :  * DESCRIPTION: Add one reference to an ACPI object
     668                 :            :  *
     669                 :            :  ******************************************************************************/
     670                 :            : 
     671                 :     157872 : void acpi_ut_add_reference(union acpi_operand_object *object)
     672                 :            : {
     673                 :            : 
     674                 :     157872 :         ACPI_FUNCTION_NAME(ut_add_reference);
     675                 :            : 
     676                 :            :         /* Ensure that we have a valid object */
     677                 :            : 
     678         [ +  + ]:     157872 :         if (!acpi_ut_valid_internal_object(object)) {
     679                 :            :                 return;
     680                 :            :         }
     681                 :            : 
     682                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
     683                 :            :                           "Obj %p Current Refs=%X [To Be Incremented]\n",
     684                 :     152240 :                           object, object->common.reference_count));
     685                 :            : 
     686                 :            :         /* Increment the reference count */
     687                 :            : 
     688                 :     152240 :         (void)acpi_ut_update_object_reference(object, REF_INCREMENT);
     689                 :     152240 :         return;
     690                 :            : }
     691                 :            : 
     692                 :            : /*******************************************************************************
     693                 :            :  *
     694                 :            :  * FUNCTION:    acpi_ut_remove_reference
     695                 :            :  *
     696                 :            :  * PARAMETERS:  object         - Object whose ref count will be decremented
     697                 :            :  *
     698                 :            :  * RETURN:      None
     699                 :            :  *
     700                 :            :  * DESCRIPTION: Decrement the reference count of an ACPI internal object
     701                 :            :  *
     702                 :            :  ******************************************************************************/
     703                 :            : 
     704                 :     340076 : void acpi_ut_remove_reference(union acpi_operand_object *object)
     705                 :            : {
     706                 :            : 
     707                 :     340076 :         ACPI_FUNCTION_NAME(ut_remove_reference);
     708                 :            : 
     709                 :            :         /*
     710                 :            :          * Allow a NULL pointer to be passed in, just ignore it. This saves
     711                 :            :          * each caller from having to check. Also, ignore NS nodes.
     712                 :            :          */
     713         [ +  + ]:     340076 :         if (!object ||
     714         [ +  + ]:     322729 :             (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED)) {
     715                 :            :                 return;
     716                 :            :         }
     717                 :            : 
     718                 :            :         /* Ensure that we have a valid object */
     719                 :            : 
     720         [ +  - ]:     322542 :         if (!acpi_ut_valid_internal_object(object)) {
     721                 :            :                 return;
     722                 :            :         }
     723                 :            : 
     724                 :            :         ACPI_DEBUG_PRINT_RAW((ACPI_DB_ALLOCATIONS,
     725                 :            :                               "%s: Obj %p Current Refs=%X [To Be Decremented]\n",
     726                 :            :                               ACPI_GET_FUNCTION_NAME, object,
     727                 :     322542 :                               object->common.reference_count));
     728                 :            : 
     729                 :            :         /*
     730                 :            :          * Decrement the reference count, and only actually delete the object
     731                 :            :          * if the reference count becomes 0. (Must also decrement the ref count
     732                 :            :          * of all subobjects!)
     733                 :            :          */
     734                 :     322542 :         (void)acpi_ut_update_object_reference(object, REF_DECREMENT);
     735                 :     322542 :         return;
     736                 :            : }

Generated by: LCOV version 1.14