CTC++ Coverage Report - Execution Profile    #274/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/acpi/utilities/utdelete.c
Instrumentation mode: function-decision-multicondition
TER: 62 % ( 79/128)

Start/ End/    
True False - Line Source

  1 /*******************************************************************************
  2  *
  3  * Module Name: utdelete - object deletion and reference count utilities
  4  *
  5  ******************************************************************************/
  6 
  7 /*
  8  * Copyright (C) 2000 - 2006, R. Byron Moore
  9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 #include <acpi/acpi.h>
  45 #include <acpi/acinterp.h>
  46 #include <acpi/acnamesp.h>
  47 #include <acpi/acevents.h>
  48 #include <acpi/amlcode.h>
  49 
  50 #define _COMPONENT          ACPI_UTILITIES
  51 ACPI_MODULE_NAME("utdelete")
  52 
  53 /* Local prototypes */
  54 static void acpi_ut_delete_internal_obj(union acpi_operand_object *object);
  55 
  56 static void
  57 acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action);
  58 
  59 /*******************************************************************************
  60  *
  61  * FUNCTION:    acpi_ut_delete_internal_obj
  62  *
  63  * PARAMETERS:  Object         - Object to be deleted
  64  *
  65  * RETURN:      None
  66  *
  67  * DESCRIPTION: Low level object deletion, after reference counts have been
  68  *              updated (All reference counts, including sub-objects!)
  69  *
  70  ******************************************************************************/
  71 
 
1344E3   72 static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
  73 {
  74    void *obj_pointer = NULL;
  75    union acpi_operand_object *handler_desc;
  76    union acpi_operand_object *second_desc;
  77    union acpi_operand_object *next_desc;
  78 
  79    ACPI_FUNCTION_TRACE_PTR("ut_delete_internal_obj", object);
  80 
1344E3 - 81    if (!object) {
 - 82       return_VOID;
  83    }
  84 
  85    /*
  86     * Must delete or free any pointers within the object that are not
  87     * actual ACPI objects (for example, a raw buffer pointer).
  88     */
    89    switch (ACPI_GET_OBJECT_TYPE(object)) {
21432    90    case ACPI_TYPE_STRING:
  91 
  92       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  93               "**** String %p, ptr %p\n", object,
  94               object->string.pointer));
  95 
  96       /* Free the actual string buffer */
  97 
21432 - 98       if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
  99          /* But only if it is NOT a pointer into an ACPI table */
  100 
  101          obj_pointer = object->string.pointer;
  102       }
21432    103       break;
  104 
7332    105    case ACPI_TYPE_BUFFER:
  106 
  107       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  108               "**** Buffer %p, ptr %p\n", object,
  109               object->buffer.pointer));
  110 
  111       /* Free the actual buffer */
  112 
7332 - 113       if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
  114          /* But only if it is NOT a pointer into an ACPI table */
  115 
  116          obj_pointer = object->buffer.pointer;
  117       }
7332    118       break;
  119 
   120    case ACPI_TYPE_PACKAGE:
  121 
  122       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  123               " **** Package of count %X\n",
  124               object->package.count));
  125 
  126       /*
  127        * Elements of the package are not handled here, they are deleted
  128        * separately
  129        */
  130 
  131       /* Free the (variable length) element pointer array */
  132 
  133       obj_pointer = object->package.elements;
   134       break;
  135 
 - 136    case ACPI_TYPE_DEVICE:
  137 
- 138       if (object->device.gpe_block) {
  139          (void)acpi_ev_delete_gpe_block(object->device.
  140                          gpe_block);
  141       }
  142 
  143       /* Walk the handler list for this device */
  144 
  145       handler_desc = object->device.handler;
