1 /******************************************************************************* 2 * 3 * Module Name: utdelete - object deletion and reference count utilities 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2008, Intel Corp. 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 "accommon.h" 46 #include "acinterp.h" 47 #include "acnamesp.h" 48 #include "acevents.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 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 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 (object->common.type) { 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 98 if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) { 99 100 /* But only if it is NOT a pointer into an ACPI table */ 101 102 obj_pointer = object->string.pointer; 103 } 104 break; 105 106 case ACPI_TYPE_BUFFER: 107 108 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 109 "**** Buffer %p, ptr %p\n", object, 110 object->buffer.pointer)); 111 112 /* Free the actual buffer */ 113 114 if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) { 115 116 /* But only if it is NOT a pointer into an ACPI table */ 117 118 obj_pointer = object->buffer.pointer; 119 } 120 break; 121 122 case ACPI_TYPE_PACKAGE: 123 124 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 125 " **** Package of count %X\n", 126 object->package.count)); 127 128 /* 129 * Elements of the package are not handled here, they are deleted 130 * separately 131 */ 132 133 /* Free the (variable length) element pointer array */ 134 135 obj_pointer = object->package.elements; 136 break; 137 138 /* 139 * These objects have a possible list of notify handlers. 140 * Device object also may have a GPE block. 141 */ 142 case ACPI_TYPE_DEVICE: 143 144 if (object->device.gpe_block) { 145 (void)acpi_ev_delete_gpe_block(object->device. 146 gpe_block); 147 } 148 149 /*lint -fallthrough */ 150 151 case ACPI_TYPE_PROCESSOR: 152 case ACPI_TYPE_THERMAL: 153 154 /* Walk the notify handler list for this object */ 155 156 handler_desc = object->common_notify.handler; 157 while (handler_desc) { 158 next_desc = handler_desc->address_space.next; 159 acpi_ut_remove_reference(handler_desc); 160 handler_desc = next_desc; 161 } 162 break; 163 164 case ACPI_TYPE_MUTEX: 165 166 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 167 "***** Mutex %p, OS Mutex %p\n", 168 object, object->mutex.os_mutex)); 169 170 if (object == acpi_gbl_global_lock_mutex) { 171 172 /* Global Lock has extra semaphore */ 173 174 (void) 175 acpi_os_delete_semaphore 176 (acpi_gbl_global_lock_semaphore); 177 acpi_gbl_global_lock_semaphore = NULL; 178 179 acpi_os_delete_mutex(object->mutex.os_mutex); 180 acpi_gbl_global_lock_mutex = NULL; 181 } else { 182 acpi_ex_unlink_mutex(object); 183 acpi_os_delete_mutex(object->mutex.os_mutex); 184 } 185 break; 186 187 case ACPI_TYPE_EVENT: 188 189 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 190 "***** Event %p, OS Semaphore %p\n", 191 object, object->event.os_semaphore)); 192 193 (void)acpi_os_delete_semaphore(object->event.os_semaphore); 194 object->event.os_semaphore = NULL; 195 break; 196 197 case ACPI_TYPE_METHOD: 198 199 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 200 "***** Method %p\n", object)); 201 202 /* Delete the method mutex if it exists */ 203 204 if (object->method.mutex) { 205 acpi_os_delete_mutex(object->method.mutex->mutex. 206 os_mutex); 207 acpi_ut_delete_object_desc(object->method.mutex); 208 object->method.mutex = NULL; 209 } 210 break; 211 212 case ACPI_TYPE_REGION: 213 214 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 215 "***** Region %p\n", object)); 216 217 second_desc = acpi_ns_get_secondary_object(object); 218 if (second_desc) { 219 /* 220 * Free the region_context if and only if the handler is one of the 221 * default handlers -- and therefore, we created the context object 222 * locally, it was not created by an external caller. 223 */ 224 handler_desc = object->region.handler; 225 if (handler_desc) { 226 if (handler_desc->address_space.handler_flags & 227 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { 228 229 /* Deactivate region and free region context */ 230 231 if (handler_desc->address_space.setup) { 232 (void)handler_desc-> 233 address_space.setup(object, 234 ACPI_REGION_DEACTIVATE, 235 handler_desc-> 236 address_space. 237 context, 238 &second_desc-> 239 extra. 240 region_context); 241 } 242 } 243 244 acpi_ut_remove_reference(handler_desc); 245 } 246 247 /* Now we can free the Extra object */ 248 249 acpi_ut_delete_object_desc(second_desc); 250 } 251 break; 252 253 case ACPI_TYPE_BUFFER_FIELD: 254 255 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 256 "***** Buffer Field %p\n", object)); 257 258 second_desc = acpi_ns_get_secondary_object(object); 259 if (second_desc) { 260 acpi_ut_delete_object_desc(second_desc); 261 } 262 break; 263 264 case ACPI_TYPE_LOCAL_BANK_FIELD: 265 266 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 267 "***** Bank Field %p\n", object)); 268 269 second_desc = acpi_ns_get_secondary_object(object); 270 if (second_desc) { 271 acpi_ut_delete_object_desc(second_desc); 272 } 273 break; 274 275 default: 276 break; 277 } 278 279 /* Free any allocated memory (pointer within the object) found above */ 280 281 if (obj_pointer) { 282 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 283 "Deleting Object Subptr %p\n", obj_pointer)); 284 ACPI_FREE(obj_pointer); 285 } 286 287 /* Now the object can be safely deleted */ 288 289 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n", 290 object, acpi_ut_get_object_type_name(object))); 291 292 acpi_ut_delete_object_desc(object); 293 return_VOID; 294 } 295 296 /******************************************************************************* 297 * 298 * FUNCTION: acpi_ut_delete_internal_object_list 299 * 300 * PARAMETERS: obj_list - Pointer to the list to be deleted 301 * 302 * RETURN: None 303 * 304 * DESCRIPTION: This function deletes an internal object list, including both 305 * simple objects and package objects 306 * 307 ******************************************************************************/ 308 309 void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list) 310 { 311 union acpi_operand_object **internal_obj; 312 313 ACPI_FUNCTION_TRACE(ut_delete_internal_object_list); 314 315 /* Walk the null-terminated internal list */ 316 317 for (internal_obj = obj_list; *internal_obj; internal_obj++) { 318 acpi_ut_remove_reference(*internal_obj); 319 } 320 321 /* Free the combined parameter pointer list and object array */ 322 323 ACPI_FREE(obj_list); 324 return_VOID; 325 } 326 327 /******************************************************************************* 328 * 329 * FUNCTION: acpi_ut_update_ref_count 330 * 331 * PARAMETERS: Object - Object whose ref count is to be updated 332 * Action - What to do 333 * 334 * RETURN: New ref count 335 * 336 * DESCRIPTION: Modify the ref count and return it. 337 * 338 ******************************************************************************/ 339 340 static void 341 acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) 342 { 343 u16 count; 344 u16 new_count; 345 346 ACPI_FUNCTION_NAME(ut_update_ref_count); 347 348 if (!object) { 349 return; 350 } 351 352 count = object->common.reference_count; 353 new_count = count; 354 355 /* 356 * Perform the reference count action (increment, decrement, force delete) 357 */ 358 switch (action) { 359 case REF_INCREMENT: 360 361 new_count++; 362 object->common.reference_count = new_count; 363 364 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 365 "Obj %p Refs=%X, [Incremented]\n", 366 object, new_count)); 367 break; 368 369 case REF_DECREMENT: 370 371 if (count < 1) { 372 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 373 "Obj %p Refs=%X, can't decrement! (Set to 0)\n", 374 object, new_count)); 375 376 new_count = 0; 377 } else { 378 new_count--; 379 380 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 381 "Obj %p Refs=%X, [Decremented]\n", 382 object, new_count)); 383 } 384 385 if (object->common.type == ACPI_TYPE_METHOD) { 386 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 387 "Method Obj %p Refs=%X, [Decremented]\n", 388 object, new_count)); 389 } 390 391 object->common.reference_count = new_count; 392 if (new_count == 0) { 393 acpi_ut_delete_internal_obj(object); 394 } 395 break; 396 397 case REF_FORCE_DELETE: 398 399 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 400 "Obj %p Refs=%X, Force delete! (Set to 0)\n", 401 object, count)); 402 403 new_count = 0; 404 object->common.reference_count = new_count; 405 acpi_ut_delete_internal_obj(object); 406 break; 407 408 default: 409 410 ACPI_ERROR((AE_INFO, "Unknown action (%X)", action)); 411 break; 412 } 413 414 /* 415 * Sanity check the reference count, for debug purposes only. 416 * (A deleted object will have a huge reference count) 417 */ 418 if (count > ACPI_MAX_REFERENCE_COUNT) { 419 ACPI_WARNING((AE_INFO, 420 "Large Reference Count (%X) in object %p", count, 421 object)); 422 } 423 } 424 425 /******************************************************************************* 426 * 427 * FUNCTION: acpi_ut_update_object_reference 428 * 429 * PARAMETERS: Object - Increment ref count for this object 430 * and all sub-objects 431 * Action - Either REF_INCREMENT or REF_DECREMENT or 432 * REF_FORCE_DELETE 433 * 434 * RETURN: Status 435 * 436 * DESCRIPTION: Increment the object reference count 437 * 438 * Object references are incremented when: 439 * 1) An object is attached to a Node (namespace object) 440 * 2) An object is copied (all subobjects must be incremented) 441 * 442 * Object references are decremented when: 443 * 1) An object is detached from an Node 444 * 445 ******************************************************************************/ 446 447 acpi_status 448 acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) 449 { 450 acpi_status status = AE_OK; 451 union acpi_generic_state *state_list = NULL; 452 union acpi_operand_object *next_object = NULL; 453 union acpi_generic_state *state; 454 u32 i; 455 456 ACPI_FUNCTION_TRACE_PTR(ut_update_object_reference, object); 457 458 while (object) { 459 460 /* Make sure that this isn't a namespace handle */ 461 462 if (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) { 463 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 464 "Object %p is NS handle\n", object)); 465 return_ACPI_STATUS(AE_OK); 466 } 467 468 /* 469 * All sub-objects must have their reference count incremented also. 470 * Different object types have different subobjects. 471 */ 472 switch (object->common.type) { 473 case ACPI_TYPE_DEVICE: 474 case ACPI_TYPE_PROCESSOR: 475 case ACPI_TYPE_POWER: 476 case ACPI_TYPE_THERMAL: 477 478 /* Update the notify objects for these types (if present) */ 479 480 acpi_ut_update_ref_count(object->common_notify. 481 system_notify, action); 482 acpi_ut_update_ref_count(object->common_notify. 483 device_notify, action); 484 break; 485 486 case ACPI_TYPE_PACKAGE: 487 /* 488 * We must update all the sub-objects of the package, 489 * each of whom may have their own sub-objects. 490 */ 491 for (i = 0; i < object->package.count; i++) { 492 /* 493 * Push each element onto the stack for later processing. 494 * Note: There can be null elements within the package, 495 * these are simply ignored 496 */ 497 status = 498 acpi_ut_create_update_state_and_push 499 (object->package.elements[i], action, 500 &state_list); 501 if (ACPI_FAILURE(status)) { 502 goto error_exit; 503 } 504 } 505 break; 506 507 case ACPI_TYPE_BUFFER_FIELD: 508 509 next_object = object->buffer_field.buffer_obj; 510 break; 511 512 case ACPI_TYPE_LOCAL_REGION_FIELD: 513 514 next_object = object->field.region_obj; 515 break; 516 517 case ACPI_TYPE_LOCAL_BANK_FIELD: 518 519 next_object = object->bank_field.bank_obj; 520 status = 521 acpi_ut_create_update_state_and_push(object-> 522 bank_field. 523 region_obj, 524 action, 525 &state_list); 526 if (ACPI_FAILURE(status)) { 527 goto error_exit; 528 } 529 break; 530 531 case ACPI_TYPE_LOCAL_INDEX_FIELD: 532 533 next_object = object->index_field.index_obj; 534 status = 535 acpi_ut_create_update_state_and_push(object-> 536 index_field. 537 data_obj, 538 action, 539 &state_list); 540 if (ACPI_FAILURE(status)) { 541 goto error_exit; 542 } 543 break; 544 545 case ACPI_TYPE_LOCAL_REFERENCE: 546 /* 547 * The target of an Index (a package, string, or buffer) or a named 548 * reference must track changes to the ref count of the index or 549 * target object. 550 */ 551 if ((object->reference.class == ACPI_REFCLASS_INDEX) || 552 (object->reference.class == ACPI_REFCLASS_NAME)) { 553 next_object = object->reference.object; 554 } 555 break; 556 557 case ACPI_TYPE_REGION: 558 default: 559 break; /* No subobjects for all other types */ 560 } 561 562 /* 563 * Now we can update the count in the main object. This can only 564 * happen after we update the sub-objects in case this causes the 565 * main object to be deleted. 566 */ 567 acpi_ut_update_ref_count(object, action); 568 object = NULL; 569 570 /* Move on to the next object to be updated */ 571 572 if (next_object) { 573 object = next_object; 574 next_object = NULL; 575 } else if (state_list) { 576 state = acpi_ut_pop_generic_state(&state_list); 577 object = state->update.object; 578 acpi_ut_delete_generic_state(state); 579 } 580 } 581 582 return_ACPI_STATUS(AE_OK); 583 584 error_exit: 585 586 ACPI_EXCEPTION((AE_INFO, status, 587 "Could not update object reference count")); 588 589 /* Free any stacked Update State objects */ 590 591 while (state_list) { 592 state = acpi_ut_pop_generic_state(&state_list); 593 acpi_ut_delete_generic_state(state); 594 } 595 596 return_ACPI_STATUS(status); 597 } 598 599 /******************************************************************************* 600 * 601 * FUNCTION: acpi_ut_add_reference 602 * 603 * PARAMETERS: Object - Object whose reference count is to be 604 * incremented 605 * 606 * RETURN: None 607 * 608 * DESCRIPTION: Add one reference to an ACPI object 609 * 610 ******************************************************************************/ 611 612 void acpi_ut_add_reference(union acpi_operand_object *object) 613 { 614 615 ACPI_FUNCTION_TRACE_PTR(ut_add_reference, object); 616 617 /* Ensure that we have a valid object */ 618 619 if (!acpi_ut_valid_internal_object(object)) { 620 return_VOID; 621 } 622 623 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 624 "Obj %p Current Refs=%X [To Be Incremented]\n", 625 object, object->common.reference_count)); 626 627 /* Increment the reference count */ 628 629 (void)acpi_ut_update_object_reference(object, REF_INCREMENT); 630 return_VOID; 631 } 632 633 /******************************************************************************* 634 * 635 * FUNCTION: acpi_ut_remove_reference 636 * 637 * PARAMETERS: Object - Object whose ref count will be decremented 638 * 639 * RETURN: None 640 * 641 * DESCRIPTION: Decrement the reference count of an ACPI internal object 642 * 643 ******************************************************************************/ 644 645 void acpi_ut_remove_reference(union acpi_operand_object *object) 646 { 647 648 ACPI_FUNCTION_TRACE_PTR(ut_remove_reference, object); 649 650 /* 651 * Allow a NULL pointer to be passed in, just ignore it. This saves 652 * each caller from having to check. Also, ignore NS nodes. 653 * 654 */ 655 if (!object || 656 (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED)) { 657 return_VOID; 658 } 659 660 /* Ensure that we have a valid object */ 661 662 if (!acpi_ut_valid_internal_object(object)) { 663 return_VOID; 664 } 665 666 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, 667 "Obj %p Current Refs=%X [To Be Decremented]\n", 668 object, object->common.reference_count)); 669 670 /* 671 * Decrement the reference count, and only actually delete the object 672 * if the reference count becomes 0. (Must also decrement the ref count 673 * of all subobjects!) 674 */ 675 (void)acpi_ut_update_object_reference(object, REF_DECREMENT); 676 return_VOID; 677 } 678