LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - utcopy.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 140 289 48.4 %
Date: 2022-03-28 16:04:14 Functions: 9 11 81.8 %
Branches: 29 84 34.5 %

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

Generated by: LCOV version 1.14