- 146       while (handler_desc) {
  147          next_desc = handler_desc->address_space.next;
  148          acpi_ut_remove_reference(handler_desc);
  149          handler_desc = next_desc;
  150       }
 - 151       break;
  152 
 - 153    case ACPI_TYPE_MUTEX:
  154 
  155       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  156               "***** Mutex %p, Semaphore %p\n",
  157               object, object->mutex.semaphore));
  158 
  159       acpi_ex_unlink_mutex(object);
  160       (void)acpi_os_delete_semaphore(object->mutex.semaphore);
 - 161       break;
  162 
 - 163    case ACPI_TYPE_EVENT:
  164 
  165       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  166               "***** Event %p, Semaphore %p\n",
  167               object, object->event.semaphore));
  168 
  169       (void)acpi_os_delete_semaphore(object->event.semaphore);
  170       object->event.semaphore = NULL;
 - 171       break;
  172 
 - 173    case ACPI_TYPE_METHOD:
  174 
  175       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  176               "***** Method %p\n", object));
  177 
  178       /* Delete the method semaphore if it exists */
  179 
- 180       if (object->method.semaphore) {
  181          (void)acpi_os_delete_semaphore(object->method.
  182                          semaphore);
  183          object->method.semaphore = NULL;
  184       }
 - 185       break;
  186 
 - 187    case ACPI_TYPE_REGION:
  188 
  189       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  190               "***** Region %p\n", object));
  191 
  192       second_desc = acpi_ns_get_secondary_object(object);
- 193       if (second_desc) {
  194          /*
  195           * Free the region_context if and only if the handler is one of the
  196           * default handlers -- and therefore, we created the context object
  197           * locally, it was not created by an external caller.
  198           */
  199          handler_desc = object->region.handler;
- 200          if (handler_desc) {
  201             if (handler_desc->address_space.
  202                 hflags &
- 203                 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
  204                obj_pointer =
  205                    second_desc->extra.region_context;
  206             }
  207 
  208             acpi_ut_remove_reference(handler_desc);
  209          }
  210 
  211          /* Now we can free the Extra object */
  212 
  213          acpi_ut_delete_object_desc(second_desc);
  214       }
 - 215       break;
  216 
726    217    case ACPI_TYPE_BUFFER_FIELD:
  218 
  219       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  220               "***** Buffer Field %p\n", object));
  221 
  222       second_desc = acpi_ns_get_secondary_object(object);
726 - 223       if (second_desc) {
  224          acpi_ut_delete_object_desc(second_desc);
  225       }
726    226       break;
  227 
1315E3    228    default:
1315E3    229       break;
  230    }
  231 
  232    /* Free any allocated memory (pointer within the object) found above */
  233 
7338 1337E3   234    if (obj_pointer) {
  235       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  236               "Deleting Object Subptr %p\n", obj_pointer));
  237       ACPI_MEM_FREE(obj_pointer);
  238    }
  239 
  240    /* Now the object can be safely deleted */
  241 
  242    ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
  243            object, acpi_ut_get_object_type_name(object)));
  244 
  245    acpi_ut_delete_object_desc(object);
1344E3    246    return_VOID;
  247 }
  248 
  249 /*******************************************************************************
  250  *
  251  * FUNCTION:    acpi_ut_delete_internal_object_list
  252  *
  253  * PARAMETERS:  obj_list        - Pointer to the list to be deleted
  254  *
  255  * RETURN:      None
  256  *
  257  * DESCRIPTION: This function deletes an internal object list, including both
  258  *              simple objects and package objects
  259  *
  260  ******************************************************************************/
  261 
 
12   262 void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list)
  263 {
  264    union acpi_operand_object **internal_obj;
  265 
  266    ACPI_FUNCTION_TRACE("ut_delete_internal_object_list");
  267 
  268    /* Walk the null-terminated internal list */
  269 
12 12   270    for (internal_obj = obj_list; *internal_obj; internal_obj++) {
  271       acpi_ut_remove_reference(*internal_obj);
  272    }
  273 
  274    /* Free the combined parameter pointer list and object array */
  275 
  276    ACPI_MEM_FREE(obj_list);
12    277    return_VOID;
  278 }
  279 
  280 /*******************************************************************************
  281  *
  282  * FUNCTION:    acpi_ut_update_ref_count
  283  *
  284  * PARAMETERS:  Object          - Object whose ref count is to be updated
  285  *              Action          - What to do
  286  *
  287  * RETURN:      New ref count
  288  *
  289  * DESCRIPTION: Modify the ref count and return it.
  290  *
  291  ******************************************************************************/
  292 
  293 static void
 
