Commit 6287ee32952b502c23d54f12895c3895ddbe5013
Committed by
Len Brown
1 parent
8ff6f48d99
Exists in
master
and in
7 other branches
ACPICA: Support for external package objects as method arguments
Implemented support to allow Package objects to be passed as method arguments to the acpi_evaluate_object interface. Previously, this would return an AE_NOT_IMPLEMENTED exception. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Showing 3 changed files with 94 additions and 70 deletions Side-by-side Diff
drivers/acpi/utilities/utcopy.c
... | ... | @@ -68,6 +68,10 @@ |
68 | 68 | union acpi_operand_object **return_obj); |
69 | 69 | |
70 | 70 | static acpi_status |
71 | +acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, | |
72 | + union acpi_operand_object **internal_object); | |
73 | + | |
74 | +static acpi_status | |
71 | 75 | acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, |
72 | 76 | union acpi_operand_object *dest_desc); |
73 | 77 | |
74 | 78 | |
75 | 79 | |
76 | 80 | |
77 | 81 | |
78 | 82 | |
79 | 83 | |
80 | 84 | |
81 | 85 | |
82 | 86 | |
83 | 87 | |
84 | 88 | |
85 | 89 | |
86 | 90 | |
87 | 91 | |
88 | 92 | |
... | ... | @@ -518,77 +522,73 @@ |
518 | 522 | return_ACPI_STATUS(AE_NO_MEMORY); |
519 | 523 | } |
520 | 524 | |
521 | -#ifdef ACPI_FUTURE_IMPLEMENTATION | |
522 | -/* Code to convert packages that are parameters to control methods */ | |
523 | - | |
524 | 525 | /******************************************************************************* |
525 | 526 | * |
526 | 527 | * FUNCTION: acpi_ut_copy_epackage_to_ipackage |
527 | 528 | * |
528 | - * PARAMETERS: *internal_object - Pointer to the object we are returning | |
529 | - * *Buffer - Where the object is returned | |
530 | - * *space_used - Where the length of the object is returned | |
529 | + * PARAMETERS: external_object - The external object to be converted | |
530 | + * internal_object - Where the internal object is returned | |
531 | 531 | * |
532 | 532 | * RETURN: Status |
533 | 533 | * |
534 | - * DESCRIPTION: This function is called to place a package object in a user | |
535 | - * buffer. A package object by definition contains other objects. | |
534 | + * DESCRIPTION: Copy an external package object to an internal package. | |
535 | + * Handles nested packages. | |
536 | 536 | * |
537 | - * The buffer is assumed to have sufficient space for the object. | |
538 | - * The caller must have verified the buffer length needed using the | |
539 | - * acpi_ut_get_object_size function before calling this function. | |
540 | - * | |
541 | 537 | ******************************************************************************/ |
542 | 538 | |
543 | 539 | static acpi_status |
544 | -acpi_ut_copy_epackage_to_ipackage(union acpi_operand_object *internal_object, | |
545 | - u8 * buffer, u32 * space_used) | |
540 | +acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, | |
541 | + union acpi_operand_object **internal_object) | |
546 | 542 | { |
547 | - u8 *free_space; | |
548 | - union acpi_object *external_object; | |
549 | - u32 length = 0; | |
550 | - u32 this_index; | |
551 | - u32 object_space = 0; | |
552 | - union acpi_operand_object *this_internal_obj; | |
553 | - union acpi_object *this_external_obj; | |
543 | + acpi_status status = AE_OK; | |
544 | + union acpi_operand_object *package_object; | |
545 | + union acpi_operand_object **package_elements; | |
546 | + acpi_native_uint i; | |
554 | 547 | |
555 | 548 | ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage); |
556 | 549 | |
557 | - /* | |
558 | - * First package at head of the buffer | |
559 | - */ | |
560 | - external_object = (union acpi_object *)buffer; | |
550 | + /* Create the package object */ | |
561 | 551 | |
562 | - /* | |
563 | - * Free space begins right after the first package | |
564 | - */ | |
565 | - free_space = buffer + sizeof(union acpi_object); | |
552 | + package_object = | |
553 | + acpi_ut_create_package_object(external_object->package.count); | |
554 | + if (!package_object) { | |
555 | + return_ACPI_STATUS(AE_NO_MEMORY); | |
556 | + } | |
566 | 557 | |
567 | - external_object->type = ACPI_GET_OBJECT_TYPE(internal_object); | |
568 | - external_object->package.count = internal_object->package.count; | |
569 | - external_object->package.elements = (union acpi_object *)free_space; | |
558 | + package_elements = package_object->package.elements; | |
570 | 559 | |
571 | 560 | /* |
572 | - * Build an array of ACPI_OBJECTS in the buffer | |
573 | - * and move the free space past it | |
561 | + * Recursive implementation. Probably ok, since nested external packages | |
562 | + * as parameters should be very rare. | |
574 | 563 | */ |
575 | - free_space += | |
576 | - external_object->package.count * sizeof(union acpi_object); | |
564 | + for (i = 0; i < external_object->package.count; i++) { | |
565 | + status = | |
566 | + acpi_ut_copy_eobject_to_iobject(&external_object->package. | |
567 | + elements[i], | |
568 | + &package_elements[i]); | |
569 | + if (ACPI_FAILURE(status)) { | |
577 | 570 | |
578 | - /* Call walk_package */ | |
571 | + /* Truncate package and delete it */ | |
579 | 572 | |
573 | + package_object->package.count = i; | |
574 | + package_elements[i] = NULL; | |
575 | + acpi_ut_remove_reference(package_object); | |
576 | + return_ACPI_STATUS(status); | |
577 | + } | |
578 | + } | |
579 | + | |
580 | + *internal_object = package_object; | |
581 | + return_ACPI_STATUS(status); | |
580 | 582 | } |
581 | 583 | |
582 | -#endif /* Future implementation */ | |
583 | - | |
584 | 584 | /******************************************************************************* |
585 | 585 | * |
586 | 586 | * FUNCTION: acpi_ut_copy_eobject_to_iobject |
587 | 587 | * |
588 | - * PARAMETERS: *internal_object - The external object to be converted | |
589 | - * *buffer_ptr - Where the internal object is returned | |
588 | + * PARAMETERS: external_object - The external object to be converted | |
589 | + * internal_object - Where the internal object is returned | |
590 | 590 | * |
591 | - * RETURN: Status - the status of the call | |
591 | + * RETURN: Status - the status of the call | |
592 | 592 | * |
593 | 593 | * DESCRIPTION: Converts an external object to an internal object. |
594 | 594 | * |
595 | 595 | |
... | ... | @@ -603,17 +603,11 @@ |
603 | 603 | ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject); |
604 | 604 | |
605 | 605 | if (external_object->type == ACPI_TYPE_PACKAGE) { |
606 | + status = | |
607 | + acpi_ut_copy_epackage_to_ipackage(external_object, | |
608 | + internal_object); | |
609 | + } else { | |
606 | 610 | /* |
607 | - * Packages as external input to control methods are not supported, | |
608 | - */ | |
609 | - ACPI_ERROR((AE_INFO, | |
610 | - "Packages as parameters not implemented!")); | |
611 | - | |
612 | - return_ACPI_STATUS(AE_NOT_IMPLEMENTED); | |
613 | - } | |
614 | - | |
615 | - else { | |
616 | - /* | |
617 | 611 | * Build a simple object (no nested objects) |
618 | 612 | */ |
619 | 613 | status = |
620 | 614 | |
621 | 615 | |
622 | 616 | |
623 | 617 | |
... | ... | @@ -803,33 +797,19 @@ |
803 | 797 | * Create and build the package object |
804 | 798 | */ |
805 | 799 | target_object = |
806 | - acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE); | |
800 | + acpi_ut_create_package_object(source_object->package.count); | |
807 | 801 | if (!target_object) { |
808 | 802 | return (AE_NO_MEMORY); |
809 | 803 | } |
810 | 804 | |
811 | - target_object->package.count = source_object->package.count; | |
812 | 805 | target_object->common.flags = source_object->common.flags; |
813 | 806 | |
814 | - /* | |
815 | - * Create the object array | |
816 | - */ | |
817 | - target_object->package.elements = | |
818 | - ACPI_ALLOCATE_ZEROED(((acpi_size) source_object->package. | |
819 | - count + 1) * sizeof(void *)); | |
820 | - if (!target_object->package.elements) { | |
821 | - status = AE_NO_MEMORY; | |
822 | - goto error_exit; | |
823 | - } | |
807 | + /* Pass the new package object back to the package walk routine */ | |
824 | 808 | |
825 | - /* | |
826 | - * Pass the new package object back to the package walk routine | |
827 | - */ | |
828 | 809 | state->pkg.this_target_obj = target_object; |
829 | 810 | |
830 | - /* | |
831 | - * Store the object pointer in the parent package object | |
832 | - */ | |
811 | + /* Store the object pointer in the parent package object */ | |
812 | + | |
833 | 813 | *this_target_ptr = target_object; |
834 | 814 | break; |
835 | 815 |
drivers/acpi/utilities/utobject.c
... | ... | @@ -146,6 +146,48 @@ |
146 | 146 | |
147 | 147 | /******************************************************************************* |
148 | 148 | * |
149 | + * FUNCTION: acpi_ut_create_package_object | |
150 | + * | |
151 | + * PARAMETERS: Count - Number of package elements | |
152 | + * | |
153 | + * RETURN: Pointer to a new Package object, null on failure | |
154 | + * | |
155 | + * DESCRIPTION: Create a fully initialized package object | |
156 | + * | |
157 | + ******************************************************************************/ | |
158 | + | |
159 | +union acpi_operand_object *acpi_ut_create_package_object(u32 count) | |
160 | +{ | |
161 | + union acpi_operand_object *package_desc; | |
162 | + union acpi_operand_object **package_elements; | |
163 | + | |
164 | + ACPI_FUNCTION_TRACE_U32(ut_create_package_object, count); | |
165 | + | |
166 | + /* Create a new Package object */ | |
167 | + | |
168 | + package_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE); | |
169 | + if (!package_desc) { | |
170 | + return_PTR(NULL); | |
171 | + } | |
172 | + | |
173 | + /* | |
174 | + * Create the element array. Count+1 allows the array to be null | |
175 | + * terminated. | |
176 | + */ | |
177 | + package_elements = ACPI_ALLOCATE_ZEROED((acpi_size) | |
178 | + (count + 1) * sizeof(void *)); | |
179 | + if (!package_elements) { | |
180 | + ACPI_FREE(package_desc); | |
181 | + return_PTR(NULL); | |
182 | + } | |
183 | + | |
184 | + package_desc->package.count = count; | |
185 | + package_desc->package.elements = package_elements; | |
186 | + return_PTR(package_desc); | |
187 | +} | |
188 | + | |
189 | +/******************************************************************************* | |
190 | + * | |
149 | 191 | * FUNCTION: acpi_ut_create_buffer_object |
150 | 192 | * |
151 | 193 | * PARAMETERS: buffer_size - Size of buffer to be created |
include/acpi/acutils.h
... | ... | @@ -390,6 +390,8 @@ |
390 | 390 | |
391 | 391 | u8 acpi_ut_valid_internal_object(void *object); |
392 | 392 | |
393 | +union acpi_operand_object *acpi_ut_create_package_object(u32 count); | |
394 | + | |
393 | 395 | union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size); |
394 | 396 | |
395 | 397 | union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size); |