CTC++ Coverage Report - Execution Profile    #246/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/acpi/resources/rscalc.c
Instrumentation mode: function-decision-multicondition
TER: 40 % ( 33/ 82)

Start/ End/    
True False - Line Source

  1 /*******************************************************************************
  2  *
  3  * Module Name: rscalc - Calculate stream and list lengths
  4  *
  5  ******************************************************************************/
  6 
  7 /*
  8  * Copyright (C) 2000 - 2006, R. Byron Moore
  9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 #include <acpi/acpi.h>
  45 #include <acpi/acresrc.h>
  46 #include <acpi/amlcode.h>
  47 #include <acpi/acnamesp.h>
  48 
  49 #define _COMPONENT          ACPI_RESOURCES
  50 ACPI_MODULE_NAME("rscalc")
  51 
  52 /* Local prototypes */
  53 static u8 acpi_rs_count_set_bits(u16 bit_field);
  54 
  55 static acpi_rs_length
  56 acpi_rs_struct_option_length(struct acpi_resource_source *resource_source);
  57 
  58 static u32
  59 acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length);
  60 
  61 /*******************************************************************************
  62  *
  63  * FUNCTION:    acpi_rs_count_set_bits
  64  *
  65  * PARAMETERS:  bit_field       - Field in which to count bits
  66  *
  67  * RETURN:      Number of bits set within the field
  68  *
  69  * DESCRIPTION: Count the number of bits set in a resource field. Used for
  70  *              (Short descriptor) interrupt and DMA lists.
  71  *
  72  ******************************************************************************/
  73 
 
48   74 static u8 acpi_rs_count_set_bits(u16 bit_field)
  75 {
  76    u8 bits_set;
  77 
  78    ACPI_FUNCTION_ENTRY();
  79 
228 48   80    for (bits_set = 0; bit_field; bits_set++) {
  81       /* Zero the least significant bit that is set */
  82 
  83       bit_field &= (bit_field - 1);
  84    }
  85 
48    86    return (bits_set);
  87 }
  88 
  89 /*******************************************************************************
  90  *
  91  * FUNCTION:    acpi_rs_struct_option_length
  92  *
  93  * PARAMETERS:  resource_source     - Pointer to optional descriptor field
  94  *
  95  * RETURN:      Status
  96  *
  97  * DESCRIPTION: Common code to handle optional resource_source_index and
  98  *              resource_source fields in some Large descriptors. Used during
  99  *              list-to-stream conversion
  100  *
  101  ******************************************************************************/
  102 
  103 static acpi_rs_length
 
- 104 acpi_rs_struct_option_length(struct acpi_resource_source *resource_source)
  105 {
  106    ACPI_FUNCTION_ENTRY();
  107 
  108    /*
  109     * If the resource_source string is valid, return the size of the string
  110     * (string_length includes the NULL terminator) plus the size of the
  111     * resource_source_index (1).
  112     */
- 113    if (resource_source->string_ptr) {
 - 114       return ((acpi_rs_length) (resource_source->string_length + 1));
  115    }
  116 
 - 117    return (0);
  118 }
  119 
  120 /*******************************************************************************
  121  *
  122  * FUNCTION:    acpi_rs_stream_option_length
  123  *
  124  * PARAMETERS:  resource_length     - Length from the resource header
  125  *              minimum_total_length - Minimum length of this resource, before
  126  *                                    any optional fields. Includes header size
  127  *
  128  * RETURN:      Length of optional string (0 if no string present)
  129  *
  130  * DESCRIPTION: Common code to handle optional resource_source_index and
  131  *              resource_source fields in some Large descriptors. Used during
  132  *              stream-to-list conversion
  133  *
  134  ******************************************************************************/
  135 
  136 static u32
 
