Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: utcopy - Internal to external object translation utilities
  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.  
  49. #define _COMPONENT          ACPI_UTILITIES
  50. ACPI_MODULE_NAME("utcopy")
  51.  
  52. /* Local prototypes */
  53. static acpi_status
  54. acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
  55.                                 union acpi_object *external_object,
  56.                                 u8 * data_space, acpi_size * buffer_space_used);
  57.  
  58. static acpi_status
  59. acpi_ut_copy_ielement_to_ielement(u8 object_type,
  60.                                   union acpi_operand_object *source_object,
  61.                                   union acpi_generic_state *state,
  62.                                   void *context);
  63.  
  64. static acpi_status
  65. acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
  66.                                   u8 * buffer, acpi_size * space_used);
  67.  
  68. static acpi_status
  69. acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
  70.                                 union acpi_operand_object **return_obj);
  71.  
  72. static acpi_status
  73. acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
  74.                                   union acpi_operand_object **internal_object);
  75.  
  76. static acpi_status
  77. acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
  78.                            union acpi_operand_object *dest_desc);
  79.  
  80. static acpi_status
  81. acpi_ut_copy_ielement_to_eelement(u8 object_type,
  82.                                   union acpi_operand_object *source_object,
  83.                                   union acpi_generic_state *state,
  84.                                   void *context);
  85.  
  86. static acpi_status
  87. acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
  88.                                   union acpi_operand_object *dest_obj,
  89.                                   struct acpi_walk_state *walk_state);
  90.  
  91. /*******************************************************************************
  92.  *
  93.  * FUNCTION:    acpi_ut_copy_isimple_to_esimple
  94.  *
  95.  * PARAMETERS:  internal_object     - Source object to be copied
  96.  *              external_object     - Where to return the copied object
  97.  *              data_space          - Where object data is returned (such as
  98.  *                                    buffer and string data)
  99.  *              buffer_space_used   - Length of data_space that was used
  100.  *
  101.  * RETURN:      Status
  102.  *
  103.  * DESCRIPTION: This function is called to copy a simple internal object to
  104.  *              an external object.
  105.  *
  106.  *              The data_space buffer is assumed to have sufficient space for
  107.  *              the object.
  108.  *
  109.  ******************************************************************************/
  110.  
  111. static acpi_status
  112. acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
  113.                                 union acpi_object *external_object,
  114.                                 u8 * data_space, acpi_size * buffer_space_used)
  115. {
  116.         acpi_status status = AE_OK;
  117.  
  118.         ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple);
  119.  
  120.         *buffer_space_used = 0;
  121.  
  122.         /*
  123.          * Check for NULL object case (could be an uninitialized
  124.          * package element)
  125.          */
  126.         if (!internal_object) {
  127.                 return_ACPI_STATUS(AE_OK);
  128.         }
  129.  
  130.         /* Always clear the external object */
  131.  
  132.         memset(external_object, 0, sizeof(union acpi_object));
  133.  
  134.         /*
  135.          * In general, the external object will be the same type as
  136.          * the internal object
  137.          */
  138.         external_object->type = internal_object->common.type;
  139.  
  140.         /* However, only a limited number of external types are supported */
  141.  
  142.         switch (internal_object->common.type) {
  143.         case ACPI_TYPE_STRING:
  144.  
  145.                 external_object->string.pointer = (char *)data_space;
  146.                 external_object->string.length = internal_object->string.length;
  147.                 *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
  148.                                                                   internal_object->
  149.                                                                   string.
  150.                                                                   length + 1);
  151.  
  152.                 memcpy((void *)data_space,
  153.                        (void *)internal_object->string.pointer,
  154.                        (acpi_size) internal_object->string.length + 1);
  155.                 break;
  156.  
  157.         case ACPI_TYPE_BUFFER:
  158.  
  159.                 external_object->buffer.pointer = data_space;
  160.                 external_object->buffer.length = internal_object->buffer.length;
  161.                 *buffer_space_used =
  162.                     ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string.
  163.                                                  length);
  164.  
  165.                 memcpy((void *)data_space,
  166.                        (void *)internal_object->buffer.pointer,
  167.                        internal_object->buffer.length);
  168.                 break;
  169.  
  170.         case ACPI_TYPE_INTEGER:
  171.  
  172.                 external_object->integer.value = internal_object->integer.value;
  173.                 break;
  174.  
  175.         case ACPI_TYPE_LOCAL_REFERENCE:
  176.  
  177.                 /* This is an object reference. */
  178.  
  179.                 switch (internal_object->reference.class) {
  180.                 case ACPI_REFCLASS_NAME:
  181.                         /*
  182.                          * For namepath, return the object handle ("reference")
  183.                          * We are referring to the namespace node
  184.                          */
  185.                         external_object->reference.handle =
  186.                             internal_object->reference.node;
  187.                         external_object->reference.actual_type =
  188.                             acpi_ns_get_type(internal_object->reference.node);
  189.                         break;
  190.  
  191.                 default:
  192.  
  193.                         /* All other reference types are unsupported */
  194.  
  195.                         return_ACPI_STATUS(AE_TYPE);
  196.                 }
  197.                 break;
  198.  
  199.         case ACPI_TYPE_PROCESSOR:
  200.  
  201.                 external_object->processor.proc_id =
  202.                     internal_object->processor.proc_id;
  203.                 external_object->processor.pblk_address =
  204.                     internal_object->processor.address;
  205.                 external_object->processor.pblk_length =
  206.                     internal_object->processor.length;
  207.                 break;
  208.  
  209.         case ACPI_TYPE_POWER:
  210.  
  211.                 external_object->power_resource.system_level =
  212.                     internal_object->power_resource.system_level;
  213.  
  214.                 external_object->power_resource.resource_order =
  215.                     internal_object->power_resource.resource_order;
  216.                 break;
  217.  
  218.         default:
  219.                 /*
  220.                  * There is no corresponding external object type
  221.                  */
  222.                 ACPI_ERROR((AE_INFO,
  223.                             "Unsupported object type, cannot convert to external object: %s",
  224.                             acpi_ut_get_type_name(internal_object->common.
  225.                                                   type)));
  226.  
  227.                 return_ACPI_STATUS(AE_SUPPORT);
  228.         }
  229.  
  230.         return_ACPI_STATUS(status);
  231. }
  232.  
  233. /*******************************************************************************
  234.  *
  235.  * FUNCTION:    acpi_ut_copy_ielement_to_eelement
  236.  *
  237.  * PARAMETERS:  acpi_pkg_callback
  238.  *
  239.  * RETURN:      Status
  240.  *
  241.  * DESCRIPTION: Copy one package element to another package element
  242.  *
  243.  ******************************************************************************/
  244.  
  245. static acpi_status
  246. acpi_ut_copy_ielement_to_eelement(u8 object_type,
  247.                                   union acpi_operand_object *source_object,
  248.                                   union acpi_generic_state *state,
  249.                                   void *context)
  250. {
  251.         acpi_status status = AE_OK;
  252.         struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
  253.         acpi_size object_space;
  254.         u32 this_index;
  255.         union acpi_object *target_object;
  256.  
  257.         ACPI_FUNCTION_ENTRY();
  258.  
  259.         this_index = state->pkg.index;
  260.         target_object = (union acpi_object *)
  261.             &((union acpi_object *)(state->pkg.dest_object))->package.
  262.             elements[this_index];
  263.  
  264.         switch (object_type) {
  265.         case ACPI_COPY_TYPE_SIMPLE:
  266.                 /*
  267.                  * This is a simple or null object
  268.                  */
  269.                 status = acpi_ut_copy_isimple_to_esimple(source_object,
  270.                                                          target_object,
  271.                                                          info->free_space,
  272.                                                          &object_space);
  273.                 if (ACPI_FAILURE(status)) {
  274.                         return (status);
  275.                 }
  276.                 break;
  277.  
  278.         case ACPI_COPY_TYPE_PACKAGE:
  279.                 /*
  280.                  * Build the package object
  281.                  */
  282.                 target_object->type = ACPI_TYPE_PACKAGE;
  283.                 target_object->package.count = source_object->package.count;
  284.                 target_object->package.elements =
  285.                     ACPI_CAST_PTR(union acpi_object, info->free_space);
  286.  
  287.                 /*
  288.                  * Pass the new package object back to the package walk routine
  289.                  */
  290.                 state->pkg.this_target_obj = target_object;
  291.  
  292.                 /*
  293.                  * Save space for the array of objects (Package elements)
  294.                  * update the buffer length counter
  295.                  */
  296.                 object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
  297.                                                             target_object->
  298.                                                             package.count *
  299.                                                             sizeof(union
  300.                                                                    acpi_object));
  301.                 break;
  302.  
  303.         default:
  304.  
  305.                 return (AE_BAD_PARAMETER);
  306.         }
  307.  
  308.         info->free_space += object_space;
  309.         info->length += object_space;
  310.         return (status);
  311. }
  312.  
  313. /*******************************************************************************
  314.  *
  315.  * FUNCTION:    acpi_ut_copy_ipackage_to_epackage
  316.  *
  317.  * PARAMETERS:  internal_object     - Pointer to the object we are returning
  318.  *              buffer              - Where the object is returned
  319.  *              space_used          - Where the object length is returned
  320.  *
  321.  * RETURN:      Status
  322.  *
  323.  * DESCRIPTION: This function is called to place a package object in a user
  324.  *              buffer. A package object by definition contains other objects.
  325.  *
  326.  *              The buffer is assumed to have sufficient space for the object.
  327.  *              The caller must have verified the buffer length needed using
  328.  *              the acpi_ut_get_object_size function before calling this function.
  329.  *
  330.  ******************************************************************************/
  331.  
  332. static acpi_status
  333. acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
  334.                                   u8 * buffer, acpi_size * space_used)
  335. {
  336.         union acpi_object *external_object;
  337.         acpi_status status;
  338.         struct acpi_pkg_info info;
  339.  
  340.         ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage);
  341.  
  342.         /*
  343.          * First package at head of the buffer
  344.          */
  345.         external_object = ACPI_CAST_PTR(union acpi_object, buffer);
  346.  
  347.         /*
  348.          * Free space begins right after the first package
  349.          */
  350.         info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  351.         info.free_space =
  352.             buffer + ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  353.         info.object_space = 0;
  354.         info.num_packages = 1;
  355.  
  356.         external_object->type = internal_object->common.type;
  357.         external_object->package.count = internal_object->package.count;
  358.         external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
  359.                                                           info.free_space);
  360.  
  361.         /*
  362.          * Leave room for an array of ACPI_OBJECTS in the buffer
  363.          * and move the free space past it
  364.          */
  365.         info.length += (acpi_size) external_object->package.count *
  366.             ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  367.         info.free_space += external_object->package.count *
  368.             ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
  369.  
  370.         status = acpi_ut_walk_package_tree(internal_object, external_object,
  371.                                            acpi_ut_copy_ielement_to_eelement,
  372.                                            &info);
  373.  
  374.         *space_used = info.length;
  375.         return_ACPI_STATUS(status);
  376. }
  377.  
  378. /*******************************************************************************
  379.  *
  380.  * FUNCTION:    acpi_ut_copy_iobject_to_eobject
  381.  *
  382.  * PARAMETERS:  internal_object     - The internal object to be converted
  383.  *              ret_buffer          - Where the object is returned
  384.  *
  385.  * RETURN:      Status
  386.  *
  387.  * DESCRIPTION: This function is called to build an API object to be returned
  388.  *              to the caller.
  389.  *
  390.  ******************************************************************************/
  391.  
  392. acpi_status
  393. acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
  394.                                 struct acpi_buffer *ret_buffer)
  395. {
  396.         acpi_status status;
  397.  
  398.         ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
  399.  
  400.         if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
  401.                 /*
  402.                  * Package object:  Copy all subobjects (including
  403.                  * nested packages)
  404.                  */
  405.                 status = acpi_ut_copy_ipackage_to_epackage(internal_object,
  406.                                                            ret_buffer->pointer,
  407.                                                            &ret_buffer->length);
  408.         } else {
  409.                 /*
  410.                  * Build a simple object (no nested objects)
  411.                  */
  412.                 status = acpi_ut_copy_isimple_to_esimple(internal_object,
  413.                                                          ACPI_CAST_PTR(union
  414.                                                                        acpi_object,
  415.                                                                        ret_buffer->
  416.                                                                        pointer),
  417.                                                          ACPI_ADD_PTR(u8,
  418.                                                                       ret_buffer->
  419.                                                                       pointer,
  420.                                                                       ACPI_ROUND_UP_TO_NATIVE_WORD
  421.                                                                       (sizeof
  422.                                                                        (union
  423.                                                                         acpi_object))),
  424.                                                          &ret_buffer->length);
  425.                 /*
  426.                  * build simple does not include the object size in the length
  427.                  * so we add it in here
  428.                  */
  429.                 ret_buffer->length += sizeof(union acpi_object);
  430.         }
  431.  
  432.         return_ACPI_STATUS(status);
  433. }
  434.  
  435. /*******************************************************************************
  436.  *
  437.  * FUNCTION:    acpi_ut_copy_esimple_to_isimple
  438.  *
  439.  * PARAMETERS:  external_object     - The external object to be converted
  440.  *              ret_internal_object - Where the internal object is returned
  441.  *
  442.  * RETURN:      Status
  443.  *
  444.  * DESCRIPTION: This function copies an external object to an internal one.
  445.  *              NOTE: Pointers can be copied, we don't need to copy data.
  446.  *              (The pointers have to be valid in our address space no matter
  447.  *              what we do with them!)
  448.  *
  449.  ******************************************************************************/
  450.  
  451. static acpi_status
  452. acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
  453.                                 union acpi_operand_object **ret_internal_object)
  454. {
  455.         union acpi_operand_object *internal_object;
  456.  
  457.         ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple);
  458.  
  459.         /*
  460.          * Simple types supported are: String, Buffer, Integer
  461.          */
  462.         switch (external_object->type) {
  463.         case ACPI_TYPE_STRING:
  464.         case ACPI_TYPE_BUFFER:
  465.         case ACPI_TYPE_INTEGER:
  466.         case ACPI_TYPE_LOCAL_REFERENCE:
  467.  
  468.                 internal_object = acpi_ut_create_internal_object((u8)
  469.                                                                  external_object->
  470.                                                                  type);
  471.                 if (!internal_object) {
  472.                         return_ACPI_STATUS(AE_NO_MEMORY);
  473.                 }
  474.                 break;
  475.  
  476.         case ACPI_TYPE_ANY:     /* This is the case for a NULL object */
  477.  
  478.                 *ret_internal_object = NULL;
  479.                 return_ACPI_STATUS(AE_OK);
  480.  
  481.         default:
  482.  
  483.                 /* All other types are not supported */
  484.  
  485.                 ACPI_ERROR((AE_INFO,
  486.                             "Unsupported object type, cannot convert to internal object: %s",
  487.                             acpi_ut_get_type_name(external_object->type)));
  488.  
  489.                 return_ACPI_STATUS(AE_SUPPORT);
  490.         }
  491.  
  492.         /* Must COPY string and buffer contents */
  493.  
  494.         switch (external_object->type) {
  495.         case ACPI_TYPE_STRING:
  496.  
  497.                 internal_object->string.pointer =
  498.                     ACPI_ALLOCATE_ZEROED((acpi_size)
  499.                                          external_object->string.length + 1);
  500.  
  501.                 if (!internal_object->string.pointer) {
  502.                         goto error_exit;
  503.                 }
  504.  
  505.                 memcpy(internal_object->string.pointer,
  506.                        external_object->string.pointer,
  507.                        external_object->string.length);
  508.  
  509.                 internal_object->string.length = external_object->string.length;
  510.                 break;
  511.  
  512.         case ACPI_TYPE_BUFFER:
  513.  
  514.                 internal_object->buffer.pointer =
  515.                     ACPI_ALLOCATE_ZEROED(external_object->buffer.length);
  516.                 if (!internal_object->buffer.pointer) {
  517.                         goto error_exit;
  518.                 }
  519.  
  520.                 memcpy(internal_object->buffer.pointer,
  521.                        external_object->buffer.pointer,
  522.                        external_object->buffer.length);
  523.  
  524.                 internal_object->buffer.length = external_object->buffer.length;
  525.  
  526.                 /* Mark buffer data valid */
  527.  
  528.                 internal_object->buffer.flags |= AOPOBJ_DATA_VALID;
  529.                 break;
  530.  
  531.         case ACPI_TYPE_INTEGER:
  532.  
  533.                 internal_object->integer.value = external_object->integer.value;
  534.                 break;
  535.  
  536.         case ACPI_TYPE_LOCAL_REFERENCE:
  537.  
  538.                 /* An incoming reference is defined to be a namespace node */
  539.  
  540.                 internal_object->reference.class = ACPI_REFCLASS_REFOF;
  541.                 internal_object->reference.object =
  542.                     external_object->reference.handle;
  543.                 break;
  544.  
  545.         default:
  546.  
  547.                 /* Other types can't get here */
  548.  
  549.                 break;
  550.         }
  551.  
  552.         *ret_internal_object = internal_object;
  553.         return_ACPI_STATUS(AE_OK);
  554.  
  555. error_exit:
  556.         acpi_ut_remove_reference(internal_object);
  557.         return_ACPI_STATUS(AE_NO_MEMORY);
  558. }
  559.  
  560. /*******************************************************************************
  561.  *
  562.  * FUNCTION:    acpi_ut_copy_epackage_to_ipackage
  563.  *
  564.  * PARAMETERS:  external_object     - The external object to be converted
  565.  *              internal_object     - Where the internal object is returned
  566.  *
  567.  * RETURN:      Status
  568.  *
  569.  * DESCRIPTION: Copy an external package object to an internal package.
  570.  *              Handles nested packages.
  571.  *
  572.  ******************************************************************************/
  573.  
  574. static acpi_status
  575. acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
  576.                                   union acpi_operand_object **internal_object)
  577. {
  578.         acpi_status status = AE_OK;
  579.         union acpi_operand_object *package_object;
  580.         union acpi_operand_object **package_elements;
  581.         u32 i;
  582.  
  583.         ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
  584.  
  585.         /* Create the package object */
  586.  
  587.         package_object =
  588.             acpi_ut_create_package_object(external_object->package.count);
  589.         if (!package_object) {
  590.                 return_ACPI_STATUS(AE_NO_MEMORY);
  591.         }
  592.  
  593.         package_elements = package_object->package.elements;
  594.  
  595.         /*
  596.          * Recursive implementation. Probably ok, since nested external packages
  597.          * as parameters should be very rare.
  598.          */
  599.         for (i = 0; i < external_object->package.count; i++) {
  600.                 status =
  601.                     acpi_ut_copy_eobject_to_iobject(&external_object->package.
  602.                                                     elements[i],
  603.                                                     &package_elements[i]);
  604.                 if (ACPI_FAILURE(status)) {
  605.  
  606.                         /* Truncate package and delete it */
  607.  
  608.                         package_object->package.count = i;
  609.                         package_elements[i] = NULL;
  610.                         acpi_ut_remove_reference(package_object);
  611.                         return_ACPI_STATUS(status);
  612.                 }
  613.         }
  614.  
  615.         /* Mark package data valid */
  616.  
  617.         package_object->package.flags |= AOPOBJ_DATA_VALID;
  618.  
  619.         *internal_object = package_object;
  620.         return_ACPI_STATUS(status);
  621. }
  622.  
  623. /*******************************************************************************
  624.  *
  625.  * FUNCTION:    acpi_ut_copy_eobject_to_iobject
  626.  *
  627.  * PARAMETERS:  external_object     - The external object to be converted
  628.  *              internal_object     - Where the internal object is returned
  629.  *
  630.  * RETURN:      Status
  631.  *
  632.  * DESCRIPTION: Converts an external object to an internal object.
  633.  *
  634.  ******************************************************************************/
  635.  
  636. acpi_status
  637. acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,
  638.                                 union acpi_operand_object **internal_object)
  639. {
  640.         acpi_status status;
  641.  
  642.         ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);
  643.  
  644.         if (external_object->type == ACPI_TYPE_PACKAGE) {
  645.                 status =
  646.                     acpi_ut_copy_epackage_to_ipackage(external_object,
  647.                                                       internal_object);
  648.         } else {
  649.                 /*
  650.                  * Build a simple object (no nested objects)
  651.                  */
  652.                 status =
  653.                     acpi_ut_copy_esimple_to_isimple(external_object,
  654.                                                     internal_object);
  655.         }
  656.  
  657.         return_ACPI_STATUS(status);
  658. }
  659.  
  660. /*******************************************************************************
  661.  *
  662.  * FUNCTION:    acpi_ut_copy_simple_object
  663.  *
  664.  * PARAMETERS:  source_desc         - The internal object to be copied
  665.  *              dest_desc           - New target object
  666.  *
  667.  * RETURN:      Status
  668.  *
  669.  * DESCRIPTION: Simple copy of one internal object to another. Reference count
  670.  *              of the destination object is preserved.
  671.  *
  672.  ******************************************************************************/
  673.  
  674. static acpi_status
  675. acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
  676.                            union acpi_operand_object *dest_desc)
  677. {
  678.         u16 reference_count;
  679.         union acpi_operand_object *next_object;
  680.         acpi_status status;
  681.         acpi_size copy_size;
  682.  
  683.         /* Save fields from destination that we don't want to overwrite */
  684.  
  685.         reference_count = dest_desc->common.reference_count;
  686.         next_object = dest_desc->common.next_object;
  687.  
  688.         /*
  689.          * Copy the entire source object over the destination object.
  690.          * Note: Source can be either an operand object or namespace node.
  691.          */
  692.         copy_size = sizeof(union acpi_operand_object);
  693.         if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_NAMED) {
  694.                 copy_size = sizeof(struct acpi_namespace_node);
  695.         }
  696.  
  697.         memcpy(ACPI_CAST_PTR(char, dest_desc),
  698.                ACPI_CAST_PTR(char, source_desc), copy_size);
  699.  
  700.         /* Restore the saved fields */
  701.  
  702.         dest_desc->common.reference_count = reference_count;
  703.         dest_desc->common.next_object = next_object;
  704.  
  705.         /* New object is not static, regardless of source */
  706.  
  707.         dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
  708.  
  709.         /* Handle the objects with extra data */
  710.  
  711.         switch (dest_desc->common.type) {
  712.         case ACPI_TYPE_BUFFER:
  713.                 /*
  714.                  * Allocate and copy the actual buffer if and only if:
  715.                  * 1) There is a valid buffer pointer
  716.                  * 2) The buffer has a length > 0
  717.                  */
  718.                 if ((source_desc->buffer.pointer) &&
  719.                     (source_desc->buffer.length)) {
  720.                         dest_desc->buffer.pointer =
  721.                             ACPI_ALLOCATE(source_desc->buffer.length);
  722.                         if (!dest_desc->buffer.pointer) {
  723.                                 return (AE_NO_MEMORY);
  724.                         }
  725.  
  726.                         /* Copy the actual buffer data */
  727.  
  728.                         memcpy(dest_desc->buffer.pointer,
  729.                                source_desc->buffer.pointer,
  730.                                source_desc->buffer.length);
  731.                 }
  732.                 break;
  733.  
  734.         case ACPI_TYPE_STRING:
  735.                 /*
  736.                  * Allocate and copy the actual string if and only if:
  737.                  * 1) There is a valid string pointer
  738.                  * (Pointer to a NULL string is allowed)
  739.                  */
  740.                 if (source_desc->string.pointer) {
  741.                         dest_desc->string.pointer =
  742.                             ACPI_ALLOCATE((acpi_size) source_desc->string.
  743.                                           length + 1);
  744.                         if (!dest_desc->string.pointer) {
  745.                                 return (AE_NO_MEMORY);
  746.                         }
  747.  
  748.                         /* Copy the actual string data */
  749.  
  750.                         memcpy(dest_desc->string.pointer,
  751.                                source_desc->string.pointer,
  752.                                (acpi_size) source_desc->string.length + 1);
  753.                 }
  754.                 break;
  755.  
  756.         case ACPI_TYPE_LOCAL_REFERENCE:
  757.                 /*
  758.                  * We copied the reference object, so we now must add a reference
  759.                  * to the object pointed to by the reference
  760.                  *
  761.                  * DDBHandle reference (from Load/load_table) is a special reference,
  762.                  * it does not have a Reference.Object, so does not need to
  763.                  * increase the reference count
  764.                  */
  765.                 if (source_desc->reference.class == ACPI_REFCLASS_TABLE) {
  766.                         break;
  767.                 }
  768.  
  769.                 acpi_ut_add_reference(source_desc->reference.object);
  770.                 break;
  771.  
  772.         case ACPI_TYPE_REGION:
  773.                 /*
  774.                  * We copied the Region Handler, so we now must add a reference
  775.                  */
  776.                 if (dest_desc->region.handler) {
  777.                         acpi_ut_add_reference(dest_desc->region.handler);
  778.                 }
  779.                 break;
  780.  
  781.                 /*
  782.                  * For Mutex and Event objects, we cannot simply copy the underlying
  783.                  * OS object. We must create a new one.
  784.                  */
  785.         case ACPI_TYPE_MUTEX:
  786.  
  787.                 status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);
  788.                 if (ACPI_FAILURE(status)) {
  789.                         return (status);
  790.                 }
  791.                 break;
  792.  
  793.         case ACPI_TYPE_EVENT:
  794.  
  795.                 status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
  796.                                                   &dest_desc->event.
  797.                                                   os_semaphore);
  798.                 if (ACPI_FAILURE(status)) {
  799.                         return (status);
  800.                 }
  801.                 break;
  802.  
  803.         default:
  804.  
  805.                 /* Nothing to do for other simple objects */
  806.  
  807.                 break;
  808.         }
  809.  
  810.         return (AE_OK);
  811. }
  812.  
  813. /*******************************************************************************
  814.  *
  815.  * FUNCTION:    acpi_ut_copy_ielement_to_ielement
  816.  *
  817.  * PARAMETERS:  acpi_pkg_callback
  818.  *
  819.  * RETURN:      Status
  820.  *
  821.  * DESCRIPTION: Copy one package element to another package element
  822.  *
  823.  ******************************************************************************/
  824.  
  825. static acpi_status
  826. acpi_ut_copy_ielement_to_ielement(u8 object_type,
  827.                                   union acpi_operand_object *source_object,
  828.                                   union acpi_generic_state *state,
  829.                                   void *context)
  830. {
  831.         acpi_status status = AE_OK;
  832.         u32 this_index;
  833.         union acpi_operand_object **this_target_ptr;
  834.         union acpi_operand_object *target_object;
  835.  
  836.         ACPI_FUNCTION_ENTRY();
  837.  
  838.         this_index = state->pkg.index;
  839.         this_target_ptr = (union acpi_operand_object **)
  840.             &state->pkg.dest_object->package.elements[this_index];
  841.  
  842.         switch (object_type) {
  843.         case ACPI_COPY_TYPE_SIMPLE:
  844.  
  845.                 /* A null source object indicates a (legal) null package element */
  846.  
  847.                 if (source_object) {
  848.                         /*
  849.                          * This is a simple object, just copy it
  850.                          */
  851.                         target_object =
  852.                             acpi_ut_create_internal_object(source_object->
  853.                                                            common.type);
  854.                         if (!target_object) {
  855.                                 return (AE_NO_MEMORY);
  856.                         }
  857.  
  858.                         status =
  859.                             acpi_ut_copy_simple_object(source_object,
  860.                                                        target_object);
  861.                         if (ACPI_FAILURE(status)) {
  862.                                 goto error_exit;
  863.                         }
  864.  
  865.                         *this_target_ptr = target_object;
  866.                 } else {
  867.                         /* Pass through a null element */
  868.  
  869.                         *this_target_ptr = NULL;
  870.                 }
  871.                 break;
  872.  
  873.         case ACPI_COPY_TYPE_PACKAGE:
  874.                 /*
  875.                  * This object is a package - go down another nesting level
  876.                  * Create and build the package object
  877.                  */
  878.                 target_object =
  879.                     acpi_ut_create_package_object(source_object->package.count);
  880.                 if (!target_object) {
  881.                         return (AE_NO_MEMORY);
  882.                 }
  883.  
  884.                 target_object->common.flags = source_object->common.flags;
  885.  
  886.                 /* Pass the new package object back to the package walk routine */
  887.  
  888.                 state->pkg.this_target_obj = target_object;
  889.  
  890.                 /* Store the object pointer in the parent package object */
  891.  
  892.                 *this_target_ptr = target_object;
  893.                 break;
  894.  
  895.         default:
  896.  
  897.                 return (AE_BAD_PARAMETER);
  898.         }
  899.  
  900.         return (status);
  901.  
  902. error_exit:
  903.         acpi_ut_remove_reference(target_object);
  904.         return (status);
  905. }
  906.  
  907. /*******************************************************************************
  908.  *
  909.  * FUNCTION:    acpi_ut_copy_ipackage_to_ipackage
  910.  *
  911.  * PARAMETERS:  source_obj      - Pointer to the source package object
  912.  *              dest_obj        - Where the internal object is returned
  913.  *              walk_state      - Current Walk state descriptor
  914.  *
  915.  * RETURN:      Status
  916.  *
  917.  * DESCRIPTION: This function is called to copy an internal package object
  918.  *              into another internal package object.
  919.  *
  920.  ******************************************************************************/
  921.  
  922. static acpi_status
  923. acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
  924.                                   union acpi_operand_object *dest_obj,
  925.                                   struct acpi_walk_state *walk_state)
  926. {
  927.         acpi_status status = AE_OK;
  928.  
  929.         ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
  930.  
  931.         dest_obj->common.type = source_obj->common.type;
  932.         dest_obj->common.flags = source_obj->common.flags;
  933.         dest_obj->package.count = source_obj->package.count;
  934.  
  935.         /*
  936.          * Create the object array and walk the source package tree
  937.          */
  938.         dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
  939.                                                            source_obj->package.
  940.                                                            count +
  941.                                                            1) * sizeof(void *));
  942.         if (!dest_obj->package.elements) {
  943.                 ACPI_ERROR((AE_INFO, "Package allocation failure"));
  944.                 return_ACPI_STATUS(AE_NO_MEMORY);
  945.         }
  946.  
  947.         /*
  948.          * Copy the package element-by-element by walking the package "tree".
  949.          * This handles nested packages of arbitrary depth.
  950.          */
  951.         status = acpi_ut_walk_package_tree(source_obj, dest_obj,
  952.                                            acpi_ut_copy_ielement_to_ielement,
  953.                                            walk_state);
  954.         if (ACPI_FAILURE(status)) {
  955.  
  956.                 /* On failure, delete the destination package object */
  957.  
  958.                 acpi_ut_remove_reference(dest_obj);
  959.         }
  960.  
  961.         return_ACPI_STATUS(status);
  962. }
  963.  
  964. /*******************************************************************************
  965.  *
  966.  * FUNCTION:    acpi_ut_copy_iobject_to_iobject
  967.  *
  968.  * PARAMETERS:  source_desc         - The internal object to be copied
  969.  *              dest_desc           - Where the copied object is returned
  970.  *              walk_state          - Current walk state
  971.  *
  972.  * RETURN:      Status
  973.  *
  974.  * DESCRIPTION: Copy an internal object to a new internal object
  975.  *
  976.  ******************************************************************************/
  977.  
  978. acpi_status
  979. acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
  980.                                 union acpi_operand_object **dest_desc,
  981.                                 struct acpi_walk_state *walk_state)
  982. {
  983.         acpi_status status = AE_OK;
  984.  
  985.         ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject);
  986.  
  987.         /* Create the top level object */
  988.  
  989.         *dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
  990.         if (!*dest_desc) {
  991.                 return_ACPI_STATUS(AE_NO_MEMORY);
  992.         }
  993.  
  994.         /* Copy the object and possible subobjects */
  995.  
  996.         if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
  997.                 status =
  998.                     acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
  999.                                                       walk_state);
  1000.         } else {
  1001.                 status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
  1002.         }
  1003.  
  1004.         /* Delete the allocated object if copy failed */
  1005.  
  1006.         if (ACPI_FAILURE(status)) {
  1007.                 acpi_ut_remove_reference(*dest_desc);
  1008.         }
  1009.  
  1010.         return_ACPI_STATUS(status);
  1011. }
  1012.