Commit 6287ee32952b502c23d54f12895c3895ddbe5013

Authored by Bob Moore
Committed by Len Brown
1 parent 8ff6f48d99

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);