3884E3   294 acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
  295 {
  296    u16 count;
  297    u16 new_count;
  298 
  299    ACPI_FUNCTION_NAME("ut_update_ref_count");
  300 
288 3884E3   301    if (!object) {
288    302       return;
  303    }
  304 
  305    count = object->common.reference_count;
  306    new_count = count;
  307 
  308    /*
  309     * Perform the reference count action
  310     * (increment, decrement, or force delete)
  311     */
    312    switch (action) {
  313 
1270E3    314    case REF_INCREMENT:
  315 
  316       new_count++;
  317       object->common.reference_count = new_count;
  318 
  319       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  320               "Obj %p Refs=%X, [Incremented]\n",
  321               object, new_count));
1270E3    322       break;
  323 
2614E3    324    case REF_DECREMENT:
  325 
2614E3 - 326       if (count < 1) {
  327          ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  328                  "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
  329                  object, new_count));
  330 
  331          new_count = 0;
    332       } else {
  333          new_count--;
  334 
  335          ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  336                  "Obj %p Refs=%X, [Decremented]\n",
  337                  object, new_count));
  338       }
  339 
1044 2613E3   340       if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) {
  341          ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  342                  "Method Obj %p Refs=%X, [Decremented]\n",
  343                  object, new_count));
  344       }
  345 
  346       object->common.reference_count = new_count;
1344E3 1269E3   347       if (new_count == 0) {
  348          acpi_ut_delete_internal_obj(object);
  349       }
  350 
2614E3    351       break;
  352 
 - 353    case REF_FORCE_DELETE:
  354 
  355       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  356               "Obj %p Refs=%X, Force delete! (Set to 0)\n",
  357               object, count));
  358 
  359       new_count = 0;
  360       object->common.reference_count = new_count;
  361       acpi_ut_delete_internal_obj(object);
 - 362       break;
  363 
 - 364    default:
  365 
  366       ACPI_ERROR((AE_INFO, "Unknown action (%X)", action));
 - 367       break;
  368    }
  369 
  370    /*
  371     * Sanity check the reference count, for debug purposes only.
  372     * (A deleted object will have a huge reference count)
  373     */
3884E3 - 374    if (count > ACPI_MAX_REFERENCE_COUNT) {
  375 
  376       ACPI_WARNING((AE_INFO,
  377                "Large Reference Count (%X) in object %p",
  378                count, object));
  379    }
  380 
3884E3    381    return;
  382 }
  383 
  384 /*******************************************************************************
  385  *
  386  * FUNCTION:    acpi_ut_update_object_reference
  387  *
  388  * PARAMETERS:  Object              - Increment ref count for this object
  389  *                                    and all sub-objects
  390  *              Action              - Either REF_INCREMENT or REF_DECREMENT or
  391  *                                    REF_FORCE_DELETE
  392  *
  393  * RETURN:      Status
  394  *
  395  * DESCRIPTION: Increment the object reference count
  396  *
  397  * Object references are incremented when:
  398  * 1) An object is attached to a Node (namespace object)
  399  * 2) An object is copied (all subobjects must be incremented)
  400  *
  401  * Object references are decremented when:
  402  * 1) An object is detached from an Node
  403  *
  404  ******************************************************************************/
  405 
  406 acpi_status
 
