Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: utobject - ACPI object create/delete/size/cache routines
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /*
  8.  * Copyright (C) 2000 - 2015, Intel Corp.
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without
  12.  * modification, are permitted provided that the following conditions
  13.  * are met:
  14.  * 1. Redistributions of source code must retain the above copyright
  15.  *    notice, this list of conditions, and the following disclaimer,
  16.  *    without modification.
  17.  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18.  *    substantially similar to the "NO WARRANTY" disclaimer below
  19.  *    ("Disclaimer") and any redistribution must be conditioned upon
  20.  *    including a substantially similar Disclaimer requirement for further
  21.  *    binary redistribution.
  22.  * 3. Neither the names of the above-listed copyright holders nor the names
  23.  *    of any contributors may be used to endorse or promote products derived
  24.  *    from this software without specific prior written permission.
  25.  *
  26.  * Alternatively, this software may be distributed under the terms of the
  27.  * GNU General Public License ("GPL") version 2 as published by the Free
  28.  * Software Foundation.
  29.  *
  30.  * NO WARRANTY
  31.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35.  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41.  * POSSIBILITY OF SUCH DAMAGES.
  42.  */
  43.  
  44. #include <acpi/acpi.h>
  45. #include "accommon.h"
  46. #include "acnamesp.h"
  47.  
  48. #define _COMPONENT          ACPI_UTILITIES
  49. ACPI_MODULE_NAME("utobject")
  50.  
  51. /* Local prototypes */
  52. static acpi_status
  53. acpi_ut_get_simple_object_size(union acpi_operand_object *obj,
  54.                                acpi_size * obj_length);
  55.  
  56. static acpi_status
  57. acpi_ut_get_package_object_size(union acpi_operand_object *obj,
  58.                                 acpi_size * obj_length);
  59.  
  60. static acpi_status
  61. acpi_ut_get_element_length(u8 object_type,
  62.                            union acpi_operand_object *source_object,
  63.                            union acpi_generic_state *state, void *context);
  64.  
  65. /*******************************************************************************
  66.  *
  67.  * FUNCTION:    acpi_ut_create_internal_object_dbg
  68.  *
  69.  * PARAMETERS:  module_name         - Source file name of caller
  70.  *              line_number         - Line number of caller
  71.  *              component_id        - Component type of caller
  72.  *              type                - ACPI Type of the new object
  73.  *
  74.  * RETURN:      A new internal object, null on failure
  75.  *
  76.  * DESCRIPTION: Create and initialize a new internal object.
  77.  *
  78.  * NOTE:        We always allocate the worst-case object descriptor because
  79.  *              these objects are cached, and we want them to be
  80.  *              one-size-satisifies-any-request. This in itself may not be
  81.  *              the most memory efficient, but the efficiency of the object
  82.  *              cache should more than make up for this!
  83.  *
  84.  ******************************************************************************/
  85.  
  86. union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
  87.                                                               *module_name,
  88.                                                               u32 line_number,
  89.                                                               u32 component_id,
  90.                                                               acpi_object_type
  91.                                                               type)
  92. {
  93.         union acpi_operand_object *object;
  94.         union acpi_operand_object *second_object;
  95.  
  96.         ACPI_FUNCTION_TRACE_STR(ut_create_internal_object_dbg,
  97.                                 acpi_ut_get_type_name(type));
  98.  
  99.         /* Allocate the raw object descriptor */
  100.  
  101.         object =
  102.             acpi_ut_allocate_object_desc_dbg(module_name, line_number,
  103.                                              component_id);
  104.         if (!object) {
  105.                 return_PTR(NULL);
  106.         }
  107.  
  108.         switch (type) {
  109.         case ACPI_TYPE_REGION:
  110.         case ACPI_TYPE_BUFFER_FIELD:
  111.         case ACPI_TYPE_LOCAL_BANK_FIELD:
  112.  
  113.                 /* These types require a secondary object */
  114.  
  115.                 second_object = acpi_ut_allocate_object_desc_dbg(module_name,
  116.                                                                  line_number,
  117.                                                                  component_id);
  118.                 if (!second_object) {
  119.                         acpi_ut_delete_object_desc(object);
  120.                         return_PTR(NULL);
  121.                 }
  122.  
  123.                 second_object->common.type = ACPI_TYPE_LOCAL_EXTRA;
  124.                 second_object->common.reference_count = 1;
  125.  
  126.                 /* Link the second object to the first */
  127.  
  128.                 object->common.next_object = second_object;
  129.                 break;
  130.  
  131.         default:
  132.  
  133.                 /* All others have no secondary object */
  134.                 break;
  135.         }
  136.  
  137.         /* Save the object type in the object descriptor */
  138.  
  139.         object->common.type = (u8) type;
  140.  
  141.         /* Init the reference count */
  142.  
  143.         object->common.reference_count = 1;
  144.  
  145.         /* Any per-type initialization should go here */
  146.  
  147.         return_PTR(object);
  148. }
  149.  
  150. /*******************************************************************************
  151.  *
  152.  * FUNCTION:    acpi_ut_create_package_object
  153.  *
  154.  * PARAMETERS:  count               - Number of package elements
  155.  *
  156.  * RETURN:      Pointer to a new Package object, null on failure
  157.  *
  158.  * DESCRIPTION: Create a fully initialized package object
  159.  *
  160.  ******************************************************************************/
  161.  
  162. union acpi_operand_object *acpi_ut_create_package_object(u32 count)
  163. {
  164.         union acpi_operand_object *package_desc;
  165.         union acpi_operand_object **package_elements;
  166.  
  167.         ACPI_FUNCTION_TRACE_U32(ut_create_package_object, count);
  168.  
  169.         /* Create a new Package object */
  170.  
  171.         package_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
  172.         if (!package_desc) {
  173.                 return_PTR(NULL);
  174.         }
  175.  
  176.         /*
  177.          * Create the element array. Count+1 allows the array to be null
  178.          * terminated.
  179.          */
  180.         package_elements = ACPI_ALLOCATE_ZEROED(((acpi_size) count +
  181.                                                  1) * sizeof(void *));
  182.         if (!package_elements) {
  183.                 ACPI_FREE(package_desc);
  184.                 return_PTR(NULL);
  185.         }
  186.  
  187.         package_desc->package.count = count;
  188.         package_desc->package.elements = package_elements;
  189.         return_PTR(package_desc);
  190. }
  191.  
  192. /*******************************************************************************
  193.  *
  194.  * FUNCTION:    acpi_ut_create_integer_object
  195.  *
  196.  * PARAMETERS:  initial_value       - Initial value for the integer
  197.  *
  198.  * RETURN:      Pointer to a new Integer object, null on failure
  199.  *
  200.  * DESCRIPTION: Create an initialized integer object
  201.  *
  202.  ******************************************************************************/
  203.  
  204. union acpi_operand_object *acpi_ut_create_integer_object(u64 initial_value)
  205. {
  206.         union acpi_operand_object *integer_desc;
  207.  
  208.         ACPI_FUNCTION_TRACE(ut_create_integer_object);
  209.  
  210.         /* Create and initialize a new integer object */
  211.  
  212.         integer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
  213.         if (!integer_desc) {
  214.                 return_PTR(NULL);
  215.         }
  216.  
  217.         integer_desc->integer.value = initial_value;
  218.         return_PTR(integer_desc);
  219. }
  220.  
  221. /*******************************************************************************
  222.  *
  223.  * FUNCTION:    acpi_ut_create_buffer_object
  224.  *
  225.  * PARAMETERS:  buffer_size            - Size of buffer to be created
  226.  *
  227.  * RETURN:      Pointer to a new Buffer object, null on failure
  228.  *
  229.  * DESCRIPTION: Create a fully initialized buffer object
  230.  *
  231.  ******************************************************************************/
  232.  
  233. union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size)
  234. {
  235.         union acpi_operand_object *buffer_desc;
  236.         u8 *buffer = NULL;
  237.  
  238.         ACPI_FUNCTION_TRACE_U32(ut_create_buffer_object, buffer_size);
  239.  
  240.         /* Create a new Buffer object */
  241.  
  242.         buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
  243.         if (!buffer_desc) {
  244.                 return_PTR(NULL);
  245.         }
  246.  
  247.         /* Create an actual buffer only if size > 0 */
  248.  
  249.         if (buffer_size > 0) {
  250.  
  251.                 /* Allocate the actual buffer */
  252.  
  253.                 buffer = ACPI_ALLOCATE_ZEROED(buffer_size);
  254.                 if (!buffer) {
  255.                         ACPI_ERROR((AE_INFO, "Could not allocate size %u",
  256.                                     (u32) buffer_size));
  257.                         acpi_ut_remove_reference(buffer_desc);
  258.                         return_PTR(NULL);
  259.                 }
  260.         }
  261.  
  262.         /* Complete buffer object initialization */
  263.  
  264.         buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID;
  265.         buffer_desc->buffer.pointer = buffer;
  266.         buffer_desc->buffer.length = (u32) buffer_size;
  267.  
  268.         /* Return the new buffer descriptor */
  269.  
  270.         return_PTR(buffer_desc);
  271. }
  272.  
  273. /*******************************************************************************
  274.  *
  275.  * FUNCTION:    acpi_ut_create_string_object
  276.  *
  277.  * PARAMETERS:  string_size         - Size of string to be created. Does not
  278.  *                                    include NULL terminator, this is added
  279.  *                                    automatically.
  280.  *
  281.  * RETURN:      Pointer to a new String object
  282.  *
  283.  * DESCRIPTION: Create a fully initialized string object
  284.  *
  285.  ******************************************************************************/
  286.  
  287. union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size)
  288. {
  289.         union acpi_operand_object *string_desc;
  290.         char *string;
  291.  
  292.         ACPI_FUNCTION_TRACE_U32(ut_create_string_object, string_size);
  293.  
  294.         /* Create a new String object */
  295.  
  296.         string_desc = acpi_ut_create_internal_object(ACPI_TYPE_STRING);
  297.         if (!string_desc) {
  298.                 return_PTR(NULL);
  299.         }
  300.  
  301.         /*
  302.          * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
  303.          * NOTE: Zero-length strings are NULL terminated
  304.          */
  305.         string = ACPI_ALLOCATE_ZEROED(string_size + 1);
  306.         if (!string) {
  307.                 ACPI_ERROR((AE_INFO, "Could not allocate size %u",
  308.                             (u32) string_size));
  309.                 acpi_ut_remove_reference(string_desc);
  310.                 return_PTR(NULL);
  311.         }
  312.  
  313.         /* Complete string object initialization */
  314.  
  315.         string_desc->string.pointer = string;
  316.         string_desc->string.length = (u32) string_size;
  317.  
  318.         /* Return the new string descriptor */
  319.  
  320.         return_PTR(string_desc);
  321. }
  322.  
  323. /*******************************************************************************
  324.  *
  325.  * FUNCTION:    acpi_ut_valid_internal_object
  326.  *
  327.  * PARAMETERS:  object              - Object to be validated
  328.  *
  329.  * RETURN:      TRUE if object is valid, FALSE otherwise
  330.  *
  331.  * DESCRIPTION: Validate a pointer to be of type union acpi_operand_object
  332.  *
  333.  ******************************************************************************/
  334.  
  335. u8 acpi_ut_valid_internal_object(void *object)
  336. {
  337.  
  338.         ACPI_FUNCTION_NAME(ut_valid_internal_object);
  339.  
  340.         /* Check for a null pointer */
  341.  
  342.         if (!object) {
  343.                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
  344.                 return (FALSE);
  345.         }
  346.  
  347.         /* Check the descriptor type field */
  348.  
  349.         switch (ACPI_GET_DESCRIPTOR_TYPE(object)) {
  350.         case ACPI_DESC_TYPE_OPERAND:
  351.  
  352.                 /* The object appears to be a valid union acpi_operand_object */
  353.  
  354.                 return (TRUE);
  355.  
  356.         default:
  357.  
  358.                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
  359.                                   "%p is not an ACPI operand obj [%s]\n",
  360.                                   object, acpi_ut_get_descriptor_name(object)));
  361.                 break;
  362.         }
  363.  
  364.         return (FALSE);
  365. }
  366.  
  367. /*******************************************************************************
  368.  *
  369.  * FUNCTION:    acpi_ut_allocate_object_desc_dbg
  370.  *
  371.  * PARAMETERS:  module_name         - Caller's module name (for error output)
  372.  *              line_number         - Caller's line number (for error output)
  373.  *              component_id        - Caller's component ID (for error output)
  374.  *
  375.  * RETURN:      Pointer to newly allocated object descriptor. Null on error
  376.  *
  377.  * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
  378.  *              error conditions.
  379.  *
  380.  ******************************************************************************/
  381.  
  382. void *acpi_ut_allocate_object_desc_dbg(const char *module_name,
  383.                                        u32 line_number, u32 component_id)
  384. {
  385.         union acpi_operand_object *object;
  386.  
  387.         ACPI_FUNCTION_TRACE(ut_allocate_object_desc_dbg);
  388.  
  389.         object = acpi_os_acquire_object(acpi_gbl_operand_cache);
  390.         if (!object) {
  391.                 ACPI_ERROR((module_name, line_number,
  392.                             "Could not allocate an object descriptor"));
  393.  
  394.                 return_PTR(NULL);
  395.         }
  396.  
  397.         /* Mark the descriptor type */
  398.  
  399.         ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_OPERAND);
  400.  
  401.         ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
  402.                           object, (u32) sizeof(union acpi_operand_object)));
  403.  
  404.         return_PTR(object);
  405. }
  406.  
  407. /*******************************************************************************
  408.  *
  409.  * FUNCTION:    acpi_ut_delete_object_desc
  410.  *
  411.  * PARAMETERS:  object          - An Acpi internal object to be deleted
  412.  *
  413.  * RETURN:      None.
  414.  *
  415.  * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
  416.  *
  417.  ******************************************************************************/
  418.  
  419. void acpi_ut_delete_object_desc(union acpi_operand_object *object)
  420. {
  421.         ACPI_FUNCTION_TRACE_PTR(ut_delete_object_desc, object);
  422.  
  423.         /* Object must be of type union acpi_operand_object */
  424.  
  425.         if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
  426.                 ACPI_ERROR((AE_INFO,
  427.                             "%p is not an ACPI Operand object [%s]", object,
  428.                             acpi_ut_get_descriptor_name(object)));
  429.                 return_VOID;
  430.         }
  431.  
  432.         (void)acpi_os_release_object(acpi_gbl_operand_cache, object);
  433.         return_VOID;
  434. }
  435.  
  436. /*******************************************************************************
  437.  *
  438.  * FUNCTION:    acpi_ut_get_simple_object_size
  439.  *
  440.  * PARAMETERS:  internal_object    - An ACPI operand object
  441.  *              obj_length         - Where the length is returned
  442.  *
  443.  * RETURN:      Status
  444.  *
  445.  * DESCRIPTION: This function is called to determine the space required to
  446.  *              contain a simple object for return to an external user.
  447.  *
  448.  *              The length includes the object structure plus any additional
  449.  *              needed space.
  450.  *
  451.  ******************************************************************************/
  452.  
  453. static acpi_status
  454. acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
  455.                                acpi_size * obj_length)
  456. {
  457.         acpi_size length;
  458.         acpi_size size;
  459.         acpi_status status = AE_OK;
  460.  
  461.         ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object);
  462.  
  463.         /* Start with the length of the (external) Acpi object */
  464.  
  465.         length = sizeof(union acpi_object);
  466.  
  467.         /* A NULL object is allowed, can be a legal uninitialized package element */
  468.  
  469.         if (!internal_object) {
  470.         /*
  471.                  * Object is NULL, just return the length of union acpi_object
  472.                  * (A NULL union acpi_object is an object of all zeroes.)
  473.          */
  474.                 *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
  475.                 return_ACPI_STATUS(AE_OK);
  476.         }
  477.  
  478.         /* A Namespace Node should never appear here */
  479.  
  480.         if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) {
  481.  
  482.                 /* A namespace node should never get here */
  483.  
  484.                 return_ACPI_STATUS(AE_AML_INTERNAL);
  485.         }
  486.  
  487.         /*
  488.          * The final length depends on the object type
  489.          * Strings and Buffers are packed right up against the parent object and
  490.          * must be accessed bytewise or there may be alignment problems on
  491.          * certain processors
  492.          */
  493.         switch (internal_object->common.type) {
  494.         case ACPI_TYPE_STRING:
  495.  
  496.                 length += (acpi_size) internal_object->string.length + 1;
  497.                 break;
  498.  
  499.         case ACPI_TYPE_BUFFER:
  500.  
  501.                 length += (acpi_size) internal_object->buffer.length;
  502.                 break;
  503.  
  504.         case ACPI_TYPE_INTEGER:
  505.         case ACPI_TYPE_PROCESSOR:
  506.         case ACPI_TYPE_POWER:
  507.  
  508.                 /* No extra data for these types */
  509.  
  510.                 break;
  511.  
  512.         case ACPI_TYPE_LOCAL_REFERENCE:
  513.  
  514.                 switch (internal_object->reference.class) {
  515.                 case ACPI_REFCLASS_NAME:
  516.                         /*
  517.                          * Get the actual length of the full pathname to this object.
  518.                          * The reference will be converted to the pathname to the object
  519.                          */
  520.                         size =
  521.                             acpi_ns_get_pathname_length(internal_object->
  522.                                                         reference.node);
  523.                         if (!size) {
  524.                                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  525.                         }
  526.  
  527.                         length += ACPI_ROUND_UP_TO_NATIVE_WORD(size);
  528.                         break;
  529.  
  530.                 default:
  531.                         /*
  532.                          * No other reference opcodes are supported.
  533.                          * Notably, Locals and Args are not supported, but this may be
  534.                          * required eventually.
  535.                          */
  536.                         ACPI_ERROR((AE_INFO,
  537.                                     "Cannot convert to external object - "
  538.                                     "unsupported Reference Class [%s] 0x%X in object %p",
  539.                                     acpi_ut_get_reference_name(internal_object),
  540.                                     internal_object->reference.class,
  541.                                     internal_object));
  542.                         status = AE_TYPE;
  543.                         break;
  544.                 }
  545.                 break;
  546.  
  547.         default:
  548.  
  549.                 ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
  550.                             "unsupported type [%s] 0x%X in object %p",
  551.                             acpi_ut_get_object_type_name(internal_object),
  552.                             internal_object->common.type, internal_object));
  553.                 status = AE_TYPE;
  554.                 break;
  555.         }
  556.  
  557.         /*
  558.          * Account for the space required by the object rounded up to the next
  559.          * multiple of the machine word size. This keeps each object aligned
  560.          * on a machine word boundary. (preventing alignment faults on some
  561.          * machines.)
  562.          */
  563.         *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
  564.         return_ACPI_STATUS(status);
  565. }
  566.  
  567. /*******************************************************************************
  568.  *
  569.  * FUNCTION:    acpi_ut_get_element_length
  570.  *
  571.  * PARAMETERS:  acpi_pkg_callback
  572.  *
  573.  * RETURN:      Status
  574.  *
  575.  * DESCRIPTION: Get the length of one package element.
  576.  *
  577.  ******************************************************************************/
  578.  
  579. static acpi_status
  580. acpi_ut_get_element_length(u8 object_type,
  581.                            union acpi_operand_object *source_object,
  582.                            union acpi_generic_state *state, void *context)
  583. {
  584.         acpi_status status = AE_OK;
  585.         struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
  586.         acpi_size object_space;
  587.  
  588.         switch (object_type) {
  589.         case ACPI_COPY_TYPE_SIMPLE:
  590.                 /*
  591.                  * Simple object - just get the size (Null object/entry is handled
  592.                  * here also) and sum it into the running package length
  593.                  */
  594.                 status =
  595.                     acpi_ut_get_simple_object_size(source_object,
  596.                                                    &object_space);
  597.                 if (ACPI_FAILURE(status)) {
  598.                         return (status);
  599.                 }
  600.  
  601.                 info->length += object_space;
  602.                 break;
  603.  
  604.         case ACPI_COPY_TYPE_PACKAGE:
  605.  
  606.                 /* Package object - nothing much to do here, let the walk handle it */
  607.  
  608.                 info->num_packages++;
  609.                 state->pkg.this_target_obj = NULL;
  610.                 break;
  611.  
  612.         default:
  613.  
  614.                 /* No other types allowed */
  615.  
  616.                 return (AE_BAD_PARAMETER);
  617.         }
  618.  
  619.         return (status);
  620. }
  621.  
  622. /*******************************************************************************
  623.  *
  624.  * FUNCTION:    acpi_ut_get_package_object_size
  625.  *
  626.  * PARAMETERS:  internal_object     - An ACPI internal object
  627.  *              obj_length          - Where the length is returned
  628.  *
  629.  * RETURN:      Status
  630.  *
  631.  * DESCRIPTION: This function is called to determine the space required to
  632.  *              contain a package object for return to an external user.
  633.  *
  634.  *              This is moderately complex since a package contains other
  635.  *              objects including packages.
  636.  *
  637.  ******************************************************************************/
  638.  
  639. static acpi_status
  640. acpi_ut_get_package_object_size(union acpi_operand_object *internal_object,
  641.                                 acpi_size * obj_length)
  642. {
  643.         acpi_status status;
  644.         struct acpi_pkg_info info;
  645.  
  646.         ACPI_FUNCTION_TRACE_PTR(ut_get_package_object_size, internal_object);
  647.  
  648.         info.length = 0;
  649.         info.object_space = 0;
  650.         info.num_packages = 1;
  651.  
  652.         status = acpi_ut_walk_package_tree(internal_object, NULL,
  653.                                            acpi_ut_get_element_length, &info);
  654.         if (ACPI_FAILURE(status)) {
  655.                 return_ACPI_STATUS(status);
  656.         }
  657.  
  658.         /*
  659.          * We have handled all of the objects in all levels of the package.
  660.          * just add the length of the package objects themselves.
  661.          * Round up to the next machine word.
  662.          */
  663.         info.length += ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)) *
  664.             (acpi_size) info.num_packages;
  665.  
  666.         /* Return the total package length */
  667.  
  668.         *obj_length = info.length;
  669.         return_ACPI_STATUS(status);
  670. }
  671.  
  672. /*******************************************************************************
  673.  *
  674.  * FUNCTION:    acpi_ut_get_object_size
  675.  *
  676.  * PARAMETERS:  internal_object     - An ACPI internal object
  677.  *              obj_length          - Where the length will be returned
  678.  *
  679.  * RETURN:      Status
  680.  *
  681.  * DESCRIPTION: This function is called to determine the space required to
  682.  *              contain an object for return to an API user.
  683.  *
  684.  ******************************************************************************/
  685.  
  686. acpi_status
  687. acpi_ut_get_object_size(union acpi_operand_object *internal_object,
  688.                         acpi_size * obj_length)
  689. {
  690.         acpi_status status;
  691.  
  692.         ACPI_FUNCTION_ENTRY();
  693.  
  694.         if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
  695.              ACPI_DESC_TYPE_OPERAND)
  696.             && (internal_object->common.type == ACPI_TYPE_PACKAGE)) {
  697.                 status =
  698.                     acpi_ut_get_package_object_size(internal_object,
  699.                                                     obj_length);
  700.         } else {
  701.                 status =
  702.                     acpi_ut_get_simple_object_size(internal_object, obj_length);
  703.         }
  704.  
  705.         return (status);
  706. }
  707.