138   137 acpi_rs_stream_option_length(u32 resource_length,
  138               u32 minimum_aml_resource_length)
  139 {
  140    u32 string_length = 0;
  141 
  142    ACPI_FUNCTION_ENTRY();
  143 
  144    /*
  145     * The resource_source_index and resource_source are optional elements of some
  146     * Large-type resource descriptors.
  147     */
  148 
  149    /*
  150     * If the length of the actual resource descriptor is greater than the ACPI
  151     * spec-defined minimum length, it means that a resource_source_index exists
  152     * and is followed by a (required) null terminated string. The string length
  153     * (including the null terminator) is the resource length minus the minimum
  154     * length, minus one byte for the resource_source_index itself.
  155     */
102 36   156    if (resource_length > minimum_aml_resource_length) {
  157       /* Compute the length of the optional string */
  158 
  159       string_length =
  160           resource_length - minimum_aml_resource_length - 1;
  161    }
  162 
  163    /* Round up length to 32 bits for internal structure alignment */
  164 
138    165    return (ACPI_ROUND_UP_to_32_bITS(string_length));
  166 }
  167 
  168 /*******************************************************************************
  169  *
  170  * FUNCTION:    acpi_rs_get_aml_length
  171  *
  172  * PARAMETERS:  Resource            - Pointer to the resource linked list
  173  *              size_needed         - Where the required size is returned
  174  *
  175  * RETURN:      Status
  176  *
  177  * DESCRIPTION: Takes a linked list of internal resource descriptors and
  178  *              calculates the size buffer needed to hold the corresponding
  179  *              external resource byte stream.
  180  *
  181  ******************************************************************************/
  182 
  183 acpi_status
 
- 184 acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed)
  185 {
  186    acpi_size aml_size_needed = 0;
  187    acpi_rs_length total_size;
  188 
  189    ACPI_FUNCTION_TRACE("rs_get_aml_length");
  190 
  191    /* Traverse entire list of internal resource descriptors */
  192 
- 193    while (resource) {
  194       /* Validate the descriptor type */
  195 
- 196       if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
 - 197          return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
  198       }
  199 
  200       /* Get the base size of the (external stream) resource descriptor */
  201 
  202       total_size = acpi_gbl_aml_resource_sizes[resource->type];
  203 
  204       /*
  205        * Augment the base size for descriptors with optional and/or
  206        * variable-length fields
  207        */
    208       switch (resource->type) {
 - 209       case ACPI_RESOURCE_TYPE_VENDOR:
  210          /*
  211           * Vendor Defined Resource:
  212           * For a Vendor Specific resource, if the Length is between 1 and 7
  213           * it will be created as a Small Resource data type, otherwise it
  214           * is a Large Resource data type.
  215           */
- 216          if (resource->data.vendor.byte_length > 7) {
  217             /* Base size of a Large resource descriptor */
  218 
  219             total_size =
  220                 sizeof(struct aml_resource_large_header);
  221          }
  222 
  223          /* Add the size of the vendor-specific data */
  224 
  225          total_size = (acpi_rs_length)
  226              (total_size + resource->data.vendor.byte_length);
 - 227          break;
  228 
 - 229       case ACPI_RESOURCE_TYPE_END_TAG:
  230          /*
  231           * End Tag:
  232           * We are done -- return the accumulated total size.
  233           */
  234          *size_needed = aml_size_needed + total_size;
  235 
  236          /* Normal exit */
  237 
 - 238          return_ACPI_STATUS(AE_OK);
  239 
 - 240       case ACPI_RESOURCE_TYPE_ADDRESS16:
  241          /*
  242           * 16-Bit Address Resource:
  243           * Add the size of the optional resource_source info
  244           */
  245          total_size = (acpi_rs_length)
  246              (total_size +
  247               acpi_rs_struct_option_length(&resource->data.
  248                        address16.
  249                        resource_source));
 - 250          break;
  251 
 - 252       case ACPI_RESOURCE_TYPE_ADDRESS32:
  253          /*
  254           * 32-Bit Address Resource:
  255           * Add the size of the optional resource_source info
  256           */
  257          total_size = (acpi_rs_length)
  258              (total_size +
  259               acpi_rs_struct_option_length(&resource->data.
  260                        address32.
  261                        resource_source));
 - 262          break;
  263 
 - 264       case ACPI_RESOURCE_TYPE_ADDRESS64:
  265          /*
  266           * 64-Bit Address Resource:
  267           * Add the size of the optional resource_source info
  268           */
  269          total_size = (acpi_rs_length)
  270              (total_size +
  271               acpi_rs_struct_option_length(&resource->data.
  272                        address64.
  273                        resource_source));
 - 274          break;
  275 
 - 276       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          total_size = (acpi_rs_length)
  283              (total_size +
  284               ((resource->data.extended_irq.interrupt_count -
  285                 1) * 4) +
  286               /* Add the size of the optional resource_source info */
  287               acpi_rs_struct_option_length(&resource->data.
  288                        extended_irq.
  289                        resource_source));
 - 290          break;
  291 
 - 292       default:
 - 293          break;
  294       }
  295 
  296       /* Update the total */
  297 
  298       aml_size_needed += total_size;
  299 
  300       /* Point to the next object */
  301 
  302       resource =
  303           ACPI_ADD_PTR(struct acpi_resource, resource,
  304              resource->length);
  305    }
  306 
  307    /* Did not find an end_tag resource descriptor */
  308 
 - 309    return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
  310 }
  311 
  312 /*******************************************************************************
  313  *
  314  * FUNCTION:    acpi_rs_get_list_length
  315  *
  316  * PARAMETERS:  aml_buffer          - Pointer to the resource byte stream
  317  *              aml_buffer_length   - Size of aml_buffer
  318  *              size_needed         - Where the size needed is returned
  319  *
  320  * RETURN:      Status
  321  *
  322  * DESCRIPTION: Takes an external resource byte stream and calculates the size
  323  *              buffer needed to hold the corresponding internal resource
  324  *              descriptor linked list.
  325  *
  326  ******************************************************************************/
  327 
  328 acpi_status
 
