LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - exfldio.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 147 256 57.4 %
Date: 2022-04-01 14:17:54 Functions: 6 6 100.0 %
Branches: 35 105 33.3 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: exfldio - Aml Field I/O
       5                 :            :  *
       6                 :            :  * Copyright (C) 2000 - 2020, Intel Corp.
       7                 :            :  *
       8                 :            :  *****************************************************************************/
       9                 :            : 
      10                 :            : #include <acpi/acpi.h>
      11                 :            : #include "accommon.h"
      12                 :            : #include "acinterp.h"
      13                 :            : #include "amlcode.h"
      14                 :            : #include "acevents.h"
      15                 :            : #include "acdispat.h"
      16                 :            : 
      17                 :            : #define _COMPONENT          ACPI_EXECUTER
      18                 :            : ACPI_MODULE_NAME("exfldio")
      19                 :            : 
      20                 :            : /* Local prototypes */
      21                 :            : static acpi_status
      22                 :            : acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
      23                 :            :                        u32 field_datum_byte_offset, u64 *value, u32 read_write);
      24                 :            : 
      25                 :            : static u8
      26                 :            : acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value);
      27                 :            : 
      28                 :            : static acpi_status
      29                 :            : acpi_ex_setup_region(union acpi_operand_object *obj_desc,
      30                 :            :                      u32 field_datum_byte_offset);
      31                 :            : 
      32                 :            : /*******************************************************************************
      33                 :            :  *
      34                 :            :  * FUNCTION:    acpi_ex_setup_region
      35                 :            :  *
      36                 :            :  * PARAMETERS:  obj_desc                - Field to be read or written
      37                 :            :  *              field_datum_byte_offset - Byte offset of this datum within the
      38                 :            :  *                                        parent field
      39                 :            :  *
      40                 :            :  * RETURN:      Status
      41                 :            :  *
      42                 :            :  * DESCRIPTION: Common processing for acpi_ex_extract_from_field and
      43                 :            :  *              acpi_ex_insert_into_field. Initialize the Region if necessary and
      44                 :            :  *              validate the request.
      45                 :            :  *
      46                 :            :  ******************************************************************************/
      47                 :            : 
      48                 :            : static acpi_status
      49                 :        660 : acpi_ex_setup_region(union acpi_operand_object *obj_desc,
      50                 :            :                      u32 field_datum_byte_offset)
      51                 :            : {
      52                 :        660 :         acpi_status status = AE_OK;
      53                 :        660 :         union acpi_operand_object *rgn_desc;
      54                 :        660 :         u8 space_id;
      55                 :            : 
      56                 :        660 :         ACPI_FUNCTION_TRACE_U32(ex_setup_region, field_datum_byte_offset);
      57                 :            : 
      58                 :        660 :         rgn_desc = obj_desc->common_field.region_obj;
      59                 :            : 
      60                 :            :         /* We must have a valid region */
      61                 :            : 
      62         [ -  + ]:        660 :         if (rgn_desc->common.type != ACPI_TYPE_REGION) {
      63                 :          0 :                 ACPI_ERROR((AE_INFO, "Needed Region, found type 0x%X (%s)",
      64                 :            :                             rgn_desc->common.type,
      65                 :            :                             acpi_ut_get_object_type_name(rgn_desc)));
      66                 :            : 
      67                 :          0 :                 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
      68                 :            :         }
      69                 :            : 
      70                 :        660 :         space_id = rgn_desc->region.space_id;
      71                 :            : 
      72                 :            :         /* Validate the Space ID */
      73                 :            : 
      74         [ -  + ]:        660 :         if (!acpi_is_valid_space_id(space_id)) {
      75                 :          0 :                 ACPI_ERROR((AE_INFO,
      76                 :            :                             "Invalid/unknown Address Space ID: 0x%2.2X",
      77                 :            :                             space_id));
      78                 :          0 :                 return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
      79                 :            :         }
      80                 :            : 
      81                 :            :         /*
      82                 :            :          * If the Region Address and Length have not been previously evaluated,
      83                 :            :          * evaluate them now and save the results.
      84                 :            :          */
      85         [ -  + ]:        660 :         if (!(rgn_desc->common.flags & AOPOBJ_DATA_VALID)) {
      86                 :          0 :                 status = acpi_ds_get_region_arguments(rgn_desc);
      87         [ #  # ]:          0 :                 if (ACPI_FAILURE(status)) {
      88                 :            :                         return_ACPI_STATUS(status);
      89                 :            :                 }
      90                 :            :         }
      91                 :            : 
      92                 :            :         /*
      93                 :            :          * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear
      94                 :            :          * address space and the request cannot be directly validated
      95                 :            :          */
      96                 :        660 :         if (space_id == ACPI_ADR_SPACE_SMBUS ||
      97   [ +  -  +  - ]:        660 :             space_id == ACPI_ADR_SPACE_GSBUS ||
      98                 :            :             space_id == ACPI_ADR_SPACE_IPMI) {
      99                 :            : 
     100                 :            :                 /* SMBus or IPMI has a non-linear address space */
     101                 :            : 
     102                 :            :                 return_ACPI_STATUS(AE_OK);
     103                 :            :         }
     104                 :            : #ifdef ACPI_UNDER_DEVELOPMENT
     105                 :            :         /*
     106                 :            :          * If the Field access is any_acc, we can now compute the optimal
     107                 :            :          * access (because we know know the length of the parent region)
     108                 :            :          */
     109                 :            :         if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
     110                 :            :                 if (ACPI_FAILURE(status)) {
     111                 :            :                         return_ACPI_STATUS(status);
     112                 :            :                 }
     113                 :            :         }
     114                 :            : #endif
     115                 :            : 
     116                 :            :         /*
     117                 :            :          * Validate the request. The entire request from the byte offset for a
     118                 :            :          * length of one field datum (access width) must fit within the region.
     119                 :            :          * (Region length is specified in bytes)
     120                 :            :          */
     121                 :        660 :         if (rgn_desc->region.length <
     122                 :        660 :             (obj_desc->common_field.base_byte_offset + field_datum_byte_offset +
     123         [ -  + ]:        660 :              obj_desc->common_field.access_byte_width)) {
     124         [ #  # ]:          0 :                 if (acpi_gbl_enable_interpreter_slack) {
     125                 :            :                         /*
     126                 :            :                          * Slack mode only:  We will go ahead and allow access to this
     127                 :            :                          * field if it is within the region length rounded up to the next
     128                 :            :                          * access width boundary. acpi_size cast for 64-bit compile.
     129                 :            :                          */
     130                 :          0 :                         if (ACPI_ROUND_UP(rgn_desc->region.length,
     131                 :            :                                           obj_desc->common_field.
     132                 :            :                                           access_byte_width) >=
     133                 :          0 :                             ((acpi_size)obj_desc->common_field.
     134                 :          0 :                              base_byte_offset +
     135         [ #  # ]:          0 :                              obj_desc->common_field.access_byte_width +
     136                 :            :                              field_datum_byte_offset)) {
     137                 :            :                                 return_ACPI_STATUS(AE_OK);
     138                 :            :                         }
     139                 :            :                 }
     140                 :            : 
     141         [ #  # ]:          0 :                 if (rgn_desc->region.length <
     142                 :            :                     obj_desc->common_field.access_byte_width) {
     143                 :            :                         /*
     144                 :            :                          * This is the case where the access_type (acc_word, etc.) is wider
     145                 :            :                          * than the region itself. For example, a region of length one
     146                 :            :                          * byte, and a field with Dword access specified.
     147                 :            :                          */
     148                 :          0 :                         ACPI_ERROR((AE_INFO,
     149                 :            :                                     "Field [%4.4s] access width (%u bytes) "
     150                 :            :                                     "too large for region [%4.4s] (length %u)",
     151                 :            :                                     acpi_ut_get_node_name(obj_desc->
     152                 :            :                                                           common_field.node),
     153                 :            :                                     obj_desc->common_field.access_byte_width,
     154                 :            :                                     acpi_ut_get_node_name(rgn_desc->region.
     155                 :            :                                                           node),
     156                 :            :                                     rgn_desc->region.length));
     157                 :            :                 }
     158                 :            : 
     159                 :            :                 /*
     160                 :            :                  * Offset rounded up to next multiple of field width
     161                 :            :                  * exceeds region length, indicate an error
     162                 :            :                  */
     163                 :          0 :                 ACPI_ERROR((AE_INFO,
     164                 :            :                             "Field [%4.4s] Base+Offset+Width %u+%u+%u "
     165                 :            :                             "is beyond end of region [%4.4s] (length %u)",
     166                 :            :                             acpi_ut_get_node_name(obj_desc->common_field.node),
     167                 :            :                             obj_desc->common_field.base_byte_offset,
     168                 :            :                             field_datum_byte_offset,
     169                 :            :                             obj_desc->common_field.access_byte_width,
     170                 :            :                             acpi_ut_get_node_name(rgn_desc->region.node),
     171                 :            :                             rgn_desc->region.length));
     172                 :            : 
     173                 :          0 :                 return_ACPI_STATUS(AE_AML_REGION_LIMIT);
     174                 :            :         }
     175                 :            : 
     176                 :            :         return_ACPI_STATUS(AE_OK);
     177                 :            : }
     178                 :            : 
     179                 :            : /*******************************************************************************
     180                 :            :  *
     181                 :            :  * FUNCTION:    acpi_ex_access_region
     182                 :            :  *
     183                 :            :  * PARAMETERS:  obj_desc                - Field to be read
     184                 :            :  *              field_datum_byte_offset - Byte offset of this datum within the
     185                 :            :  *                                        parent field
     186                 :            :  *              value                   - Where to store value (must at least
     187                 :            :  *                                        64 bits)
     188                 :            :  *              function                - Read or Write flag plus other region-
     189                 :            :  *                                        dependent flags
     190                 :            :  *
     191                 :            :  * RETURN:      Status
     192                 :            :  *
     193                 :            :  * DESCRIPTION: Read or Write a single field datum to an Operation Region.
     194                 :            :  *
     195                 :            :  ******************************************************************************/
     196                 :            : 
     197                 :            : acpi_status
     198                 :        660 : acpi_ex_access_region(union acpi_operand_object *obj_desc,
     199                 :            :                       u32 field_datum_byte_offset, u64 *value, u32 function)
     200                 :            : {
     201                 :        660 :         acpi_status status;
     202                 :        660 :         union acpi_operand_object *rgn_desc;
     203                 :        660 :         u32 region_offset;
     204                 :            : 
     205                 :        660 :         ACPI_FUNCTION_TRACE(ex_access_region);
     206                 :            : 
     207                 :            :         /*
     208                 :            :          * Ensure that the region operands are fully evaluated and verify
     209                 :            :          * the validity of the request
     210                 :            :          */
     211                 :        660 :         status = acpi_ex_setup_region(obj_desc, field_datum_byte_offset);
     212         [ +  - ]:        660 :         if (ACPI_FAILURE(status)) {
     213                 :            :                 return_ACPI_STATUS(status);
     214                 :            :         }
     215                 :            : 
     216                 :            :         /*
     217                 :            :          * The physical address of this field datum is:
     218                 :            :          *
     219                 :            :          * 1) The base of the region, plus
     220                 :            :          * 2) The base offset of the field, plus
     221                 :            :          * 3) The current offset into the field
     222                 :            :          */
     223                 :        660 :         rgn_desc = obj_desc->common_field.region_obj;
     224                 :        660 :         region_offset =
     225                 :        660 :             obj_desc->common_field.base_byte_offset + field_datum_byte_offset;
     226                 :            : 
     227                 :        660 :         if ((function & ACPI_IO_MASK) == ACPI_READ) {
     228                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "[READ]"));
     229                 :            :         } else {
     230                 :        660 :                 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "[WRITE]"));
     231                 :            :         }
     232                 :            : 
     233                 :            :         ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD,
     234                 :            :                               " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n",
     235                 :            :                               acpi_ut_get_region_name(rgn_desc->region.
     236                 :            :                                                       space_id),
     237                 :            :                               rgn_desc->region.space_id,
     238                 :            :                               obj_desc->common_field.access_byte_width,
     239                 :            :                               obj_desc->common_field.base_byte_offset,
     240                 :            :                               field_datum_byte_offset,
     241                 :            :                               ACPI_FORMAT_UINT64(rgn_desc->region.address +
     242                 :        660 :                                                  region_offset)));
     243                 :            : 
     244                 :            :         /* Invoke the appropriate address_space/op_region handler */
     245                 :            : 
     246                 :        660 :         status = acpi_ev_address_space_dispatch(rgn_desc, obj_desc,
     247                 :            :                                                 function, region_offset,
     248                 :        660 :                                                 ACPI_MUL_8(obj_desc->
     249                 :            :                                                            common_field.
     250                 :            :                                                            access_byte_width),
     251                 :            :                                                 value);
     252                 :            : 
     253         [ -  + ]:        660 :         if (ACPI_FAILURE(status)) {
     254         [ #  # ]:          0 :                 if (status == AE_NOT_IMPLEMENTED) {
     255                 :          0 :                         ACPI_ERROR((AE_INFO,
     256                 :            :                                     "Region %s (ID=%u) not implemented",
     257                 :            :                                     acpi_ut_get_region_name(rgn_desc->region.
     258                 :            :                                                             space_id),
     259                 :            :                                     rgn_desc->region.space_id));
     260         [ #  # ]:          0 :                 } else if (status == AE_NOT_EXIST) {
     261                 :          0 :                         ACPI_ERROR((AE_INFO,
     262                 :            :                                     "Region %s (ID=%u) has no handler",
     263                 :            :                                     acpi_ut_get_region_name(rgn_desc->region.
     264                 :            :                                                             space_id),
     265                 :            :                                     rgn_desc->region.space_id));
     266                 :            :                 }
     267                 :            :         }
     268                 :            : 
     269                 :            :         return_ACPI_STATUS(status);
     270                 :            : }
     271                 :            : 
     272                 :            : /*******************************************************************************
     273                 :            :  *
     274                 :            :  * FUNCTION:    acpi_ex_register_overflow
     275                 :            :  *
     276                 :            :  * PARAMETERS:  obj_desc                - Register(Field) to be written
     277                 :            :  *              value                   - Value to be stored
     278                 :            :  *
     279                 :            :  * RETURN:      TRUE if value overflows the field, FALSE otherwise
     280                 :            :  *
     281                 :            :  * DESCRIPTION: Check if a value is out of range of the field being written.
     282                 :            :  *              Used to check if the values written to Index and Bank registers
     283                 :            :  *              are out of range. Normally, the value is simply truncated
     284                 :            :  *              to fit the field, but this case is most likely a serious
     285                 :            :  *              coding error in the ASL.
     286                 :            :  *
     287                 :            :  ******************************************************************************/
     288                 :            : 
     289                 :            : static u8
     290                 :            : acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value)
     291                 :            : {
     292                 :            : 
     293                 :            :         if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) {
     294                 :            :                 /*
     295                 :            :                  * The field is large enough to hold the maximum integer, so we can
     296                 :            :                  * never overflow it.
     297                 :            :                  */
     298                 :            :                 return (FALSE);
     299                 :            :         }
     300                 :            : 
     301                 :            :         if (value >= ((u64) 1 << obj_desc->common_field.bit_length)) {
     302                 :            :                 /*
     303                 :            :                  * The Value is larger than the maximum value that can fit into
     304                 :            :                  * the register.
     305                 :            :                  */
     306                 :            :                 ACPI_ERROR((AE_INFO,
     307                 :            :                             "Index value 0x%8.8X%8.8X overflows field width 0x%X",
     308                 :            :                             ACPI_FORMAT_UINT64(value),
     309                 :            :                             obj_desc->common_field.bit_length));
     310                 :            : 
     311                 :            :                 return (TRUE);
     312                 :            :         }
     313                 :            : 
     314                 :            :         /* The Value will fit into the field with no truncation */
     315                 :            : 
     316                 :            :         return (FALSE);
     317                 :            : }
     318                 :            : 
     319                 :            : /*******************************************************************************
     320                 :            :  *
     321                 :            :  * FUNCTION:    acpi_ex_field_datum_io
     322                 :            :  *
     323                 :            :  * PARAMETERS:  obj_desc                - Field to be read
     324                 :            :  *              field_datum_byte_offset - Byte offset of this datum within the
     325                 :            :  *                                        parent field
     326                 :            :  *              value                   - Where to store value (must be 64 bits)
     327                 :            :  *              read_write              - Read or Write flag
     328                 :            :  *
     329                 :            :  * RETURN:      Status
     330                 :            :  *
     331                 :            :  * DESCRIPTION: Read or Write a single datum of a field. The field_type is
     332                 :            :  *              demultiplexed here to handle the different types of fields
     333                 :            :  *              (buffer_field, region_field, index_field, bank_field)
     334                 :            :  *
     335                 :            :  ******************************************************************************/
     336                 :            : 
     337                 :            : static acpi_status
     338                 :        770 : acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
     339                 :            :                        u32 field_datum_byte_offset, u64 *value, u32 read_write)
     340                 :            : {
     341                 :        770 :         acpi_status status;
     342                 :        770 :         u64 local_value;
     343                 :            : 
     344                 :        770 :         ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset);
     345                 :            : 
     346         [ +  + ]:        770 :         if (read_write == ACPI_READ) {
     347         [ -  + ]:        583 :                 if (!value) {
     348                 :          0 :                         local_value = 0;
     349                 :            : 
     350                 :            :                         /* To support reads without saving return value */
     351                 :          0 :                         value = &local_value;
     352                 :            :                 }
     353                 :            : 
     354                 :            :                 /* Clear the entire return buffer first, [Very Important!] */
     355                 :            : 
     356                 :        583 :                 *value = 0;
     357                 :            :         }
     358                 :            : 
     359                 :            :         /*
     360                 :            :          * The four types of fields are:
     361                 :            :          *
     362                 :            :          * buffer_field - Read/write from/to a Buffer
     363                 :            :          * region_field - Read/write from/to a Operation Region.
     364                 :            :          * bank_field  - Write to a Bank Register, then read/write from/to an
     365                 :            :          *               operation_region
     366                 :            :          * index_field - Write to an Index Register, then read/write from/to a
     367                 :            :          *               Data Register
     368                 :            :          */
     369   [ +  -  +  -  :        770 :         switch (obj_desc->common.type) {
                      - ]
     370                 :        110 :         case ACPI_TYPE_BUFFER_FIELD:
     371                 :            :                 /*
     372                 :            :                  * If the buffer_field arguments have not been previously evaluated,
     373                 :            :                  * evaluate them now and save the results.
     374                 :            :                  */
     375         [ -  + ]:        110 :                 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
     376                 :          0 :                         status = acpi_ds_get_buffer_field_arguments(obj_desc);
     377         [ #  # ]:          0 :                         if (ACPI_FAILURE(status)) {
     378                 :            :                                 return_ACPI_STATUS(status);
     379                 :            :                         }
     380                 :            :                 }
     381                 :            : 
     382         [ +  + ]:        110 :                 if (read_write == ACPI_READ) {
     383                 :            :                         /*
     384                 :            :                          * Copy the data from the source buffer.
     385                 :            :                          * Length is the field width in bytes.
     386                 :            :                          */
     387                 :         11 :                         memcpy(value,
     388                 :         11 :                                (obj_desc->buffer_field.buffer_obj)->buffer.
     389                 :            :                                pointer +
     390                 :         11 :                                obj_desc->buffer_field.base_byte_offset +
     391                 :            :                                field_datum_byte_offset,
     392                 :         11 :                                obj_desc->common_field.access_byte_width);
     393                 :            :                 } else {
     394                 :            :                         /*
     395                 :            :                          * Copy the data to the target buffer.
     396                 :            :                          * Length is the field width in bytes.
     397                 :            :                          */
     398                 :         99 :                         memcpy((obj_desc->buffer_field.buffer_obj)->buffer.
     399                 :            :                                pointer +
     400                 :         99 :                                obj_desc->buffer_field.base_byte_offset +
     401                 :            :                                field_datum_byte_offset, value,
     402                 :         99 :                                obj_desc->common_field.access_byte_width);
     403                 :            :                 }
     404                 :            : 
     405                 :            :                 status = AE_OK;
     406                 :            :                 break;
     407                 :            : 
     408                 :          0 :         case ACPI_TYPE_LOCAL_BANK_FIELD:
     409                 :            :                 /*
     410                 :            :                  * Ensure that the bank_value is not beyond the capacity of
     411                 :            :                  * the register
     412                 :            :                  */
     413         [ #  # ]:          0 :                 if (acpi_ex_register_overflow(obj_desc->bank_field.bank_obj,
     414                 :          0 :                                               (u64) obj_desc->bank_field.
     415                 :            :                                               value)) {
     416                 :            :                         return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);
     417                 :            :                 }
     418                 :            : 
     419                 :            :                 /*
     420                 :            :                  * For bank_fields, we must write the bank_value to the bank_register
     421                 :            :                  * (itself a region_field) before we can access the data.
     422                 :            :                  */
     423                 :          0 :                 status =
     424                 :          0 :                     acpi_ex_insert_into_field(obj_desc->bank_field.bank_obj,
     425                 :          0 :                                               &obj_desc->bank_field.value,
     426                 :            :                                               sizeof(obj_desc->bank_field.
     427                 :            :                                                      value));
     428         [ #  # ]:          0 :                 if (ACPI_FAILURE(status)) {
     429                 :            :                         return_ACPI_STATUS(status);
     430                 :            :                 }
     431                 :            : 
     432                 :            :                 /*
     433                 :            :                  * Now that the Bank has been selected, fall through to the
     434                 :            :                  * region_field case and write the datum to the Operation Region
     435                 :            :                  */
     436                 :            : 
     437                 :            :                 /*lint -fallthrough */
     438                 :            : 
     439                 :            :         case ACPI_TYPE_LOCAL_REGION_FIELD:
     440                 :            :                 /*
     441                 :            :                  * For simple region_fields, we just directly access the owning
     442                 :            :                  * Operation Region.
     443                 :            :                  */
     444                 :        660 :                 status =
     445                 :        660 :                     acpi_ex_access_region(obj_desc, field_datum_byte_offset,
     446                 :            :                                           value, read_write);
     447                 :        660 :                 break;
     448                 :            : 
     449                 :          0 :         case ACPI_TYPE_LOCAL_INDEX_FIELD:
     450                 :            :                 /*
     451                 :            :                  * Ensure that the index_value is not beyond the capacity of
     452                 :            :                  * the register
     453                 :            :                  */
     454         [ #  # ]:          0 :                 if (acpi_ex_register_overflow(obj_desc->index_field.index_obj,
     455                 :          0 :                                               (u64) obj_desc->index_field.
     456                 :            :                                               value)) {
     457                 :            :                         return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);
     458                 :            :                 }
     459                 :            : 
     460                 :            :                 /* Write the index value to the index_register (itself a region_field) */
     461                 :            : 
     462                 :          0 :                 field_datum_byte_offset += obj_desc->index_field.value;
     463                 :            : 
     464                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
     465                 :            :                                   "Write to Index Register: Value %8.8X\n",
     466                 :          0 :                                   field_datum_byte_offset));
     467                 :            : 
     468                 :          0 :                 status =
     469                 :          0 :                     acpi_ex_insert_into_field(obj_desc->index_field.index_obj,
     470                 :            :                                               &field_datum_byte_offset,
     471                 :            :                                               sizeof(field_datum_byte_offset));
     472         [ #  # ]:          0 :                 if (ACPI_FAILURE(status)) {
     473                 :            :                         return_ACPI_STATUS(status);
     474                 :            :                 }
     475                 :            : 
     476         [ #  # ]:          0 :                 if (read_write == ACPI_READ) {
     477                 :            : 
     478                 :            :                         /* Read the datum from the data_register */
     479                 :            : 
     480                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
     481                 :          0 :                                           "Read from Data Register\n"));
     482                 :            : 
     483                 :          0 :                         status =
     484                 :          0 :                             acpi_ex_extract_from_field(obj_desc->index_field.
     485                 :            :                                                        data_obj, value,
     486                 :            :                                                        sizeof(u64));
     487                 :            :                 } else {
     488                 :            :                         /* Write the datum to the data_register */
     489                 :            : 
     490                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
     491                 :            :                                           "Write to Data Register: Value %8.8X%8.8X\n",
     492                 :          0 :                                           ACPI_FORMAT_UINT64(*value)));
     493                 :            : 
     494                 :          0 :                         status =
     495                 :          0 :                             acpi_ex_insert_into_field(obj_desc->index_field.
     496                 :            :                                                       data_obj, value,
     497                 :            :                                                       sizeof(u64));
     498                 :            :                 }
     499                 :            :                 break;
     500                 :            : 
     501                 :          0 :         default:
     502                 :            : 
     503                 :          0 :                 ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %u",
     504                 :            :                             obj_desc->common.type));
     505                 :          0 :                 status = AE_AML_INTERNAL;
     506                 :          0 :                 break;
     507                 :            :         }
     508                 :            : 
     509                 :            :         if (ACPI_SUCCESS(status)) {
     510                 :            :                 if (read_write == ACPI_READ) {
     511                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
     512                 :            :                                           "Value Read %8.8X%8.8X, Width %u\n",
     513                 :            :                                           ACPI_FORMAT_UINT64(*value),
     514                 :            :                                           obj_desc->common_field.
     515                 :            :                                           access_byte_width));
     516                 :            :                 } else {
     517                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
     518                 :            :                                           "Value Written %8.8X%8.8X, Width %u\n",
     519                 :            :                                           ACPI_FORMAT_UINT64(*value),
     520                 :            :                                           obj_desc->common_field.
     521                 :            :                                           access_byte_width));
     522                 :            :                 }
     523                 :            :         }
     524                 :            : 
     525                 :            :         return_ACPI_STATUS(status);
     526                 :            : }
     527                 :            : 
     528                 :            : /*******************************************************************************
     529                 :            :  *
     530                 :            :  * FUNCTION:    acpi_ex_write_with_update_rule
     531                 :            :  *
     532                 :            :  * PARAMETERS:  obj_desc                - Field to be written
     533                 :            :  *              mask                    - bitmask within field datum
     534                 :            :  *              field_value             - Value to write
     535                 :            :  *              field_datum_byte_offset - Offset of datum within field
     536                 :            :  *
     537                 :            :  * RETURN:      Status
     538                 :            :  *
     539                 :            :  * DESCRIPTION: Apply the field update rule to a field write
     540                 :            :  *
     541                 :            :  ******************************************************************************/
     542                 :            : 
     543                 :            : acpi_status
     544                 :        187 : acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
     545                 :            :                                u64 mask,
     546                 :            :                                u64 field_value, u32 field_datum_byte_offset)
     547                 :            : {
     548                 :        187 :         acpi_status status = AE_OK;
     549                 :        187 :         u64 merged_value;
     550                 :        187 :         u64 current_value;
     551                 :            : 
     552                 :        187 :         ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask);
     553                 :            : 
     554                 :            :         /* Start with the new bits  */
     555                 :            : 
     556                 :        187 :         merged_value = field_value;
     557                 :            : 
     558                 :            :         /* If the mask is all ones, we don't need to worry about the update rule */
     559                 :            : 
     560         [ +  - ]:        187 :         if (mask != ACPI_UINT64_MAX) {
     561                 :            : 
     562                 :            :                 /* Decode the update rule */
     563                 :            : 
     564                 :        187 :                 switch (obj_desc->common_field.
     565   [ +  -  -  - ]:        187 :                         field_flags & AML_FIELD_UPDATE_RULE_MASK) {
     566                 :        187 :                 case AML_FIELD_UPDATE_PRESERVE:
     567                 :            :                         /*
     568                 :            :                          * Check if update rule needs to be applied (not if mask is all
     569                 :            :                          * ones)  The left shift drops the bits we want to ignore.
     570                 :            :                          */
     571                 :        187 :                         if ((~mask << (ACPI_MUL_8(sizeof(mask)) -
     572         [ -  + ]:        187 :                                        ACPI_MUL_8(obj_desc->common_field.
     573                 :            :                                                   access_byte_width))) != 0) {
     574                 :            :                                 /*
     575                 :            :                                  * Read the current contents of the byte/word/dword containing
     576                 :            :                                  * the field, and merge with the new field value.
     577                 :            :                                  */
     578                 :          0 :                                 status =
     579                 :          0 :                                     acpi_ex_field_datum_io(obj_desc,
     580                 :            :                                                            field_datum_byte_offset,
     581                 :            :                                                            &current_value,
     582                 :            :                                                            ACPI_READ);
     583         [ #  # ]:          0 :                                 if (ACPI_FAILURE(status)) {
     584                 :            :                                         return_ACPI_STATUS(status);
     585                 :            :                                 }
     586                 :            : 
     587                 :          0 :                                 merged_value |= (current_value & ~mask);
     588                 :            :                         }
     589                 :            :                         break;
     590                 :            : 
     591                 :          0 :                 case AML_FIELD_UPDATE_WRITE_AS_ONES:
     592                 :            : 
     593                 :            :                         /* Set positions outside the field to all ones */
     594                 :            : 
     595                 :          0 :                         merged_value |= ~mask;
     596                 :          0 :                         break;
     597                 :            : 
     598                 :          0 :                 case AML_FIELD_UPDATE_WRITE_AS_ZEROS:
     599                 :            : 
     600                 :            :                         /* Set positions outside the field to all zeros */
     601                 :            : 
     602                 :          0 :                         merged_value &= mask;
     603                 :          0 :                         break;
     604                 :            : 
     605                 :          0 :                 default:
     606                 :            : 
     607                 :          0 :                         ACPI_ERROR((AE_INFO,
     608                 :            :                                     "Unknown UpdateRule value: 0x%X",
     609                 :            :                                     (obj_desc->common_field.field_flags &
     610                 :            :                                      AML_FIELD_UPDATE_RULE_MASK)));
     611                 :          0 :                         return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
     612                 :            :                 }
     613                 :          0 :         }
     614                 :            : 
     615                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
     616                 :            :                           "Mask %8.8X%8.8X, DatumOffset %X, Width %X, "
     617                 :            :                           "Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n",
     618                 :            :                           ACPI_FORMAT_UINT64(mask),
     619                 :            :                           field_datum_byte_offset,
     620                 :            :                           obj_desc->common_field.access_byte_width,
     621                 :            :                           ACPI_FORMAT_UINT64(field_value),
     622                 :        187 :                           ACPI_FORMAT_UINT64(merged_value)));
     623                 :            : 
     624                 :            :         /* Write the merged value */
     625                 :            : 
     626                 :        187 :         status =
     627                 :        187 :             acpi_ex_field_datum_io(obj_desc, field_datum_byte_offset,
     628                 :            :                                    &merged_value, ACPI_WRITE);
     629                 :            : 
     630                 :        187 :         return_ACPI_STATUS(status);
     631                 :            : }
     632                 :            : 
     633                 :            : /*******************************************************************************
     634                 :            :  *
     635                 :            :  * FUNCTION:    acpi_ex_extract_from_field
     636                 :            :  *
     637                 :            :  * PARAMETERS:  obj_desc            - Field to be read
     638                 :            :  *              buffer              - Where to store the field data
     639                 :            :  *              buffer_length       - Length of Buffer
     640                 :            :  *
     641                 :            :  * RETURN:      Status
     642                 :            :  *
     643                 :            :  * DESCRIPTION: Retrieve the current value of the given field
     644                 :            :  *
     645                 :            :  ******************************************************************************/
     646                 :            : 
     647                 :            : acpi_status
     648                 :        583 : acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
     649                 :            :                            void *buffer, u32 buffer_length)
     650                 :            : {
     651                 :        583 :         acpi_status status;
     652                 :        583 :         u64 raw_datum;
     653                 :        583 :         u64 merged_datum;
     654                 :        583 :         u32 field_offset = 0;
     655                 :        583 :         u32 buffer_offset = 0;
     656                 :        583 :         u32 buffer_tail_bits;
     657                 :        583 :         u32 datum_count;
     658                 :        583 :         u32 field_datum_count;
     659                 :        583 :         u32 access_bit_width;
     660                 :        583 :         u32 i;
     661                 :            : 
     662                 :        583 :         ACPI_FUNCTION_TRACE(ex_extract_from_field);
     663                 :            : 
     664                 :            :         /* Validate target buffer and clear it */
     665                 :            : 
     666                 :        583 :         if (buffer_length <
     667         [ -  + ]:        583 :             ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {
     668                 :          0 :                 ACPI_ERROR((AE_INFO,
     669                 :            :                             "Field size %u (bits) is too large for buffer (%u)",
     670                 :            :                             obj_desc->common_field.bit_length, buffer_length));
     671                 :            : 
     672                 :          0 :                 return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
     673                 :            :         }
     674                 :            : 
     675                 :        583 :         memset(buffer, 0, buffer_length);
     676                 :        583 :         access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
     677                 :            : 
     678                 :            :         /* Handle the simple case here */
     679                 :            : 
     680         [ +  + ]:        583 :         if ((obj_desc->common_field.start_field_bit_offset == 0) &&
     681         [ +  + ]:        451 :             (obj_desc->common_field.bit_length == access_bit_width)) {
     682         [ -  + ]:        429 :                 if (buffer_length >= sizeof(u64)) {
     683                 :          0 :                         status =
     684                 :          0 :                             acpi_ex_field_datum_io(obj_desc, 0, buffer,
     685                 :            :                                                    ACPI_READ);
     686                 :            :                 } else {
     687                 :            :                         /* Use raw_datum (u64) to handle buffers < 64 bits */
     688                 :            : 
     689                 :        429 :                         status =
     690                 :        429 :                             acpi_ex_field_datum_io(obj_desc, 0, &raw_datum,
     691                 :            :                                                    ACPI_READ);
     692                 :        429 :                         memcpy(buffer, &raw_datum, buffer_length);
     693                 :            :                 }
     694                 :            : 
     695                 :        429 :                 return_ACPI_STATUS(status);
     696                 :            :         }
     697                 :            : 
     698                 :            : /* TBD: Move to common setup code */
     699                 :            : 
     700                 :            :         /* Field algorithm is limited to sizeof(u64), truncate if needed */
     701                 :            : 
     702         [ -  + ]:        154 :         if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
     703                 :          0 :                 obj_desc->common_field.access_byte_width = sizeof(u64);
     704                 :          0 :                 access_bit_width = sizeof(u64) * 8;
     705                 :            :         }
     706                 :            : 
     707                 :            :         /* Compute the number of datums (access width data items) */
     708                 :            : 
     709                 :        154 :         datum_count =
     710                 :        154 :             ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
     711                 :            :                              access_bit_width);
     712                 :            : 
     713                 :        154 :         field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
     714                 :            :                                              obj_desc->common_field.
     715                 :            :                                              start_field_bit_offset,
     716                 :            :                                              access_bit_width);
     717                 :            : 
     718                 :            :         /* Priming read from the field */
     719                 :            : 
     720                 :        154 :         status =
     721                 :        154 :             acpi_ex_field_datum_io(obj_desc, field_offset, &raw_datum,
     722                 :            :                                    ACPI_READ);
     723         [ +  - ]:        154 :         if (ACPI_FAILURE(status)) {
     724                 :            :                 return_ACPI_STATUS(status);
     725                 :            :         }
     726                 :        154 :         merged_datum =
     727                 :        154 :             raw_datum >> obj_desc->common_field.start_field_bit_offset;
     728                 :            : 
     729                 :            :         /* Read the rest of the field */
     730                 :            : 
     731         [ -  + ]:        154 :         for (i = 1; i < field_datum_count; i++) {
     732                 :            : 
     733                 :            :                 /* Get next input datum from the field */
     734                 :            : 
     735                 :          0 :                 field_offset += obj_desc->common_field.access_byte_width;
     736                 :          0 :                 status =
     737                 :          0 :                     acpi_ex_field_datum_io(obj_desc, field_offset, &raw_datum,
     738                 :            :                                            ACPI_READ);
     739         [ #  # ]:          0 :                 if (ACPI_FAILURE(status)) {
     740                 :          0 :                         return_ACPI_STATUS(status);
     741                 :            :                 }
     742                 :            : 
     743                 :            :                 /*
     744                 :            :                  * Merge with previous datum if necessary.
     745                 :            :                  *
     746                 :            :                  * Note: Before the shift, check if the shift value will be larger than
     747                 :            :                  * the integer size. If so, there is no need to perform the operation.
     748                 :            :                  * This avoids the differences in behavior between different compilers
     749                 :            :                  * concerning shift values larger than the target data width.
     750                 :            :                  */
     751                 :          0 :                 if (access_bit_width -
     752         [ #  # ]:          0 :                     obj_desc->common_field.start_field_bit_offset <
     753                 :            :                     ACPI_INTEGER_BIT_SIZE) {
     754                 :          0 :                         merged_datum |=
     755                 :          0 :                             raw_datum << (access_bit_width -
     756                 :            :                                           obj_desc->common_field.
     757                 :            :                                           start_field_bit_offset);
     758                 :            :                 }
     759                 :            : 
     760         [ #  # ]:          0 :                 if (i == datum_count) {
     761                 :            :                         break;
     762                 :            :                 }
     763                 :            : 
     764                 :            :                 /* Write merged datum to target buffer */
     765                 :            : 
     766                 :          0 :                 memcpy(((char *)buffer) + buffer_offset, &merged_datum,
     767                 :          0 :                        ACPI_MIN(obj_desc->common_field.access_byte_width,
     768                 :            :                                 buffer_length - buffer_offset));
     769                 :            : 
     770                 :          0 :                 buffer_offset += obj_desc->common_field.access_byte_width;
     771                 :          0 :                 merged_datum =
     772                 :          0 :                     raw_datum >> obj_desc->common_field.start_field_bit_offset;
     773                 :            :         }
     774                 :            : 
     775                 :            :         /* Mask off any extra bits in the last datum */
     776                 :            : 
     777                 :        154 :         buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width;
     778         [ +  - ]:        154 :         if (buffer_tail_bits) {
     779                 :        154 :                 merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
     780                 :            :         }
     781                 :            : 
     782                 :            :         /* Write the last datum to the buffer */
     783                 :            : 
     784                 :        154 :         memcpy(((char *)buffer) + buffer_offset, &merged_datum,
     785                 :        154 :                ACPI_MIN(obj_desc->common_field.access_byte_width,
     786                 :            :                         buffer_length - buffer_offset));
     787                 :            : 
     788                 :        154 :         return_ACPI_STATUS(AE_OK);
     789                 :            : }
     790                 :            : 
     791                 :            : /*******************************************************************************
     792                 :            :  *
     793                 :            :  * FUNCTION:    acpi_ex_insert_into_field
     794                 :            :  *
     795                 :            :  * PARAMETERS:  obj_desc            - Field to be written
     796                 :            :  *              buffer              - Data to be written
     797                 :            :  *              buffer_length       - Length of Buffer
     798                 :            :  *
     799                 :            :  * RETURN:      Status
     800                 :            :  *
     801                 :            :  * DESCRIPTION: Store the Buffer contents into the given field
     802                 :            :  *
     803                 :            :  ******************************************************************************/
     804                 :            : 
     805                 :            : acpi_status
     806                 :        187 : acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
     807                 :            :                           void *buffer, u32 buffer_length)
     808                 :            : {
     809                 :        187 :         void *new_buffer;
     810                 :        187 :         acpi_status status;
     811                 :        187 :         u64 mask;
     812                 :        187 :         u64 width_mask;
     813                 :        187 :         u64 merged_datum;
     814                 :        187 :         u64 raw_datum = 0;
     815                 :        187 :         u32 field_offset = 0;
     816                 :        187 :         u32 buffer_offset = 0;
     817                 :        187 :         u32 buffer_tail_bits;
     818                 :        187 :         u32 datum_count;
     819                 :        187 :         u32 field_datum_count;
     820                 :        187 :         u32 access_bit_width;
     821                 :        187 :         u32 required_length;
     822                 :        187 :         u32 i;
     823                 :            : 
     824                 :        187 :         ACPI_FUNCTION_TRACE(ex_insert_into_field);
     825                 :            : 
     826                 :            :         /* Validate input buffer */
     827                 :            : 
     828                 :        187 :         new_buffer = NULL;
     829                 :        187 :         required_length =
     830                 :        187 :             ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
     831                 :            : 
     832                 :            :         /*
     833                 :            :          * We must have a buffer that is at least as long as the field
     834                 :            :          * we are writing to. This is because individual fields are
     835                 :            :          * indivisible and partial writes are not supported -- as per
     836                 :            :          * the ACPI specification.
     837                 :            :          */
     838         [ -  + ]:        187 :         if (buffer_length < required_length) {
     839                 :            : 
     840                 :            :                 /* We need to create a new buffer */
     841                 :            : 
     842                 :          0 :                 new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
     843         [ #  # ]:          0 :                 if (!new_buffer) {
     844                 :            :                         return_ACPI_STATUS(AE_NO_MEMORY);
     845                 :            :                 }
     846                 :            : 
     847                 :            :                 /*
     848                 :            :                  * Copy the original data to the new buffer, starting
     849                 :            :                  * at Byte zero. All unused (upper) bytes of the
     850                 :            :                  * buffer will be 0.
     851                 :            :                  */
     852                 :          0 :                 memcpy((char *)new_buffer, (char *)buffer, buffer_length);
     853                 :          0 :                 buffer = new_buffer;
     854                 :          0 :                 buffer_length = required_length;
     855                 :            :         }
     856                 :            : 
     857                 :            : /* TBD: Move to common setup code */
     858                 :            : 
     859                 :            :         /* Algo is limited to sizeof(u64), so cut the access_byte_width */
     860         [ -  + ]:        187 :         if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
     861                 :          0 :                 obj_desc->common_field.access_byte_width = sizeof(u64);
     862                 :            :         }
     863                 :            : 
     864                 :        187 :         access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
     865                 :            : 
     866                 :            :         /* Create the bitmasks used for bit insertion */
     867                 :            : 
     868         [ +  - ]:        187 :         width_mask = ACPI_MASK_BITS_ABOVE_64(access_bit_width);
     869                 :        187 :         mask = width_mask &
     870                 :        187 :             ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset);
     871                 :            : 
     872                 :            :         /* Compute the number of datums (access width data items) */
     873                 :            : 
     874                 :        187 :         datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
     875                 :            :                                        access_bit_width);
     876                 :            : 
     877                 :        187 :         field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
     878                 :            :                                              obj_desc->common_field.
     879                 :            :                                              start_field_bit_offset,
     880                 :            :                                              access_bit_width);
     881                 :            : 
     882                 :            :         /* Get initial Datum from the input buffer */
     883                 :            : 
     884                 :        187 :         memcpy(&raw_datum, buffer,
     885                 :        187 :                ACPI_MIN(obj_desc->common_field.access_byte_width,
     886                 :            :                         buffer_length - buffer_offset));
     887                 :            : 
     888                 :        187 :         merged_datum =
     889                 :        187 :             raw_datum << obj_desc->common_field.start_field_bit_offset;
     890                 :            : 
     891                 :            :         /* Write the entire field */
     892                 :            : 
     893         [ -  + ]:        187 :         for (i = 1; i < field_datum_count; i++) {
     894                 :            : 
     895                 :            :                 /* Write merged datum to the target field */
     896                 :            : 
     897                 :          0 :                 merged_datum &= mask;
     898                 :          0 :                 status =
     899                 :          0 :                     acpi_ex_write_with_update_rule(obj_desc, mask, merged_datum,
     900                 :            :                                                    field_offset);
     901         [ #  # ]:          0 :                 if (ACPI_FAILURE(status)) {
     902                 :          0 :                         goto exit;
     903                 :            :                 }
     904                 :            : 
     905                 :          0 :                 field_offset += obj_desc->common_field.access_byte_width;
     906                 :            : 
     907                 :            :                 /*
     908                 :            :                  * Start new output datum by merging with previous input datum
     909                 :            :                  * if necessary.
     910                 :            :                  *
     911                 :            :                  * Note: Before the shift, check if the shift value will be larger than
     912                 :            :                  * the integer size. If so, there is no need to perform the operation.
     913                 :            :                  * This avoids the differences in behavior between different compilers
     914                 :            :                  * concerning shift values larger than the target data width.
     915                 :            :                  */
     916                 :          0 :                 if ((access_bit_width -
     917         [ #  # ]:          0 :                      obj_desc->common_field.start_field_bit_offset) <
     918                 :            :                     ACPI_INTEGER_BIT_SIZE) {
     919                 :          0 :                         merged_datum =
     920                 :          0 :                             raw_datum >> (access_bit_width -
     921                 :            :                                           obj_desc->common_field.
     922                 :            :                                           start_field_bit_offset);
     923                 :            :                 } else {
     924                 :            :                         merged_datum = 0;
     925                 :            :                 }
     926                 :            : 
     927                 :          0 :                 mask = width_mask;
     928                 :            : 
     929         [ #  # ]:          0 :                 if (i == datum_count) {
     930                 :            :                         break;
     931                 :            :                 }
     932                 :            : 
     933                 :            :                 /* Get the next input datum from the buffer */
     934                 :            : 
     935                 :          0 :                 buffer_offset += obj_desc->common_field.access_byte_width;
     936                 :          0 :                 memcpy(&raw_datum, ((char *)buffer) + buffer_offset,
     937                 :          0 :                        ACPI_MIN(obj_desc->common_field.access_byte_width,
     938                 :            :                                 buffer_length - buffer_offset));
     939                 :            : 
     940                 :          0 :                 merged_datum |=
     941                 :          0 :                     raw_datum << obj_desc->common_field.start_field_bit_offset;
     942                 :            :         }
     943                 :            : 
     944                 :            :         /* Mask off any extra bits in the last datum */
     945                 :            : 
     946                 :        187 :         buffer_tail_bits = (obj_desc->common_field.bit_length +
     947                 :        187 :                             obj_desc->common_field.start_field_bit_offset) %
     948                 :            :             access_bit_width;
     949         [ -  + ]:        187 :         if (buffer_tail_bits) {
     950                 :          0 :                 mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
     951                 :            :         }
     952                 :            : 
     953                 :            :         /* Write the last datum to the field */
     954                 :            : 
     955                 :        187 :         merged_datum &= mask;
     956                 :        187 :         status =
     957                 :        187 :             acpi_ex_write_with_update_rule(obj_desc, mask, merged_datum,
     958                 :            :                                            field_offset);
     959                 :            : 
     960                 :        187 : exit:
     961                 :            :         /* Free temporary buffer if we used one */
     962                 :            : 
     963         [ -  + ]:        187 :         if (new_buffer) {
     964                 :          0 :                 ACPI_FREE(new_buffer);
     965                 :            :         }
     966                 :            :         return_ACPI_STATUS(status);
     967                 :            : }

Generated by: LCOV version 1.14