LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - rscalc.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 121 269 45.0 %
Date: 2022-03-28 15:32:58 Functions: 6 6 100.0 %
Branches: 31 82 37.8 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /*******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: rscalc - Calculate stream and list lengths
       5                 :            :  *
       6                 :            :  ******************************************************************************/
       7                 :            : 
       8                 :            : #include <acpi/acpi.h>
       9                 :            : #include "accommon.h"
      10                 :            : #include "acresrc.h"
      11                 :            : #include "acnamesp.h"
      12                 :            : 
      13                 :            : #define _COMPONENT          ACPI_RESOURCES
      14                 :            : ACPI_MODULE_NAME("rscalc")
      15                 :            : 
      16                 :            : /* Local prototypes */
      17                 :            : static u8 acpi_rs_count_set_bits(u16 bit_field);
      18                 :            : 
      19                 :            : static acpi_rs_length
      20                 :            : acpi_rs_struct_option_length(struct acpi_resource_source *resource_source);
      21                 :            : 
      22                 :            : static u32
      23                 :            : acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length);
      24                 :            : 
      25                 :            : /*******************************************************************************
      26                 :            :  *
      27                 :            :  * FUNCTION:    acpi_rs_count_set_bits
      28                 :            :  *
      29                 :            :  * PARAMETERS:  bit_field       - Field in which to count bits
      30                 :            :  *
      31                 :            :  * RETURN:      Number of bits set within the field
      32                 :            :  *
      33                 :            :  * DESCRIPTION: Count the number of bits set in a resource field. Used for
      34                 :            :  *              (Short descriptor) interrupt and DMA lists.
      35                 :            :  *
      36                 :            :  ******************************************************************************/
      37                 :            : 
      38                 :        420 : static u8 acpi_rs_count_set_bits(u16 bit_field)
      39                 :            : {
      40                 :        420 :         u8 bits_set;
      41                 :            : 
      42                 :        420 :         ACPI_FUNCTION_ENTRY();
      43                 :            : 
      44         [ +  + ]:        840 :         for (bits_set = 0; bit_field; bits_set++) {
      45                 :            : 
      46                 :            :                 /* Zero the least significant bit that is set */
      47                 :            : 
      48                 :        420 :                 bit_field &= (u16) (bit_field - 1);
      49                 :            :         }
      50                 :            : 
      51                 :        420 :         return (bits_set);
      52                 :            : }
      53                 :            : 
      54                 :            : /*******************************************************************************
      55                 :            :  *
      56                 :            :  * FUNCTION:    acpi_rs_struct_option_length
      57                 :            :  *
      58                 :            :  * PARAMETERS:  resource_source     - Pointer to optional descriptor field
      59                 :            :  *
      60                 :            :  * RETURN:      Status
      61                 :            :  *
      62                 :            :  * DESCRIPTION: Common code to handle optional resource_source_index and
      63                 :            :  *              resource_source fields in some Large descriptors. Used during
      64                 :            :  *              list-to-stream conversion
      65                 :            :  *
      66                 :            :  ******************************************************************************/
      67                 :            : 
      68                 :            : static acpi_rs_length
      69                 :         28 : acpi_rs_struct_option_length(struct acpi_resource_source *resource_source)
      70                 :            : {
      71                 :         28 :         ACPI_FUNCTION_ENTRY();
      72                 :            : 
      73                 :            :         /*
      74                 :            :          * If the resource_source string is valid, return the size of the string
      75                 :            :          * (string_length includes the NULL terminator) plus the size of the
      76                 :            :          * resource_source_index (1).
      77                 :            :          */
      78         [ -  + ]:         28 :         if (resource_source->string_ptr) {
      79                 :          0 :                 return ((acpi_rs_length)(resource_source->string_length + 1));
      80                 :            :         }
      81                 :            : 
      82                 :            :         return (0);
      83                 :            : }
      84                 :            : 
      85                 :            : /*******************************************************************************
      86                 :            :  *
      87                 :            :  * FUNCTION:    acpi_rs_stream_option_length
      88                 :            :  *
      89                 :            :  * PARAMETERS:  resource_length     - Length from the resource header
      90                 :            :  *              minimum_total_length - Minimum length of this resource, before
      91                 :            :  *                                    any optional fields. Includes header size
      92                 :            :  *
      93                 :            :  * RETURN:      Length of optional string (0 if no string present)
      94                 :            :  *
      95                 :            :  * DESCRIPTION: Common code to handle optional resource_source_index and
      96                 :            :  *              resource_source fields in some Large descriptors. Used during
      97                 :            :  *              stream-to-list conversion
      98                 :            :  *
      99                 :            :  ******************************************************************************/
     100                 :            : 
     101                 :            : static u32
     102                 :        868 : acpi_rs_stream_option_length(u32 resource_length,
     103                 :            :                              u32 minimum_aml_resource_length)
     104                 :            : {
     105                 :        868 :         u32 string_length = 0;
     106                 :            : 
     107                 :        868 :         ACPI_FUNCTION_ENTRY();
     108                 :            : 
     109                 :            :         /*
     110                 :            :          * The resource_source_index and resource_source are optional elements of
     111                 :            :          * some Large-type resource descriptors.
     112                 :            :          */
     113                 :            : 
     114                 :            :         /*
     115                 :            :          * If the length of the actual resource descriptor is greater than the
     116                 :            :          * ACPI spec-defined minimum length, it means that a resource_source_index
     117                 :            :          * exists and is followed by a (required) null terminated string. The
     118                 :            :          * string length (including the null terminator) is the resource length
     119                 :            :          * minus the minimum length, minus one byte for the resource_source_index
     120                 :            :          * itself.
     121                 :            :          */
     122         [ -  + ]:        868 :         if (resource_length > minimum_aml_resource_length) {
     123                 :            : 
     124                 :            :                 /* Compute the length of the optional string */
     125                 :            : 
     126                 :          0 :                 string_length =
     127                 :          0 :                     resource_length - minimum_aml_resource_length - 1;
     128                 :            :         }
     129                 :            : 
     130                 :            :         /*
     131                 :            :          * Round the length up to a multiple of the native word in order to
     132                 :            :          * guarantee that the entire resource descriptor is native word aligned
     133                 :            :          */
     134                 :        868 :         return ((u32) ACPI_ROUND_UP_TO_NATIVE_WORD(string_length));
     135                 :            : }
     136                 :            : 
     137                 :            : /*******************************************************************************
     138                 :            :  *
     139                 :            :  * FUNCTION:    acpi_rs_get_aml_length
     140                 :            :  *
     141                 :            :  * PARAMETERS:  resource            - Pointer to the resource linked list
     142                 :            :  *              resource_list_size  - Size of the resource linked list
     143                 :            :  *              size_needed         - Where the required size is returned
     144                 :            :  *
     145                 :            :  * RETURN:      Status
     146                 :            :  *
     147                 :            :  * DESCRIPTION: Takes a linked list of internal resource descriptors and
     148                 :            :  *              calculates the size buffer needed to hold the corresponding
     149                 :            :  *              external resource byte stream.
     150                 :            :  *
     151                 :            :  ******************************************************************************/
     152                 :            : 
     153                 :            : acpi_status
     154                 :         28 : acpi_rs_get_aml_length(struct acpi_resource *resource,
     155                 :            :                        acpi_size resource_list_size, acpi_size *size_needed)
     156                 :            : {
     157                 :         28 :         acpi_size aml_size_needed = 0;
     158                 :         28 :         struct acpi_resource *resource_end;
     159                 :         28 :         acpi_rs_length total_size;
     160                 :            : 
     161                 :         28 :         ACPI_FUNCTION_TRACE(rs_get_aml_length);
     162                 :            : 
     163                 :            :         /* Traverse entire list of internal resource descriptors */
     164                 :            : 
     165                 :         28 :         resource_end =
     166                 :            :             ACPI_ADD_PTR(struct acpi_resource, resource, resource_list_size);
     167         [ +  - ]:         56 :         while (resource < resource_end) {
     168                 :            : 
     169                 :            :                 /* Validate the descriptor type */
     170                 :            : 
     171         [ +  - ]:         56 :                 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
     172                 :            :                         return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
     173                 :            :                 }
     174                 :            : 
     175                 :            :                 /* Sanity check the length. It must not be zero, or we loop forever */
     176                 :            : 
     177         [ +  - ]:         56 :                 if (!resource->length) {
     178                 :            :                         return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
     179                 :            :                 }
     180                 :            : 
     181                 :            :                 /* Get the base size of the (external stream) resource descriptor */
     182                 :            : 
     183                 :         56 :                 total_size = acpi_gbl_aml_resource_sizes[resource->type];
     184                 :            : 
     185                 :            :                 /*
     186                 :            :                  * Augment the base size for descriptors with optional and/or
     187                 :            :                  * variable-length fields
     188                 :            :                  */
     189   [ -  -  -  +  :         56 :                 switch (resource->type) {
          -  -  -  +  -  
          -  -  -  -  -  
                   -  - ]
     190                 :          0 :                 case ACPI_RESOURCE_TYPE_IRQ:
     191                 :            : 
     192                 :            :                         /* Length can be 3 or 2 */
     193                 :            : 
     194         [ #  # ]:          0 :                         if (resource->data.irq.descriptor_length == 2) {
     195                 :          0 :                                 total_size--;
     196                 :            :                         }
     197                 :            :                         break;
     198                 :            : 
     199                 :          0 :                 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
     200                 :            : 
     201                 :            :                         /* Length can be 1 or 0 */
     202                 :            : 
     203         [ #  # ]:          0 :                         if (resource->data.irq.descriptor_length == 0) {
     204                 :          0 :                                 total_size--;
     205                 :            :                         }
     206                 :            :                         break;
     207                 :            : 
     208                 :          0 :                 case ACPI_RESOURCE_TYPE_VENDOR:
     209                 :            :                         /*
     210                 :            :                          * Vendor Defined Resource:
     211                 :            :                          * For a Vendor Specific resource, if the Length is between 1 and 7
     212                 :            :                          * it will be created as a Small Resource data type, otherwise it
     213                 :            :                          * is a Large Resource data type.
     214                 :            :                          */
     215         [ #  # ]:          0 :                         if (resource->data.vendor.byte_length > 7) {
     216                 :            : 
     217                 :            :                                 /* Base size of a Large resource descriptor */
     218                 :            : 
     219                 :          0 :                                 total_size =
     220                 :            :                                     sizeof(struct aml_resource_large_header);
     221                 :            :                         }
     222                 :            : 
     223                 :            :                         /* Add the size of the vendor-specific data */
     224                 :            : 
     225                 :          0 :                         total_size = (acpi_rs_length)
     226                 :            :                             (total_size + resource->data.vendor.byte_length);
     227                 :          0 :                         break;
     228                 :            : 
     229                 :         28 :                 case ACPI_RESOURCE_TYPE_END_TAG:
     230                 :            :                         /*
     231                 :            :                          * End Tag:
     232                 :            :                          * We are done -- return the accumulated total size.
     233                 :            :                          */
     234                 :         28 :                         *size_needed = aml_size_needed + total_size;
     235                 :            : 
     236                 :            :                         /* Normal exit */
     237                 :            : 
     238                 :         28 :                         return_ACPI_STATUS(AE_OK);
     239                 :            : 
     240                 :          0 :                 case ACPI_RESOURCE_TYPE_ADDRESS16:
     241                 :            :                         /*
     242                 :            :                          * 16-Bit Address Resource:
     243                 :            :                          * Add the size of the optional resource_source info
     244                 :            :                          */
     245                 :          0 :                         total_size = (acpi_rs_length)(total_size +
     246                 :          0 :                                                       acpi_rs_struct_option_length
     247                 :            :                                                       (&resource->data.
     248                 :            :                                                        address16.
     249                 :            :                                                        resource_source));
     250                 :          0 :                         break;
     251                 :            : 
     252                 :          0 :                 case ACPI_RESOURCE_TYPE_ADDRESS32:
     253                 :            :                         /*
     254                 :            :                          * 32-Bit Address Resource:
     255                 :            :                          * Add the size of the optional resource_source info
     256                 :            :                          */
     257                 :          0 :                         total_size = (acpi_rs_length)(total_size +
     258                 :          0 :                                                       acpi_rs_struct_option_length
     259                 :            :                                                       (&resource->data.
     260                 :            :                                                        address32.
     261                 :            :                                                        resource_source));
     262                 :          0 :                         break;
     263                 :            : 
     264                 :          0 :                 case ACPI_RESOURCE_TYPE_ADDRESS64:
     265                 :            :                         /*
     266                 :            :                          * 64-Bit Address Resource:
     267                 :            :                          * Add the size of the optional resource_source info
     268                 :            :                          */
     269                 :          0 :                         total_size = (acpi_rs_length)(total_size +
     270                 :          0 :                                                       acpi_rs_struct_option_length
     271                 :            :                                                       (&resource->data.
     272                 :            :                                                        address64.
     273                 :            :                                                        resource_source));
     274                 :          0 :                         break;
     275                 :            : 
     276                 :         28 :                 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
     277                 :            :                         /*
     278                 :            :                          * Extended IRQ Resource:
     279                 :            :                          * Add the size of each additional optional interrupt beyond the
     280                 :            :                          * required 1 (4 bytes for each u32 interrupt number)
     281                 :            :                          */
     282                 :         28 :                         total_size = (acpi_rs_length)(total_size +
     283                 :            :                                                       ((resource->data.
     284                 :         28 :                                                         extended_irq.
     285                 :         28 :                                                         interrupt_count -
     286                 :         28 :                                                         1) * 4) +
     287                 :            :                                                       /* Add the size of the optional resource_source info */
     288                 :         28 :                                                       acpi_rs_struct_option_length
     289                 :            :                                                       (&resource->data.
     290                 :            :                                                        extended_irq.
     291                 :            :                                                        resource_source));
     292                 :         28 :                         break;
     293                 :            : 
     294                 :          0 :                 case ACPI_RESOURCE_TYPE_GPIO:
     295                 :            : 
     296                 :          0 :                         total_size = (acpi_rs_length)(total_size +
     297                 :          0 :                                                       (resource->data.gpio.
     298                 :          0 :                                                        pin_table_length * 2) +
     299                 :            :                                                       resource->data.gpio.
     300                 :          0 :                                                       resource_source.
     301                 :          0 :                                                       string_length +
     302                 :          0 :                                                       resource->data.gpio.
     303                 :            :                                                       vendor_length);
     304                 :            : 
     305                 :          0 :                         break;
     306                 :            : 
     307                 :          0 :                 case ACPI_RESOURCE_TYPE_PIN_FUNCTION:
     308                 :            : 
     309                 :          0 :                         total_size = (acpi_rs_length)(total_size +
     310                 :            :                                                       (resource->data.
     311                 :          0 :                                                        pin_function.
     312                 :          0 :                                                        pin_table_length * 2) +
     313                 :            :                                                       resource->data.
     314                 :            :                                                       pin_function.
     315                 :          0 :                                                       resource_source.
     316                 :          0 :                                                       string_length +
     317                 :            :                                                       resource->data.
     318                 :          0 :                                                       pin_function.
     319                 :            :                                                       vendor_length);
     320                 :            : 
     321                 :          0 :                         break;
     322                 :            : 
     323                 :          0 :                 case ACPI_RESOURCE_TYPE_SERIAL_BUS:
     324                 :            : 
     325                 :          0 :                         total_size =
     326                 :          0 :                             acpi_gbl_aml_resource_serial_bus_sizes[resource->
     327                 :            :                                                                    data.
     328                 :          0 :                                                                    common_serial_bus.
     329                 :            :                                                                    type];
     330                 :            : 
     331                 :          0 :                         total_size = (acpi_rs_length)(total_size +
     332                 :            :                                                       resource->data.
     333                 :            :                                                       i2c_serial_bus.
     334                 :          0 :                                                       resource_source.
     335                 :          0 :                                                       string_length +
     336                 :            :                                                       resource->data.
     337                 :          0 :                                                       i2c_serial_bus.
     338                 :            :                                                       vendor_length);
     339                 :            : 
     340                 :          0 :                         break;
     341                 :            : 
     342                 :          0 :                 case ACPI_RESOURCE_TYPE_PIN_CONFIG:
     343                 :            : 
     344                 :          0 :                         total_size = (acpi_rs_length)(total_size +
     345                 :            :                                                       (resource->data.
     346                 :          0 :                                                        pin_config.
     347                 :          0 :                                                        pin_table_length * 2) +
     348                 :            :                                                       resource->data.pin_config.
     349                 :          0 :                                                       resource_source.
     350                 :          0 :                                                       string_length +
     351                 :          0 :                                                       resource->data.pin_config.
     352                 :            :                                                       vendor_length);
     353                 :            : 
     354                 :          0 :                         break;
     355                 :            : 
     356                 :          0 :                 case ACPI_RESOURCE_TYPE_PIN_GROUP:
     357                 :            : 
     358                 :          0 :                         total_size = (acpi_rs_length)(total_size +
     359                 :          0 :                                                       (resource->data.pin_group.
     360                 :          0 :                                                        pin_table_length * 2) +
     361                 :            :                                                       resource->data.pin_group.
     362                 :          0 :                                                       resource_label.
     363                 :          0 :                                                       string_length +
     364                 :          0 :                                                       resource->data.pin_group.
     365                 :            :                                                       vendor_length);
     366                 :            : 
     367                 :          0 :                         break;
     368                 :            : 
     369                 :          0 :                 case ACPI_RESOURCE_TYPE_PIN_GROUP_FUNCTION:
     370                 :            : 
     371                 :          0 :                         total_size = (acpi_rs_length)(total_size +
     372                 :            :                                                       resource->data.
     373                 :            :                                                       pin_group_function.
     374                 :          0 :                                                       resource_source.
     375                 :          0 :                                                       string_length +
     376                 :            :                                                       resource->data.
     377                 :            :                                                       pin_group_function.
     378                 :          0 :                                                       resource_source_label.
     379                 :          0 :                                                       string_length +
     380                 :            :                                                       resource->data.
     381                 :          0 :                                                       pin_group_function.
     382                 :            :                                                       vendor_length);
     383                 :            : 
     384                 :          0 :                         break;
     385                 :            : 
     386                 :          0 :                 case ACPI_RESOURCE_TYPE_PIN_GROUP_CONFIG:
     387                 :            : 
     388                 :          0 :                         total_size = (acpi_rs_length)(total_size +
     389                 :            :                                                       resource->data.
     390                 :            :                                                       pin_group_config.
     391                 :          0 :                                                       resource_source.
     392                 :          0 :                                                       string_length +
     393                 :            :                                                       resource->data.
     394                 :            :                                                       pin_group_config.
     395                 :          0 :                                                       resource_source_label.
     396                 :          0 :                                                       string_length +
     397                 :            :                                                       resource->data.
     398                 :          0 :                                                       pin_group_config.
     399                 :            :                                                       vendor_length);
     400                 :            : 
     401                 :          0 :                         break;
     402                 :            : 
     403                 :            :                 default:
     404                 :            : 
     405                 :            :                         break;
     406                 :            :                 }
     407                 :            : 
     408                 :            :                 /* Update the total */
     409                 :            : 
     410                 :         28 :                 aml_size_needed += total_size;
     411                 :            : 
     412                 :            :                 /* Point to the next object */
     413                 :            : 
     414                 :         28 :                 resource =
     415                 :         28 :                     ACPI_ADD_PTR(struct acpi_resource, resource,
     416                 :            :                                  resource->length);
     417                 :            :         }
     418                 :            : 
     419                 :            :         /* Did not find an end_tag resource descriptor */
     420                 :            : 
     421                 :            :         return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
     422                 :            : }
     423                 :            : 
     424                 :            : /*******************************************************************************
     425                 :            :  *
     426                 :            :  * FUNCTION:    acpi_rs_get_list_length
     427                 :            :  *
     428                 :            :  * PARAMETERS:  aml_buffer          - Pointer to the resource byte stream
     429                 :            :  *              aml_buffer_length   - Size of aml_buffer
     430                 :            :  *              size_needed         - Where the size needed is returned
     431                 :            :  *
     432                 :            :  * RETURN:      Status
     433                 :            :  *
     434                 :            :  * DESCRIPTION: Takes an external resource byte stream and calculates the size
     435                 :            :  *              buffer needed to hold the corresponding internal resource
     436                 :            :  *              descriptor linked list.
     437                 :            :  *
     438                 :            :  ******************************************************************************/
     439                 :            : 
     440                 :            : acpi_status
     441                 :       1120 : acpi_rs_get_list_length(u8 *aml_buffer,
     442                 :            :                         u32 aml_buffer_length, acpi_size *size_needed)
     443                 :            : {
     444                 :       1120 :         acpi_status status;
     445                 :       1120 :         u8 *end_aml;
     446                 :       1120 :         u8 *buffer;
     447                 :       1120 :         u32 buffer_size;
     448                 :       1120 :         u16 temp16;
     449                 :       1120 :         u16 resource_length;
     450                 :       1120 :         u32 extra_struct_bytes;
     451                 :       1120 :         u8 resource_index;
     452                 :       1120 :         u8 minimum_aml_resource_length;
     453                 :       1120 :         union aml_resource *aml_resource;
     454                 :            : 
     455                 :       1120 :         ACPI_FUNCTION_TRACE(rs_get_list_length);
     456                 :            : 
     457                 :       1120 :         *size_needed = ACPI_RS_SIZE_MIN;        /* Minimum size is one end_tag */
     458                 :       1120 :         end_aml = aml_buffer + aml_buffer_length;
     459                 :            : 
     460                 :            :         /* Walk the list of AML resource descriptors */
     461                 :            : 
     462         [ +  - ]:       3192 :         while (aml_buffer < end_aml) {
     463                 :            : 
     464                 :            :                 /* Validate the Resource Type and Resource Length */
     465                 :            : 
     466                 :       3192 :                 status =
     467                 :       3192 :                     acpi_ut_validate_resource(NULL, aml_buffer,
     468                 :            :                                               &resource_index);
     469         [ -  + ]:       3192 :                 if (ACPI_FAILURE(status)) {
     470                 :            :                         /*
     471                 :            :                          * Exit on failure. Cannot continue because the descriptor length
     472                 :            :                          * may be bogus also.
     473                 :            :                          */
     474                 :          0 :                         return_ACPI_STATUS(status);
     475                 :            :                 }
     476                 :            : 
     477                 :       3192 :                 aml_resource = (void *)aml_buffer;
     478                 :            : 
     479                 :            :                 /* Get the resource length and base (minimum) AML size */
     480                 :            : 
     481                 :       3192 :                 resource_length = acpi_ut_get_resource_length(aml_buffer);
     482                 :       3192 :                 minimum_aml_resource_length =
     483                 :       3192 :                     acpi_gbl_resource_aml_sizes[resource_index];
     484                 :            : 
     485                 :            :                 /*
     486                 :            :                  * Augment the size for descriptors with optional
     487                 :            :                  * and/or variable length fields
     488                 :            :                  */
     489                 :       3192 :                 extra_struct_bytes = 0;
     490                 :       6384 :                 buffer =
     491                 :       3192 :                     aml_buffer + acpi_ut_get_resource_header_length(aml_buffer);
     492                 :            : 
     493   [ +  +  -  +  :       3192 :                 switch (acpi_ut_get_resource_type(aml_buffer)) {
          +  -  -  -  -  
             -  -  -  +  
                      + ]
     494                 :        364 :                 case ACPI_RESOURCE_NAME_IRQ:
     495                 :            :                         /*
     496                 :            :                          * IRQ Resource:
     497                 :            :                          * Get the number of bits set in the 16-bit IRQ mask
     498                 :            :                          */
     499                 :        364 :                         ACPI_MOVE_16_TO_16(&temp16, buffer);
     500                 :        364 :                         extra_struct_bytes = acpi_rs_count_set_bits(temp16);
     501                 :        364 :                         break;
     502                 :            : 
     503                 :         56 :                 case ACPI_RESOURCE_NAME_DMA:
     504                 :            :                         /*
     505                 :            :                          * DMA Resource:
     506                 :            :                          * Get the number of bits set in the 8-bit DMA mask
     507                 :            :                          */
     508                 :         56 :                         extra_struct_bytes = acpi_rs_count_set_bits(*buffer);
     509                 :         56 :                         break;
     510                 :            : 
     511                 :          0 :                 case ACPI_RESOURCE_NAME_VENDOR_SMALL:
     512                 :            :                 case ACPI_RESOURCE_NAME_VENDOR_LARGE:
     513                 :            :                         /*
     514                 :            :                          * Vendor Resource:
     515                 :            :                          * Get the number of vendor data bytes
     516                 :            :                          */
     517                 :          0 :                         extra_struct_bytes = resource_length;
     518                 :            : 
     519                 :            :                         /*
     520                 :            :                          * There is already one byte included in the minimum
     521                 :            :                          * descriptor size. If there are extra struct bytes,
     522                 :            :                          * subtract one from the count.
     523                 :            :                          */
     524         [ #  # ]:          0 :                         if (extra_struct_bytes) {
     525                 :          0 :                                 extra_struct_bytes--;
     526                 :            :                         }
     527                 :            :                         break;
     528                 :            : 
     529                 :            :                 case ACPI_RESOURCE_NAME_END_TAG:
     530                 :            :                         /*
     531                 :            :                          * End Tag: This is the normal exit
     532                 :            :                          */
     533                 :            :                         return_ACPI_STATUS(AE_OK);
     534                 :            : 
     535                 :        420 :                 case ACPI_RESOURCE_NAME_ADDRESS32:
     536                 :            :                 case ACPI_RESOURCE_NAME_ADDRESS16:
     537                 :            :                 case ACPI_RESOURCE_NAME_ADDRESS64:
     538                 :            :                         /*
     539                 :            :                          * Address Resource:
     540                 :            :                          * Add the size of the optional resource_source
     541                 :            :                          */
     542                 :        420 :                         extra_struct_bytes =
     543                 :        420 :                             acpi_rs_stream_option_length(resource_length,
     544                 :            :                                                          minimum_aml_resource_length);
     545                 :        420 :                         break;
     546                 :            : 
     547                 :        448 :                 case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
     548                 :            :                         /*
     549                 :            :                          * Extended IRQ Resource:
     550                 :            :                          * Using the interrupt_table_length, add 4 bytes for each additional
     551                 :            :                          * interrupt. Note: at least one interrupt is required and is
     552                 :            :                          * included in the minimum descriptor size (reason for the -1)
     553                 :            :                          */
     554                 :        448 :                         extra_struct_bytes = (buffer[1] - 1) * sizeof(u32);
     555                 :            : 
     556                 :            :                         /* Add the size of the optional resource_source */
     557                 :            : 
     558                 :        448 :                         extra_struct_bytes +=
     559                 :        448 :                             acpi_rs_stream_option_length(resource_length -
     560                 :            :                                                          extra_struct_bytes,
     561                 :            :                                                          minimum_aml_resource_length);
     562                 :        448 :                         break;
     563                 :            : 
     564                 :          0 :                 case ACPI_RESOURCE_NAME_GPIO:
     565                 :            : 
     566                 :            :                         /* Vendor data is optional */
     567                 :            : 
     568         [ #  # ]:          0 :                         if (aml_resource->gpio.vendor_length) {
     569                 :          0 :                                 extra_struct_bytes +=
     570                 :          0 :                                     aml_resource->gpio.vendor_offset -
     571                 :          0 :                                     aml_resource->gpio.pin_table_offset +
     572                 :          0 :                                     aml_resource->gpio.vendor_length;
     573                 :            :                         } else {
     574                 :          0 :                                 extra_struct_bytes +=
     575                 :          0 :                                     aml_resource->large_header.resource_length +
     576                 :          0 :                                     sizeof(struct aml_resource_large_header) -
     577                 :          0 :                                     aml_resource->gpio.pin_table_offset;
     578                 :            :                         }
     579                 :            :                         break;
     580                 :            : 
     581                 :          0 :                 case ACPI_RESOURCE_NAME_PIN_FUNCTION:
     582                 :            : 
     583                 :            :                         /* Vendor data is optional */
     584                 :            : 
     585         [ #  # ]:          0 :                         if (aml_resource->pin_function.vendor_length) {
     586                 :          0 :                                 extra_struct_bytes +=
     587                 :          0 :                                     aml_resource->pin_function.vendor_offset -
     588                 :          0 :                                     aml_resource->pin_function.
     589                 :          0 :                                     pin_table_offset +
     590                 :          0 :                                     aml_resource->pin_function.vendor_length;
     591                 :            :                         } else {
     592                 :          0 :                                 extra_struct_bytes +=
     593                 :          0 :                                     aml_resource->large_header.resource_length +
     594                 :          0 :                                     sizeof(struct aml_resource_large_header) -
     595                 :          0 :                                     aml_resource->pin_function.pin_table_offset;
     596                 :            :                         }
     597                 :            :                         break;
     598                 :            : 
     599                 :          0 :                 case ACPI_RESOURCE_NAME_SERIAL_BUS:
     600                 :            : 
     601                 :          0 :                         minimum_aml_resource_length =
     602                 :            :                             acpi_gbl_resource_aml_serial_bus_sizes
     603                 :          0 :                             [aml_resource->common_serial_bus.type];
     604                 :          0 :                         extra_struct_bytes +=
     605                 :          0 :                             aml_resource->common_serial_bus.resource_length -
     606                 :            :                             minimum_aml_resource_length;
     607                 :          0 :                         break;
     608                 :            : 
     609                 :          0 :                 case ACPI_RESOURCE_NAME_PIN_CONFIG:
     610                 :            : 
     611                 :            :                         /* Vendor data is optional */
     612                 :            : 
     613         [ #  # ]:          0 :                         if (aml_resource->pin_config.vendor_length) {
     614                 :          0 :                                 extra_struct_bytes +=
     615                 :          0 :                                     aml_resource->pin_config.vendor_offset -
     616                 :          0 :                                     aml_resource->pin_config.pin_table_offset +
     617                 :          0 :                                     aml_resource->pin_config.vendor_length;
     618                 :            :                         } else {
     619                 :          0 :                                 extra_struct_bytes +=
     620                 :          0 :                                     aml_resource->large_header.resource_length +
     621                 :          0 :                                     sizeof(struct aml_resource_large_header) -
     622                 :          0 :                                     aml_resource->pin_config.pin_table_offset;
     623                 :            :                         }
     624                 :            :                         break;
     625                 :            : 
     626                 :          0 :                 case ACPI_RESOURCE_NAME_PIN_GROUP:
     627                 :            : 
     628                 :          0 :                         extra_struct_bytes +=
     629                 :          0 :                             aml_resource->pin_group.vendor_offset -
     630                 :          0 :                             aml_resource->pin_group.pin_table_offset +
     631                 :          0 :                             aml_resource->pin_group.vendor_length;
     632                 :            : 
     633                 :          0 :                         break;
     634                 :            : 
     635                 :          0 :                 case ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION:
     636                 :            : 
     637                 :          0 :                         extra_struct_bytes +=
     638                 :          0 :                             aml_resource->pin_group_function.vendor_offset -
     639                 :          0 :                             aml_resource->pin_group_function.res_source_offset +
     640                 :          0 :                             aml_resource->pin_group_function.vendor_length;
     641                 :            : 
     642                 :          0 :                         break;
     643                 :            : 
     644                 :          0 :                 case ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG:
     645                 :            : 
     646                 :          0 :                         extra_struct_bytes +=
     647                 :          0 :                             aml_resource->pin_group_config.vendor_offset -
     648                 :          0 :                             aml_resource->pin_group_config.res_source_offset +
     649                 :          0 :                             aml_resource->pin_group_config.vendor_length;
     650                 :            : 
     651                 :          0 :                         break;
     652                 :            : 
     653                 :            :                 default:
     654                 :            : 
     655                 :            :                         break;
     656                 :            :                 }
     657                 :            : 
     658                 :            :                 /*
     659                 :            :                  * Update the required buffer size for the internal descriptor structs
     660                 :            :                  *
     661                 :            :                  * Important: Round the size up for the appropriate alignment. This
     662                 :            :                  * is a requirement on IA64.
     663                 :            :                  */
     664         [ -  + ]:       2072 :                 if (acpi_ut_get_resource_type(aml_buffer) ==
     665                 :            :                     ACPI_RESOURCE_NAME_SERIAL_BUS) {
     666                 :          0 :                         buffer_size =
     667                 :            :                             acpi_gbl_resource_struct_serial_bus_sizes
     668                 :          0 :                             [aml_resource->common_serial_bus.type] +
     669                 :            :                             extra_struct_bytes;
     670                 :            :                 } else {
     671                 :       2072 :                         buffer_size =
     672                 :       2072 :                             acpi_gbl_resource_struct_sizes[resource_index] +
     673                 :            :                             extra_struct_bytes;
     674                 :            :                 }
     675                 :            : 
     676                 :       2072 :                 buffer_size = (u32)ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size);
     677                 :       2072 :                 *size_needed += buffer_size;
     678                 :            : 
     679                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
     680                 :            :                                   "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
     681                 :            :                                   acpi_ut_get_resource_type(aml_buffer),
     682                 :            :                                   acpi_ut_get_descriptor_length(aml_buffer),
     683                 :       2072 :                                   buffer_size));
     684                 :            : 
     685                 :            :                 /*
     686                 :            :                  * Point to the next resource within the AML stream using the length
     687                 :            :                  * contained in the resource descriptor header
     688                 :            :                  */
     689                 :       2072 :                 aml_buffer += acpi_ut_get_descriptor_length(aml_buffer);
     690                 :            :         }
     691                 :            : 
     692                 :            :         /* Did not find an end_tag resource descriptor */
     693                 :            : 
     694                 :            :         return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
     695                 :            : }
     696                 :            : 
     697                 :            : /*******************************************************************************
     698                 :            :  *
     699                 :            :  * FUNCTION:    acpi_rs_get_pci_routing_table_length
     700                 :            :  *
     701                 :            :  * PARAMETERS:  package_object          - Pointer to the package object
     702                 :            :  *              buffer_size_needed      - u32 pointer of the size buffer
     703                 :            :  *                                        needed to properly return the
     704                 :            :  *                                        parsed data
     705                 :            :  *
     706                 :            :  * RETURN:      Status
     707                 :            :  *
     708                 :            :  * DESCRIPTION: Given a package representing a PCI routing table, this
     709                 :            :  *              calculates the size of the corresponding linked list of
     710                 :            :  *              descriptions.
     711                 :            :  *
     712                 :            :  ******************************************************************************/
     713                 :            : 
     714                 :            : acpi_status
     715                 :         31 : acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
     716                 :            :                                      acpi_size *buffer_size_needed)
     717                 :            : {
     718                 :         31 :         u32 number_of_elements;
     719                 :         31 :         acpi_size temp_size_needed = 0;
     720                 :         31 :         union acpi_operand_object **top_object_list;
     721                 :         31 :         u32 index;
     722                 :         31 :         union acpi_operand_object *package_element;
     723                 :         31 :         union acpi_operand_object **sub_object_list;
     724                 :         31 :         u8 name_found;
     725                 :         31 :         u32 table_index;
     726                 :            : 
     727                 :         31 :         ACPI_FUNCTION_TRACE(rs_get_pci_routing_table_length);
     728                 :            : 
     729                 :         31 :         number_of_elements = package_object->package.count;
     730                 :            : 
     731                 :            :         /*
     732                 :            :          * Calculate the size of the return buffer.
     733                 :            :          * The base size is the number of elements * the sizes of the
     734                 :            :          * structures. Additional space for the strings is added below.
     735                 :            :          * The minus one is to subtract the size of the u8 Source[1]
     736                 :            :          * member because it is added below.
     737                 :            :          *
     738                 :            :          * But each PRT_ENTRY structure has a pointer to a string and
     739                 :            :          * the size of that string must be found.
     740                 :            :          */
     741                 :         31 :         top_object_list = package_object->package.elements;
     742                 :            : 
     743         [ +  + ]:       3999 :         for (index = 0; index < number_of_elements; index++) {
     744                 :            : 
     745                 :            :                 /* Dereference the subpackage */
     746                 :            : 
     747                 :       3968 :                 package_element = *top_object_list;
     748                 :            : 
     749                 :            :                 /* We must have a valid Package object */
     750                 :            : 
     751         [ +  - ]:       3968 :                 if (!package_element ||
     752         [ +  - ]:       3968 :                     (package_element->common.type != ACPI_TYPE_PACKAGE)) {
     753                 :            :                         return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
     754                 :            :                 }
     755                 :            : 
     756                 :            :                 /*
     757                 :            :                  * The sub_object_list will now point to an array of the
     758                 :            :                  * four IRQ elements: Address, Pin, Source and source_index
     759                 :            :                  */
     760                 :       3968 :                 sub_object_list = package_element->package.elements;
     761                 :            : 
     762                 :            :                 /* Scan the irq_table_elements for the Source Name String */
     763                 :            : 
     764                 :       3968 :                 name_found = FALSE;
     765                 :            : 
     766                 :       3968 :                 for (table_index = 0;
     767         [ +  - ]:      15872 :                      table_index < package_element->package.count
     768         [ +  + ]:      27776 :                      && !name_found; table_index++) {
     769         [ +  - ]:      11904 :                         if (*sub_object_list && /* Null object allowed */
     770                 :            :                             ((ACPI_TYPE_STRING ==
     771         [ +  - ]:      11904 :                               (*sub_object_list)->common.type) ||
     772                 :            :                              ((ACPI_TYPE_LOCAL_REFERENCE ==
     773         [ +  + ]:      11904 :                                (*sub_object_list)->common.type) &&
     774                 :            :                               ((*sub_object_list)->reference.class ==
     775                 :            :                                ACPI_REFCLASS_NAME)))) {
     776                 :            :                                 name_found = TRUE;
     777                 :            :                         } else {
     778                 :            :                                 /* Look at the next element */
     779                 :            : 
     780                 :       7936 :                                 sub_object_list++;
     781                 :            :                         }
     782                 :            :                 }
     783                 :            : 
     784                 :       3968 :                 temp_size_needed += (sizeof(struct acpi_pci_routing_table) - 4);
     785                 :            : 
     786                 :            :                 /* Was a String type found? */
     787                 :            : 
     788         [ +  - ]:       3968 :                 if (name_found) {
     789         [ -  + ]:       3968 :                         if ((*sub_object_list)->common.type == ACPI_TYPE_STRING) {
     790                 :            :                                 /*
     791                 :            :                                  * The length String.Length field does not include the
     792                 :            :                                  * terminating NULL, add 1
     793                 :            :                                  */
     794                 :          0 :                                 temp_size_needed += ((acpi_size)
     795                 :          0 :                                                      (*sub_object_list)->string.
     796                 :            :                                                      length + 1);
     797                 :            :                         } else {
     798                 :       3968 :                                 temp_size_needed += acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
     799                 :            :                         }
     800                 :            :                 } else {
     801                 :            :                         /*
     802                 :            :                          * If no name was found, then this is a NULL, which is
     803                 :            :                          * translated as a u32 zero.
     804                 :            :                          */
     805                 :          0 :                         temp_size_needed += sizeof(u32);
     806                 :            :                 }
     807                 :            : 
     808                 :            :                 /* Round up the size since each element must be aligned */
     809                 :            : 
     810                 :       3968 :                 temp_size_needed = ACPI_ROUND_UP_TO_64BIT(temp_size_needed);
     811                 :            : 
     812                 :            :                 /* Point to the next union acpi_operand_object */
     813                 :            : 
     814                 :       3968 :                 top_object_list++;
     815                 :            :         }
     816                 :            : 
     817                 :            :         /*
     818                 :            :          * Add an extra element to the end of the list, essentially a
     819                 :            :          * NULL terminator
     820                 :            :          */
     821                 :         31 :         *buffer_size_needed =
     822                 :         31 :             temp_size_needed + sizeof(struct acpi_pci_routing_table);
     823                 :         31 :         return_ACPI_STATUS(AE_OK);
     824                 :            : }

Generated by: LCOV version 1.14