diff options
Diffstat (limited to 'drivers/acpi/utilities/utdelete.c')
-rw-r--r-- | drivers/acpi/utilities/utdelete.c | 140 |
1 files changed, 34 insertions, 106 deletions
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index bc5403022681..eeafb324c504 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c | |||
@@ -435,35 +435,24 @@ acpi_ut_update_object_reference ( | |||
435 | union acpi_operand_object *object, | 435 | union acpi_operand_object *object, |
436 | u16 action) | 436 | u16 action) |
437 | { | 437 | { |
438 | acpi_status status; | 438 | acpi_status status = AE_OK; |
439 | u32 i; | 439 | union acpi_generic_state *state_list = NULL; |
440 | union acpi_generic_state *state_list = NULL; | 440 | union acpi_operand_object *next_object = NULL; |
441 | union acpi_generic_state *state; | 441 | union acpi_generic_state *state; |
442 | union acpi_operand_object *tmp; | 442 | acpi_native_uint i; |
443 | |||
444 | ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object); | ||
445 | 443 | ||
446 | 444 | ||
447 | /* Ignore a null object ptr */ | 445 | ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object); |
448 | |||
449 | if (!object) { | ||
450 | return_ACPI_STATUS (AE_OK); | ||
451 | } | ||
452 | 446 | ||
453 | /* Make sure that this isn't a namespace handle */ | ||
454 | 447 | ||
455 | if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) { | 448 | while (object) { |
456 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, | 449 | /* Make sure that this isn't a namespace handle */ |
457 | "Object %p is NS handle\n", object)); | ||
458 | return_ACPI_STATUS (AE_OK); | ||
459 | } | ||
460 | 450 | ||
461 | state = acpi_ut_create_update_state (object, action); | 451 | if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) { |
462 | 452 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, | |
463 | while (state) { | 453 | "Object %p is NS handle\n", object)); |
464 | object = state->update.object; | 454 | return_ACPI_STATUS (AE_OK); |
465 | action = state->update.value; | 455 | } |
466 | acpi_ut_delete_generic_state (state); | ||
467 | 456 | ||
468 | /* | 457 | /* |
469 | * All sub-objects must have their reference count incremented also. | 458 | * All sub-objects must have their reference count incremented also. |
@@ -472,24 +461,14 @@ acpi_ut_update_object_reference ( | |||
472 | switch (ACPI_GET_OBJECT_TYPE (object)) { | 461 | switch (ACPI_GET_OBJECT_TYPE (object)) { |
473 | case ACPI_TYPE_DEVICE: | 462 | case ACPI_TYPE_DEVICE: |
474 | 463 | ||
475 | tmp = object->device.system_notify; | 464 | acpi_ut_update_ref_count (object->device.system_notify, action); |
476 | if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT) | 465 | acpi_ut_update_ref_count (object->device.device_notify, action); |
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; | 466 | break; |
486 | 467 | ||
487 | |||
488 | case ACPI_TYPE_PACKAGE: | 468 | case ACPI_TYPE_PACKAGE: |
489 | |||
490 | /* | 469 | /* |
491 | * We must update all the sub-objects of the package | 470 | * We must update all the sub-objects of the package, |
492 | * (Each of whom may have their own sub-objects, etc. | 471 | * each of whom may have their own sub-objects. |
493 | */ | 472 | */ |
494 | for (i = 0; i < object->package.count; i++) { | 473 | for (i = 0; i < object->package.count; i++) { |
495 | /* | 474 | /* |
@@ -502,111 +481,52 @@ acpi_ut_update_object_reference ( | |||
502 | if (ACPI_FAILURE (status)) { | 481 | if (ACPI_FAILURE (status)) { |
503 | goto error_exit; | 482 | goto error_exit; |
504 | } | 483 | } |
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 | } | 484 | } |
510 | break; | 485 | break; |
511 | 486 | ||
512 | |||
513 | case ACPI_TYPE_BUFFER_FIELD: | 487 | case ACPI_TYPE_BUFFER_FIELD: |
514 | 488 | ||
515 | status = acpi_ut_create_update_state_and_push ( | 489 | next_object = object->buffer_field.buffer_obj; |
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; | 490 | break; |
525 | 491 | ||
526 | |||
527 | case ACPI_TYPE_LOCAL_REGION_FIELD: | 492 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
528 | 493 | ||
529 | status = acpi_ut_create_update_state_and_push ( | 494 | next_object = object->field.region_obj; |
530 | object->field.region_obj, action, &state_list); | 495 | break; |
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 | 496 | ||
541 | case ACPI_TYPE_LOCAL_BANK_FIELD: | 497 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
542 | 498 | ||
543 | status = acpi_ut_create_update_state_and_push ( | 499 | next_object = object->bank_field.bank_obj; |
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 ( | 500 | status = acpi_ut_create_update_state_and_push ( |
554 | object->bank_field.region_obj, action, &state_list); | 501 | object->bank_field.region_obj, action, &state_list); |
555 | if (ACPI_FAILURE (status)) { | 502 | if (ACPI_FAILURE (status)) { |
556 | goto error_exit; | 503 | goto error_exit; |
557 | } | 504 | } |
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; | 505 | break; |
563 | 506 | ||
564 | |||
565 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | 507 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
566 | 508 | ||
567 | status = acpi_ut_create_update_state_and_push ( | 509 | next_object = object->index_field.index_obj; |
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 ( | 510 | status = acpi_ut_create_update_state_and_push ( |
578 | object->index_field.data_obj, action, &state_list); | 511 | object->index_field.data_obj, action, &state_list); |
579 | if (ACPI_FAILURE (status)) { | 512 | if (ACPI_FAILURE (status)) { |
580 | goto error_exit; | 513 | goto error_exit; |
581 | } | 514 | } |
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; | 515 | break; |
587 | 516 | ||
588 | |||
589 | case ACPI_TYPE_LOCAL_REFERENCE: | 517 | case ACPI_TYPE_LOCAL_REFERENCE: |
590 | |||
591 | /* | 518 | /* |
592 | * The target of an Index (a package, string, or buffer) must track | 519 | * The target of an Index (a package, string, or buffer) must track |
593 | * changes to the ref count of the index. | 520 | * changes to the ref count of the index. |
594 | */ | 521 | */ |
595 | if (object->reference.opcode == AML_INDEX_OP) { | 522 | if (object->reference.opcode == AML_INDEX_OP) { |
596 | status = acpi_ut_create_update_state_and_push ( | 523 | next_object = object->reference.object; |
597 | object->reference.object, action, &state_list); | ||
598 | if (ACPI_FAILURE (status)) { | ||
599 | goto error_exit; | ||
600 | } | ||
601 | } | 524 | } |
602 | break; | 525 | break; |
603 | 526 | ||
604 | |||
605 | case ACPI_TYPE_REGION: | 527 | case ACPI_TYPE_REGION: |
606 | default: | 528 | default: |
607 | 529 | break;/* No subobjects */ | |
608 | /* No subobjects */ | ||
609 | break; | ||
610 | } | 530 | } |
611 | 531 | ||
612 | /* | 532 | /* |
@@ -615,15 +535,23 @@ acpi_ut_update_object_reference ( | |||
615 | * main object to be deleted. | 535 | * main object to be deleted. |
616 | */ | 536 | */ |
617 | acpi_ut_update_ref_count (object, action); | 537 | acpi_ut_update_ref_count (object, action); |
538 | object = NULL; | ||
618 | 539 | ||
619 | /* Move on to the next object to be updated */ | 540 | /* Move on to the next object to be updated */ |
620 | 541 | ||
621 | state = acpi_ut_pop_generic_state (&state_list); | 542 | if (next_object) { |
543 | object = next_object; | ||
544 | next_object = NULL; | ||
545 | } | ||
546 | else if (state_list) { | ||
547 | state = acpi_ut_pop_generic_state (&state_list); | ||
548 | object = state->update.object; | ||
549 | acpi_ut_delete_generic_state (state); | ||
550 | } | ||
622 | } | 551 | } |
623 | 552 | ||
624 | return_ACPI_STATUS (AE_OK); | 553 | return_ACPI_STATUS (AE_OK); |
625 | 554 | ||
626 | |||
627 | error_exit: | 555 | error_exit: |
628 | 556 | ||
629 | ACPI_REPORT_ERROR (("Could not update object reference count, %s\n", | 557 | ACPI_REPORT_ERROR (("Could not update object reference count, %s\n", |