120   329 acpi_rs_get_list_length(u8 * aml_buffer,
  330          u32 aml_buffer_length, acpi_size * size_needed)
  331 {
  332    acpi_status status;
  333    u8 *end_aml;
  334    u8 *buffer;
  335    u32 buffer_size = 0;
  336    u16 temp16;
  337    u16 resource_length;
  338    u32 extra_struct_bytes;
  339    u8 resource_index;
  340    u8 minimum_aml_resource_length;
  341 
  342    ACPI_FUNCTION_TRACE("rs_get_list_length");
  343 
  344    end_aml = aml_buffer + aml_buffer_length;
  345 
  346    /* Walk the list of AML resource descriptors */
  347 
426 - 348    while (aml_buffer < end_aml) {
  349       /* Validate the Resource Type and Resource Length */
  350 
  351       status = acpi_ut_validate_resource(aml_buffer, &resource_index);
426 - 352       if (ACPI_FAILURE(status)) {
 - 353          return_ACPI_STATUS(status);
  354       }
  355 
  356       /* Get the resource length and base (minimum) AML size */
  357 
  358       resource_length = acpi_ut_get_resource_length(aml_buffer);
  359       minimum_aml_resource_length =
  360           acpi_gbl_resource_aml_sizes[resource_index];
  361 
  362       /*
  363        * Augment the size for descriptors with optional
  364        * and/or variable length fields
  365        */
  366       extra_struct_bytes = 0;
  367       buffer =
  368           aml_buffer + acpi_ut_get_resource_header_length(aml_buffer);
  369 
    370       switch (acpi_ut_get_resource_type(aml_buffer)) {
48    371       case ACPI_RESOURCE_NAME_IRQ:
  372          /*
  373           * IRQ Resource:
  374           * Get the number of bits set in the 16-bit IRQ mask
  375           */
  376          ACPI_MOVE_16_TO_16(&temp16, buffer);
  377          extra_struct_bytes = acpi_rs_count_set_bits(temp16);
48    378          break;
  379 
 - 380       case ACPI_RESOURCE_NAME_DMA:
  381          /*
  382           * DMA Resource:
  383           * Get the number of bits set in the 8-bit DMA mask
  384           */
  385          extra_struct_bytes = acpi_rs_count_set_bits(*buffer);
 - 386          break;
  387 
 - 388       case ACPI_RESOURCE_NAME_VENDOR_SMALL:
  389          /*
  390           * Vendor Resource:
  391           * Ensure a 32-bit boundary for the structure
  392           */
  393          extra_struct_bytes =
  394              ACPI_ROUND_UP_to_32_bITS(resource_length);
 - 395          break;
  396 
120    397       case ACPI_RESOURCE_NAME_END_TAG:
  398          /*
  399           * End Tag: This is the normal exit, add size of end_tag
  400           */
  401          *size_needed = buffer_size + ACPI_RS_SIZE_MIN;
120    402          return_ACPI_STATUS(AE_OK);
  403 
 - 404       case ACPI_RESOURCE_NAME_VENDOR_LARGE:
  405          /*
  406           * Vendor Resource:
  407           * Add vendor data and ensure a 32-bit boundary for the structure
  408           */
  409          extra_struct_bytes =
  410              ACPI_ROUND_UP_to_32_bITS(resource_length);
 - 411          break;
  412 
84    413       case ACPI_RESOURCE_NAME_ADDRESS32:
   414       case ACPI_RESOURCE_NAME_ADDRESS16:
  415          /*
  416           * 32-Bit or 16-bit Address Resource:
  417           * Add the size of any optional data (resource_source)
  418           */
  419          extra_struct_bytes =
  420              acpi_rs_stream_option_length(resource_length,
  421                       minimum_aml_resource_length);
90    422          break;
  423 
48    424       case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
  425          /*
  426           * Extended IRQ:
  427           * Point past the interrupt_vector_flags to get the
  428           * interrupt_table_length.
  429           */
  430          buffer++;
  431 
  432          extra_struct_bytes =
  433              /*
  434               * Add 4 bytes for each additional interrupt. Note: at
  435               * least one interrupt is required and is included in
  436               * the minimum descriptor size
  437               */
  438              ((*buffer - 1) * sizeof(u32)) +
  439              /* Add the size of any optional data (resource_source) */
  440              acpi_rs_stream_option_length(resource_length -
  441                       extra_struct_bytes,
  442                       minimum_aml_resource_length);
48    443          break;
  444 
 - 445       case ACPI_RESOURCE_NAME_ADDRESS64:
  446          /*
  447           * 64-Bit Address Resource:
  448           * Add the size of any optional data (resource_source)
  449           * Ensure a 64-bit boundary for the structure
  450           */
  451          extra_struct_bytes =
  452              ACPI_ROUND_UP_to_64_bITS
  453              (acpi_rs_stream_option_length
  454               (resource_length, minimum_aml_resource_length));
 - 455          break;
  456 
120    457       default:
120    458          break;
  459       }
  460 
  461       /* Update the required buffer size for the internal descriptor structs */
  462 
  463       temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] +
  464             extra_struct_bytes);
  465       buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16);
  466 
  467       /*
  468        * Point to the next resource within the stream
  469        * using the size of the header plus the length contained in the header
  470        */
  471       aml_buffer += acpi_ut_get_descriptor_length(aml_buffer);
  472    }
  473 
  474    /* Did not find an end_tag resource descriptor */
  475 
 - 476    return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
  477 }
  478 
  479 /*******************************************************************************
  480  *
  481  * FUNCTION:    acpi_rs_get_pci_routing_table_length
  482  *
  483  * PARAMETERS:  package_object          - Pointer to the package object
  484  *              buffer_size_needed      - u32 pointer of the size buffer
  485  *                                        needed to properly return the
  486  *                                        parsed data
  487  *
  488  * RETURN:      Status
  489  *
  490  * DESCRIPTION: Given a package representing a PCI routing table, this
  491  *              calculates the size of the corresponding linked list of
  492  *              descriptions.
  493  *
  494  ******************************************************************************/
  495 
  496 acpi_status
 
