root/drivers/acpi/acpica/exstorob.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ex_store_string_to_string

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: exstorob - AML object store support, store to object
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "acinterp.h"
  13 
  14 #define _COMPONENT          ACPI_EXECUTER
  15 ACPI_MODULE_NAME("exstorob")
  16 
  17 /*******************************************************************************
  18  *
  19  * FUNCTION:    acpi_ex_store_buffer_to_buffer
  20  *
  21  * PARAMETERS:  source_desc         - Source object to copy
  22  *              target_desc         - Destination object of the copy
  23  *
  24  * RETURN:      Status
  25  *
  26  * DESCRIPTION: Copy a buffer object to another buffer object.
  27  *
  28  ******************************************************************************/
  29 acpi_status
  30 acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
  31                                union acpi_operand_object *target_desc)
  32 {
  33         u32 length;
  34         u8 *buffer;
  35 
  36         ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc);
  37 
  38         /* If Source and Target are the same, just return */
  39 
  40         if (source_desc == target_desc) {
  41                 return_ACPI_STATUS(AE_OK);
  42         }
  43 
  44         /* We know that source_desc is a buffer by now */
  45 
  46         buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
  47         length = source_desc->buffer.length;
  48 
  49         /*
  50          * If target is a buffer of length zero or is a static buffer,
  51          * allocate a new buffer of the proper length
  52          */
  53         if ((target_desc->buffer.length == 0) ||
  54             (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
  55                 target_desc->buffer.pointer = ACPI_ALLOCATE(length);
  56                 if (!target_desc->buffer.pointer) {
  57                         return_ACPI_STATUS(AE_NO_MEMORY);
  58                 }
  59 
  60                 target_desc->buffer.length = length;
  61         }
  62 
  63         /* Copy source buffer to target buffer */
  64 
  65         if (length <= target_desc->buffer.length) {
  66 
  67                 /* Clear existing buffer and copy in the new one */
  68 
  69                 memset(target_desc->buffer.pointer, 0,
  70                        target_desc->buffer.length);
  71                 memcpy(target_desc->buffer.pointer, buffer, length);
  72 
  73 #ifdef ACPI_OBSOLETE_BEHAVIOR
  74                 /*
  75                  * NOTE: ACPI versions up to 3.0 specified that the buffer must be
  76                  * truncated if the string is smaller than the buffer. However, "other"
  77                  * implementations of ACPI never did this and thus became the defacto
  78                  * standard. ACPI 3.0A changes this behavior such that the buffer
  79                  * is no longer truncated.
  80                  */
  81 
  82                 /*
  83                  * OBSOLETE BEHAVIOR:
  84                  * If the original source was a string, we must truncate the buffer,
  85                  * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
  86                  * copy must not truncate the original buffer.
  87                  */
  88                 if (original_src_type == ACPI_TYPE_STRING) {
  89 
  90                         /* Set the new length of the target */
  91 
  92                         target_desc->buffer.length = length;
  93                 }
  94 #endif
  95         } else {
  96                 /* Truncate the source, copy only what will fit */
  97 
  98                 memcpy(target_desc->buffer.pointer, buffer,
  99                        target_desc->buffer.length);
 100 
 101                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 102                                   "Truncating source buffer from %X to %X\n",
 103                                   length, target_desc->buffer.length));
 104         }
 105 
 106         /* Copy flags */
 107 
 108         target_desc->buffer.flags = source_desc->buffer.flags;
 109         target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
 110         return_ACPI_STATUS(AE_OK);
 111 }
 112 
 113 /*******************************************************************************
 114  *
 115  * FUNCTION:    acpi_ex_store_string_to_string
 116  *
 117  * PARAMETERS:  source_desc         - Source object to copy
 118  *              target_desc         - Destination object of the copy
 119  *
 120  * RETURN:      Status
 121  *
 122  * DESCRIPTION: Copy a String object to another String object
 123  *
 124  ******************************************************************************/
 125 
 126 acpi_status
 127 acpi_ex_store_string_to_string(union acpi_operand_object *source_desc,
 128                                union acpi_operand_object *target_desc)
 129 {
 130         u32 length;
 131         u8 *buffer;
 132 
 133         ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc);
 134 
 135         /* If Source and Target are the same, just return */
 136 
 137         if (source_desc == target_desc) {
 138                 return_ACPI_STATUS(AE_OK);
 139         }
 140 
 141         /* We know that source_desc is a string by now */
 142 
 143         buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer);
 144         length = source_desc->string.length;
 145 
 146         /*
 147          * Replace existing string value if it will fit and the string
 148          * pointer is not a static pointer (part of an ACPI table)
 149          */
 150         if ((length < target_desc->string.length) &&
 151             (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
 152                 /*
 153                  * String will fit in existing non-static buffer.
 154                  * Clear old string and copy in the new one
 155                  */
 156                 memset(target_desc->string.pointer, 0,
 157                        (acpi_size)target_desc->string.length + 1);
 158                 memcpy(target_desc->string.pointer, buffer, length);
 159         } else {
 160                 /*
 161                  * Free the current buffer, then allocate a new buffer
 162                  * large enough to hold the value
 163                  */
 164                 if (target_desc->string.pointer &&
 165                     (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
 166 
 167                         /* Only free if not a pointer into the DSDT */
 168 
 169                         ACPI_FREE(target_desc->string.pointer);
 170                 }
 171 
 172                 target_desc->string.pointer =
 173                     ACPI_ALLOCATE_ZEROED((acpi_size)length + 1);
 174 
 175                 if (!target_desc->string.pointer) {
 176                         return_ACPI_STATUS(AE_NO_MEMORY);
 177                 }
 178 
 179                 target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
 180                 memcpy(target_desc->string.pointer, buffer, length);
 181         }
 182 
 183         /* Set the new target length */
 184 
 185         target_desc->string.length = length;
 186         return_ACPI_STATUS(AE_OK);
 187 }

/* [<][>][^][v][top][bottom][index][help] */