0001
0002
0003
0004
0005
0006
0007
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "acinterp.h"
0011 #include "acnamesp.h"
0012 #include "acevents.h"
0013
0014 #define _COMPONENT ACPI_UTILITIES
0015 ACPI_MODULE_NAME("utdelete")
0016
0017
0018 static void acpi_ut_delete_internal_obj(union acpi_operand_object *object);
0019
0020 static void
0021 acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action);
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
0037 {
0038 void *obj_pointer = NULL;
0039 union acpi_operand_object *handler_desc;
0040 union acpi_operand_object *second_desc;
0041 union acpi_operand_object *next_desc;
0042 union acpi_operand_object *start_desc;
0043 union acpi_operand_object **last_obj_ptr;
0044
0045 ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object);
0046
0047 if (!object) {
0048 return_VOID;
0049 }
0050
0051
0052
0053
0054
0055 switch (object->common.type) {
0056 case ACPI_TYPE_STRING:
0057
0058 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0059 "**** String %p, ptr %p\n", object,
0060 object->string.pointer));
0061
0062
0063
0064 if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
0065
0066
0067
0068 obj_pointer = object->string.pointer;
0069 }
0070 break;
0071
0072 case ACPI_TYPE_BUFFER:
0073
0074 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0075 "**** Buffer %p, ptr %p\n", object,
0076 object->buffer.pointer));
0077
0078
0079
0080 if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
0081
0082
0083
0084 obj_pointer = object->buffer.pointer;
0085 }
0086 break;
0087
0088 case ACPI_TYPE_PACKAGE:
0089
0090 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0091 " **** Package of count %X\n",
0092 object->package.count));
0093
0094
0095
0096
0097
0098
0099
0100
0101 obj_pointer = object->package.elements;
0102 break;
0103
0104
0105
0106
0107
0108 case ACPI_TYPE_DEVICE:
0109
0110 if (object->device.gpe_block) {
0111 (void)acpi_ev_delete_gpe_block(object->device.
0112 gpe_block);
0113 }
0114
0115 ACPI_FALLTHROUGH;
0116
0117 case ACPI_TYPE_PROCESSOR:
0118 case ACPI_TYPE_THERMAL:
0119
0120
0121
0122 handler_desc = object->common_notify.handler;
0123 while (handler_desc) {
0124 next_desc = handler_desc->address_space.next;
0125 acpi_ut_remove_reference(handler_desc);
0126 handler_desc = next_desc;
0127 }
0128 break;
0129
0130 case ACPI_TYPE_MUTEX:
0131
0132 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0133 "***** Mutex %p, OS Mutex %p\n",
0134 object, object->mutex.os_mutex));
0135
0136 if (object == acpi_gbl_global_lock_mutex) {
0137
0138
0139
0140 (void)
0141 acpi_os_delete_semaphore
0142 (acpi_gbl_global_lock_semaphore);
0143 acpi_gbl_global_lock_semaphore = NULL;
0144
0145 acpi_os_delete_mutex(object->mutex.os_mutex);
0146 acpi_gbl_global_lock_mutex = NULL;
0147 } else {
0148 acpi_ex_unlink_mutex(object);
0149 acpi_os_delete_mutex(object->mutex.os_mutex);
0150 }
0151 break;
0152
0153 case ACPI_TYPE_EVENT:
0154
0155 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0156 "***** Event %p, OS Semaphore %p\n",
0157 object, object->event.os_semaphore));
0158
0159 (void)acpi_os_delete_semaphore(object->event.os_semaphore);
0160 object->event.os_semaphore = NULL;
0161 break;
0162
0163 case ACPI_TYPE_METHOD:
0164
0165 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0166 "***** Method %p\n", object));
0167
0168
0169
0170 if (object->method.mutex) {
0171 acpi_os_delete_mutex(object->method.mutex->mutex.
0172 os_mutex);
0173 acpi_ut_delete_object_desc(object->method.mutex);
0174 object->method.mutex = NULL;
0175 }
0176
0177 if (object->method.node) {
0178 object->method.node = NULL;
0179 }
0180 break;
0181
0182 case ACPI_TYPE_REGION:
0183
0184 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0185 "***** Region %p\n", object));
0186
0187
0188
0189
0190
0191 if (!(object->region.node->flags & ANOBJ_TEMPORARY)) {
0192 acpi_ut_remove_address_range(object->region.space_id,
0193 object->region.node);
0194 }
0195
0196 second_desc = acpi_ns_get_secondary_object(object);
0197 if (second_desc) {
0198
0199
0200
0201
0202
0203 handler_desc = object->region.handler;
0204 if (handler_desc) {
0205 next_desc =
0206 handler_desc->address_space.region_list;
0207 start_desc = next_desc;
0208 last_obj_ptr =
0209 &handler_desc->address_space.region_list;
0210
0211
0212
0213 while (next_desc) {
0214 if (next_desc == object) {
0215 *last_obj_ptr =
0216 next_desc->region.next;
0217 break;
0218 }
0219
0220
0221
0222 last_obj_ptr = &next_desc->region.next;
0223 next_desc = next_desc->region.next;
0224
0225
0226
0227 if (next_desc == start_desc) {
0228 ACPI_ERROR((AE_INFO,
0229 "Circular region list in address handler object %p",
0230 handler_desc));
0231 return_VOID;
0232 }
0233 }
0234
0235 if (handler_desc->address_space.handler_flags &
0236 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
0237
0238
0239
0240 if (handler_desc->address_space.setup) {
0241 (void)handler_desc->
0242 address_space.setup(object,
0243 ACPI_REGION_DEACTIVATE,
0244 handler_desc->
0245 address_space.
0246 context,
0247 &second_desc->
0248 extra.
0249 region_context);
0250 }
0251 }
0252
0253 acpi_ut_remove_reference(handler_desc);
0254 }
0255
0256
0257
0258 acpi_ut_delete_object_desc(second_desc);
0259 }
0260 if (object->field.internal_pcc_buffer) {
0261 ACPI_FREE(object->field.internal_pcc_buffer);
0262 }
0263
0264 break;
0265
0266 case ACPI_TYPE_BUFFER_FIELD:
0267
0268 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0269 "***** Buffer Field %p\n", object));
0270
0271 second_desc = acpi_ns_get_secondary_object(object);
0272 if (second_desc) {
0273 acpi_ut_delete_object_desc(second_desc);
0274 }
0275 break;
0276
0277 case ACPI_TYPE_LOCAL_BANK_FIELD:
0278
0279 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0280 "***** Bank Field %p\n", object));
0281
0282 second_desc = acpi_ns_get_secondary_object(object);
0283 if (second_desc) {
0284 acpi_ut_delete_object_desc(second_desc);
0285 }
0286 break;
0287
0288 case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
0289
0290 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0291 "***** Address handler %p\n", object));
0292
0293 acpi_os_delete_mutex(object->address_space.context_mutex);
0294 break;
0295
0296 default:
0297
0298 break;
0299 }
0300
0301
0302
0303 if (obj_pointer) {
0304 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0305 "Deleting Object Subptr %p\n", obj_pointer));
0306 ACPI_FREE(obj_pointer);
0307 }
0308
0309
0310
0311 ACPI_DEBUG_PRINT_RAW((ACPI_DB_ALLOCATIONS,
0312 "%s: Deleting Object %p [%s]\n",
0313 ACPI_GET_FUNCTION_NAME, object,
0314 acpi_ut_get_object_type_name(object)));
0315
0316 acpi_ut_delete_object_desc(object);
0317 return_VOID;
0318 }
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333 void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list)
0334 {
0335 union acpi_operand_object **internal_obj;
0336
0337 ACPI_FUNCTION_ENTRY();
0338
0339
0340
0341 for (internal_obj = obj_list; *internal_obj; internal_obj++) {
0342 acpi_ut_remove_reference(*internal_obj);
0343 }
0344
0345
0346
0347 ACPI_FREE(obj_list);
0348 return;
0349 }
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 static void
0365 acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
0366 {
0367 u16 original_count;
0368 u16 new_count = 0;
0369 acpi_cpu_flags lock_flags;
0370 char *message;
0371
0372 ACPI_FUNCTION_NAME(ut_update_ref_count);
0373
0374 if (!object) {
0375 return;
0376 }
0377
0378
0379
0380
0381
0382 lock_flags = acpi_os_acquire_lock(acpi_gbl_reference_count_lock);
0383 original_count = object->common.reference_count;
0384
0385
0386
0387 switch (action) {
0388 case REF_INCREMENT:
0389
0390 new_count = original_count + 1;
0391 object->common.reference_count = new_count;
0392 acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);
0393
0394
0395
0396 if (!original_count) {
0397 ACPI_WARNING((AE_INFO,
0398 "Obj %p, Reference Count was zero before increment\n",
0399 object));
0400 }
0401
0402 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0403 "Obj %p Type %.2X [%s] Refs %.2X [Incremented]\n",
0404 object, object->common.type,
0405 acpi_ut_get_object_type_name(object),
0406 new_count));
0407 message = "Incremement";
0408 break;
0409
0410 case REF_DECREMENT:
0411
0412
0413
0414 if (original_count) {
0415 new_count = original_count - 1;
0416 object->common.reference_count = new_count;
0417 }
0418
0419 acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);
0420
0421 if (!original_count) {
0422 ACPI_WARNING((AE_INFO,
0423 "Obj %p, Reference Count is already zero, cannot decrement\n",
0424 object));
0425 return;
0426 }
0427
0428 ACPI_DEBUG_PRINT_RAW((ACPI_DB_ALLOCATIONS,
0429 "%s: Obj %p Type %.2X Refs %.2X [Decremented]\n",
0430 ACPI_GET_FUNCTION_NAME, object,
0431 object->common.type, new_count));
0432
0433
0434
0435 if (new_count == 0) {
0436 acpi_ut_delete_internal_obj(object);
0437 }
0438 message = "Decrement";
0439 break;
0440
0441 default:
0442
0443 acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);
0444 ACPI_ERROR((AE_INFO, "Unknown Reference Count action (0x%X)",
0445 action));
0446 return;
0447 }
0448
0449
0450
0451
0452
0453 if (new_count > ACPI_MAX_REFERENCE_COUNT) {
0454 ACPI_WARNING((AE_INFO,
0455 "Large Reference Count (0x%X) in object %p, Type=0x%.2X Operation=%s",
0456 new_count, object, object->common.type, message));
0457 }
0458 }
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481 acpi_status
0482 acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
0483 {
0484 acpi_status status = AE_OK;
0485 union acpi_generic_state *state_list = NULL;
0486 union acpi_operand_object *next_object = NULL;
0487 union acpi_operand_object *prev_object;
0488 union acpi_generic_state *state;
0489 u32 i;
0490
0491 ACPI_FUNCTION_NAME(ut_update_object_reference);
0492
0493 while (object) {
0494
0495
0496
0497 if (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) {
0498 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0499 "Object %p is NS handle\n", object));
0500 return (AE_OK);
0501 }
0502
0503
0504
0505
0506
0507 switch (object->common.type) {
0508 case ACPI_TYPE_DEVICE:
0509 case ACPI_TYPE_PROCESSOR:
0510 case ACPI_TYPE_POWER:
0511 case ACPI_TYPE_THERMAL:
0512
0513
0514
0515
0516 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
0517 prev_object =
0518 object->common_notify.notify_list[i];
0519 while (prev_object) {
0520 next_object =
0521 prev_object->notify.next[i];
0522 acpi_ut_update_ref_count(prev_object,
0523 action);
0524 prev_object = next_object;
0525 }
0526 }
0527 break;
0528
0529 case ACPI_TYPE_PACKAGE:
0530
0531
0532
0533
0534 for (i = 0; i < object->package.count; i++) {
0535
0536
0537
0538
0539 next_object = object->package.elements[i];
0540 if (!next_object) {
0541 continue;
0542 }
0543
0544 switch (next_object->common.type) {
0545 case ACPI_TYPE_INTEGER:
0546 case ACPI_TYPE_STRING:
0547 case ACPI_TYPE_BUFFER:
0548
0549
0550
0551
0552
0553 acpi_ut_update_ref_count(next_object,
0554 action);
0555 break;
0556
0557 default:
0558
0559
0560
0561
0562 status =
0563 acpi_ut_create_update_state_and_push
0564 (next_object, action, &state_list);
0565 if (ACPI_FAILURE(status)) {
0566 goto error_exit;
0567 }
0568 break;
0569 }
0570 }
0571
0572 next_object = NULL;
0573 break;
0574
0575 case ACPI_TYPE_BUFFER_FIELD:
0576
0577 next_object = object->buffer_field.buffer_obj;
0578 break;
0579
0580 case ACPI_TYPE_LOCAL_BANK_FIELD:
0581
0582 next_object = object->bank_field.bank_obj;
0583 status =
0584 acpi_ut_create_update_state_and_push(object->
0585 bank_field.
0586 region_obj,
0587 action,
0588 &state_list);
0589 if (ACPI_FAILURE(status)) {
0590 goto error_exit;
0591 }
0592 break;
0593
0594 case ACPI_TYPE_LOCAL_INDEX_FIELD:
0595
0596 next_object = object->index_field.index_obj;
0597 status =
0598 acpi_ut_create_update_state_and_push(object->
0599 index_field.
0600 data_obj,
0601 action,
0602 &state_list);
0603 if (ACPI_FAILURE(status)) {
0604 goto error_exit;
0605 }
0606 break;
0607
0608 case ACPI_TYPE_LOCAL_REFERENCE:
0609
0610
0611
0612
0613
0614 if ((object->reference.class == ACPI_REFCLASS_INDEX) ||
0615 (object->reference.class == ACPI_REFCLASS_NAME)) {
0616 next_object = object->reference.object;
0617 }
0618 break;
0619
0620 case ACPI_TYPE_LOCAL_REGION_FIELD:
0621 case ACPI_TYPE_REGION:
0622 default:
0623
0624 break;
0625 }
0626
0627
0628
0629
0630
0631
0632 acpi_ut_update_ref_count(object, action);
0633 object = NULL;
0634
0635
0636
0637 if (next_object) {
0638 object = next_object;
0639 next_object = NULL;
0640 } else if (state_list) {
0641 state = acpi_ut_pop_generic_state(&state_list);
0642 object = state->update.object;
0643 acpi_ut_delete_generic_state(state);
0644 }
0645 }
0646
0647 return (AE_OK);
0648
0649 error_exit:
0650
0651 ACPI_EXCEPTION((AE_INFO, status,
0652 "Could not update object reference count"));
0653
0654
0655
0656 while (state_list) {
0657 state = acpi_ut_pop_generic_state(&state_list);
0658 acpi_ut_delete_generic_state(state);
0659 }
0660
0661 return (status);
0662 }
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677 void acpi_ut_add_reference(union acpi_operand_object *object)
0678 {
0679
0680 ACPI_FUNCTION_NAME(ut_add_reference);
0681
0682
0683
0684 if (!acpi_ut_valid_internal_object(object)) {
0685 return;
0686 }
0687
0688 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
0689 "Obj %p Current Refs=%X [To Be Incremented]\n",
0690 object, object->common.reference_count));
0691
0692
0693
0694 (void)acpi_ut_update_object_reference(object, REF_INCREMENT);
0695 return;
0696 }
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710 void acpi_ut_remove_reference(union acpi_operand_object *object)
0711 {
0712
0713 ACPI_FUNCTION_NAME(ut_remove_reference);
0714
0715
0716
0717
0718
0719 if (!object ||
0720 (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED)) {
0721 return;
0722 }
0723
0724
0725
0726 if (!acpi_ut_valid_internal_object(object)) {
0727 return;
0728 }
0729
0730 ACPI_DEBUG_PRINT_RAW((ACPI_DB_ALLOCATIONS,
0731 "%s: Obj %p Current Refs=%X [To Be Decremented]\n",
0732 ACPI_GET_FUNCTION_NAME, object,
0733 object->common.reference_count));
0734
0735
0736
0737
0738
0739
0740 (void)acpi_ut_update_object_reference(object, REF_DECREMENT);
0741 return;
0742 }