24   497 acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
  498                  acpi_size * buffer_size_needed)
  499 {
  500    u32 number_of_elements;
  501    acpi_size temp_size_needed = 0;
  502    union acpi_operand_object **top_object_list;
  503    u32 index;
  504    union acpi_operand_object *package_element;
  505    union acpi_operand_object **sub_object_list;
  506    u8 name_found;
  507    u32 table_index;
  508 
  509    ACPI_FUNCTION_TRACE("rs_get_pci_routing_table_length");
  510 
  511    number_of_elements = package_object->package.count;
  512 
  513    /*
  514     * Calculate the size of the return buffer.
  515     * The base size is the number of elements * the sizes of the
  516     * structures.  Additional space for the strings is added below.
  517     * The minus one is to subtract the size of the u8 Source[1]
  518     * member because it is added below.
  519     *
  520     * But each PRT_ENTRY structure has a pointer to a string and
  521     * the size of that string must be found.
  522     */
  523    top_object_list = package_object->package.elements;
  524 
156 24   525    for (index = 0; index < number_of_elements; index++) {
  526       /* Dereference the sub-package */
  527 
  528       package_element = *top_object_list;
  529 
  530       /*
  531        * The sub_object_list will now point to an array of the
  532        * four IRQ elements: Address, Pin, Source and source_index
  533        */
  534       sub_object_list = package_element->package.elements;
  535 
  536       /* Scan the irq_table_elements for the Source Name String */
  537 
  538       name_found = FALSE;
  539 
624 156   540       for (table_index = 0; table_index < 4 && !name_found;
624    540     T && T
 - 540     T && F
 156   540     F && _
  541            table_index++) {
  542          if (*sub_object_list &&   /* Null object allowed */