diff options
author | Bob Moore <robert.moore@intel.com> | 2007-04-03 19:59:37 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-06-02 00:20:29 -0400 |
commit | 6287ee32952b502c23d54f12895c3895ddbe5013 (patch) | |
tree | 2b7c0baaeda3687793d46b3836ec236c1bea5ed0 /drivers/acpi | |
parent | 8ff6f48d99a0351bcc9ceab422042ef9d3bad9aa (diff) |
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>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/utilities/utcopy.c | 120 | ||||
-rw-r--r-- | drivers/acpi/utilities/utobject.c | 42 |
2 files changed, 92 insertions, 70 deletions
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 4c1e00874dff..879eaa10d3ae 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c | |||
@@ -68,6 +68,10 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj, | |||
68 | union acpi_operand_object **return_obj); | 68 | union acpi_operand_object **return_obj); |
69 | 69 | ||
70 | static acpi_status | 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 | acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | 75 | acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, |
72 | union acpi_operand_object *dest_desc); | 76 | union acpi_operand_object *dest_desc); |
73 | 77 | ||
@@ -518,77 +522,73 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, | |||
518 | return_ACPI_STATUS(AE_NO_MEMORY); | 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 | * FUNCTION: acpi_ut_copy_epackage_to_ipackage | 527 | * FUNCTION: acpi_ut_copy_epackage_to_ipackage |
527 | * | 528 | * |
528 | * PARAMETERS: *internal_object - Pointer to the object we are returning | 529 | * PARAMETERS: external_object - The external object to be converted |
529 | * *Buffer - Where the object is returned | 530 | * internal_object - Where the internal object is returned |
530 | * *space_used - Where the length of the object is returned | ||
531 | * | 531 | * |
532 | * RETURN: Status | 532 | * RETURN: Status |
533 | * | 533 | * |
534 | * DESCRIPTION: This function is called to place a package object in a user | 534 | * DESCRIPTION: Copy an external package object to an internal package. |
535 | * buffer. A package object by definition contains other objects. | 535 | * Handles nested packages. |
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 | * | 536 | * |
541 | ******************************************************************************/ | 537 | ******************************************************************************/ |
542 | 538 | ||
543 | static acpi_status | 539 | static acpi_status |
544 | acpi_ut_copy_epackage_to_ipackage(union acpi_operand_object *internal_object, | 540 | acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, |
545 | u8 * buffer, u32 * space_used) | 541 | union acpi_operand_object **internal_object) |
546 | { | 542 | { |
547 | u8 *free_space; | 543 | acpi_status status = AE_OK; |
548 | union acpi_object *external_object; | 544 | union acpi_operand_object *package_object; |
549 | u32 length = 0; | 545 | union acpi_operand_object **package_elements; |
550 | u32 this_index; | 546 | acpi_native_uint i; |
551 | u32 object_space = 0; | ||
552 | union acpi_operand_object *this_internal_obj; | ||
553 | union acpi_object *this_external_obj; | ||
554 | 547 | ||
555 | ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage); | 548 | ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage); |
556 | 549 | ||
557 | /* | 550 | /* Create the package object */ |
558 | * First package at head of the buffer | ||
559 | */ | ||
560 | external_object = (union acpi_object *)buffer; | ||
561 | 551 | ||
562 | /* | 552 | package_object = |
563 | * Free space begins right after the first package | 553 | acpi_ut_create_package_object(external_object->package.count); |
564 | */ | 554 | if (!package_object) { |
565 | free_space = buffer + sizeof(union acpi_object); | 555 | return_ACPI_STATUS(AE_NO_MEMORY); |
556 | } | ||
566 | 557 | ||
567 | external_object->type = ACPI_GET_OBJECT_TYPE(internal_object); | 558 | package_elements = package_object->package.elements; |
568 | external_object->package.count = internal_object->package.count; | ||
569 | external_object->package.elements = (union acpi_object *)free_space; | ||
570 | 559 | ||
571 | /* | 560 | /* |
572 | * Build an array of ACPI_OBJECTS in the buffer | 561 | * Recursive implementation. Probably ok, since nested external packages |
573 | * and move the free space past it | 562 | * as parameters should be very rare. |
574 | */ | 563 | */ |
575 | free_space += | 564 | for (i = 0; i < external_object->package.count; i++) { |
576 | external_object->package.count * sizeof(union acpi_object); | 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 | ||
580 | } | 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 | } | ||
581 | 579 | ||
582 | #endif /* Future implementation */ | 580 | *internal_object = package_object; |
581 | return_ACPI_STATUS(status); | ||
582 | } | ||
583 | 583 | ||
584 | /******************************************************************************* | 584 | /******************************************************************************* |
585 | * | 585 | * |
586 | * FUNCTION: acpi_ut_copy_eobject_to_iobject | 586 | * FUNCTION: acpi_ut_copy_eobject_to_iobject |
587 | * | 587 | * |
588 | * PARAMETERS: *internal_object - The external object to be converted | 588 | * PARAMETERS: external_object - The external object to be converted |
589 | * *buffer_ptr - Where the internal object is returned | 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 | * DESCRIPTION: Converts an external object to an internal object. | 593 | * DESCRIPTION: Converts an external object to an internal object. |
594 | * | 594 | * |
@@ -603,16 +603,10 @@ acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object, | |||
603 | ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject); | 603 | ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject); |
604 | 604 | ||
605 | if (external_object->type == ACPI_TYPE_PACKAGE) { | 605 | if (external_object->type == ACPI_TYPE_PACKAGE) { |
606 | /* | 606 | status = |
607 | * Packages as external input to control methods are not supported, | 607 | acpi_ut_copy_epackage_to_ipackage(external_object, |
608 | */ | 608 | internal_object); |
609 | ACPI_ERROR((AE_INFO, | 609 | } else { |
610 | "Packages as parameters not implemented!")); | ||
611 | |||
612 | return_ACPI_STATUS(AE_NOT_IMPLEMENTED); | ||
613 | } | ||
614 | |||
615 | else { | ||
616 | /* | 610 | /* |
617 | * Build a simple object (no nested objects) | 611 | * Build a simple object (no nested objects) |
618 | */ | 612 | */ |
@@ -803,33 +797,19 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type, | |||
803 | * Create and build the package object | 797 | * Create and build the package object |
804 | */ | 798 | */ |
805 | target_object = | 799 | target_object = |
806 | acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE); | 800 | acpi_ut_create_package_object(source_object->package.count); |
807 | if (!target_object) { | 801 | if (!target_object) { |
808 | return (AE_NO_MEMORY); | 802 | return (AE_NO_MEMORY); |
809 | } | 803 | } |
810 | 804 | ||
811 | target_object->package.count = source_object->package.count; | ||
812 | target_object->common.flags = source_object->common.flags; | 805 | target_object->common.flags = source_object->common.flags; |
813 | 806 | ||
814 | /* | 807 | /* Pass the new package object back to the package walk routine */ |
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 | } | ||
824 | 808 | ||
825 | /* | ||
826 | * Pass the new package object back to the package walk routine | ||
827 | */ | ||
828 | state->pkg.this_target_obj = target_object; | 809 | state->pkg.this_target_obj = target_object; |
829 | 810 | ||
830 | /* | 811 | /* Store the object pointer in the parent package object */ |
831 | * Store the object pointer in the parent package object | 812 | |
832 | */ | ||
833 | *this_target_ptr = target_object; | 813 | *this_target_ptr = target_object; |
834 | break; | 814 | break; |
835 | 815 | ||
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index 4696124759e1..db0b9bac7945 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c | |||
@@ -146,6 +146,48 @@ union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name, | |||
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 | * FUNCTION: acpi_ut_create_buffer_object | 191 | * FUNCTION: acpi_ut_create_buffer_object |
150 | * | 192 | * |
151 | * PARAMETERS: buffer_size - Size of buffer to be created | 193 | * PARAMETERS: buffer_size - Size of buffer to be created |