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