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