3518E3   407 acpi_ut_update_object_reference(union acpi_operand_object * object, u16 action)
  408 {
  409    acpi_status status = AE_OK;
  410    union acpi_generic_state *state_list = NULL;
  411    union acpi_operand_object *next_object = NULL;
  412    union acpi_generic_state *state;
  413    acpi_native_uint i;
  414 
  415    ACPI_FUNCTION_TRACE_PTR("ut_update_object_reference", object);
  416 
3884E3 3518E3   417    while (object) {
  418       /* Make sure that this isn't a namespace handle */
  419 
3884E3 - 420       if (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) {
  421          ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
  422                  "Object %p is NS handle\n", object));
 - 423          return_ACPI_STATUS(AE_OK);
  424       }
  425 
  426       /*
  427        * All sub-objects must have their reference count incremented also.
  428        * Different object types have different subobjects.
  429        */
    430       switch (ACPI_GET_OBJECT_TYPE(object)) {
144    431       case ACPI_TYPE_DEVICE:
  432 
  433          acpi_ut_update_ref_count(object->device.system_notify,
  434                    action);
  435          acpi_ut_update_ref_count(object->device.device_notify,
  436                    action);
144    437          break;
  438 
69996    439       case ACPI_TYPE_PACKAGE:
  440          /*
  441           * We must update all the sub-objects of the package,
  442           * each of whom may have their own sub-objects.
  443           */
338754 69996   444          for (i = 0; i < object->package.count; i++) {
  445             /*
  446              * Push each element onto the stack for later processing.
  447              * Note: There can be null elements within the package,
  448              * these are simply ignored
  449              */
  450             status =
  451                 acpi_ut_create_update_state_and_push
  452                 (object->package.elements[i], action,
  453                  &state_list);
338754 - 454             if (ACPI_FAILURE(status)) {
 - 455                goto error_exit;
  456             }
  457          }
69996    458          break;
  459 
2178    460       case ACPI_TYPE_BUFFER_FIELD:
  461 
  462          next_object = object->buffer_field.buffer_obj;
2178    463          break;
  464 
2700    465       case ACPI_TYPE_LOCAL_REGION_FIELD:
  466 
  467          next_object = object->field.region_obj;
2700    468          break;
  469 
 - 470       case ACPI_TYPE_LOCAL_BANK_FIELD:
  471 
  472          next_object = object->bank_field.bank_obj;
  473          status =
  474              acpi_ut_create_update_state_and_push(object->
  475                          bank_field.
  476                          region_obj,
  477                          action,
  478                          &state_list);
- 479          if (ACPI_FAILURE(status)) {
 - 480             goto error_exit;
  481          }
 - 482          break;
  483 
144    484       case ACPI_TYPE_LOCAL_INDEX_FIELD:
  485 
  486          next_object = object->index_field.index_obj;
  487          status =
  488              acpi_ut_create_update_state_and_push(object->
  489                          index_field.
  490                          data_obj,
  491                          action,
  492                          &state_list);
144 - 493          if (ACPI_FAILURE(status)) {
 - 494             goto error_exit;
  495          }
144    496          break;
  497 
633693    498       case ACPI_TYPE_LOCAL_REFERENCE:
  499          /*
  500           * The target of an Index (a package, string, or buffer) must track
  501           * changes to the ref count of the index.
  502           */
23349 610344   503          if (object->reference.opcode == AML_INDEX_OP) {
  504             next_object = object->reference.object;
  505          }
633693    506          break;
  507 
3978    508       case ACPI_TYPE_REGION:
3171E3    509       default:
3175E3    510          break;   /* No subobjects */
  511       }
  512 
  513       /*
  514        * Now we can update the count in the main object.  This can only
  515        * happen after we update the sub-objects in case this causes the
  516        * main object to be deleted.
  517        */
  518       acpi_ut_update_ref_count(object, action);
  519       object = NULL;
  520 
  521       /* Move on to the next object to be updated */
  522 
26919 3857E3   523       if (next_object) {
  524          object = next_object;
  525          next_object = NULL;
338898 3518E3   526       } else if (state_list) {
  527          state = acpi_ut_pop_generic_state(&state_list);
  528          object = state->update.object;
  529          acpi_ut_delete_generic_state(state);
  530       }
  531    }
  532 
3518E3    533    return_ACPI_STATUS(AE_OK);
  534 
  535       error_exit:
  536 
  537    ACPI_EXCEPTION((AE_INFO, status,
  538          "Could not update object reference count"));
  539 
 - 540    return_ACPI_STATUS(status);
  541 }
  542 
  543 /*******************************************************************************
  544  *
  545  * FUNCTION:    acpi_ut_add_reference
  546  *
  547  * PARAMETERS:  Object          - Object whose reference count is to be
  548  *                                incremented