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