Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: rslist - Linked list utilities
  4.  *
  5.  ******************************************************************************/
  6.  
  7. /*
  8.  * Copyright (C) 2000 - 2015, Intel Corp.
  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 "accommon.h"
  46. #include "acresrc.h"
  47.  
  48. #define _COMPONENT          ACPI_RESOURCES
  49. ACPI_MODULE_NAME("rslist")
  50.  
  51. /*******************************************************************************
  52.  *
  53.  * FUNCTION:    acpi_rs_convert_aml_to_resources
  54.  *
  55.  * PARAMETERS:  acpi_walk_aml_callback
  56.  *              resource_ptr            - Pointer to the buffer that will
  57.  *                                        contain the output structures
  58.  *
  59.  * RETURN:      Status
  60.  *
  61.  * DESCRIPTION: Convert an AML resource to an internal representation of the
  62.  *              resource that is aligned and easier to access.
  63.  *
  64.  ******************************************************************************/
  65. acpi_status
  66. acpi_rs_convert_aml_to_resources(u8 * aml,
  67.                                  u32 length,
  68.                                  u32 offset, u8 resource_index, void **context)
  69. {
  70.         struct acpi_resource **resource_ptr =
  71.             ACPI_CAST_INDIRECT_PTR(struct acpi_resource, context);
  72.         struct acpi_resource *resource;
  73.         union aml_resource *aml_resource;
  74.         struct acpi_rsconvert_info *conversion_table;
  75.         acpi_status status;
  76.  
  77.         ACPI_FUNCTION_TRACE(rs_convert_aml_to_resources);
  78.  
  79.         /*
  80.          * Check that the input buffer and all subsequent pointers into it
  81.          * are aligned on a native word boundary. Most important on IA64
  82.          */
  83.         resource = *resource_ptr;
  84.         if (ACPI_IS_MISALIGNED(resource)) {
  85.                 ACPI_WARNING((AE_INFO,
  86.                               "Misaligned resource pointer %p", resource));
  87.         }
  88.  
  89.         /* Get the appropriate conversion info table */
  90.  
  91.         aml_resource = ACPI_CAST_PTR(union aml_resource, aml);
  92.         if (acpi_ut_get_resource_type(aml) == ACPI_RESOURCE_NAME_SERIAL_BUS) {
  93.                 if (aml_resource->common_serial_bus.type >
  94.                     AML_RESOURCE_MAX_SERIALBUSTYPE) {
  95.                         conversion_table = NULL;
  96.                 } else {
  97.                         /* This is an I2C, SPI, or UART serial_bus descriptor */
  98.  
  99.                         conversion_table =
  100.                             acpi_gbl_convert_resource_serial_bus_dispatch
  101.                             [aml_resource->common_serial_bus.type];
  102.                 }
  103.         } else {
  104.                 conversion_table =
  105.                     acpi_gbl_get_resource_dispatch[resource_index];
  106.         }
  107.  
  108.         if (!conversion_table) {
  109.                 ACPI_ERROR((AE_INFO,
  110.                             "Invalid/unsupported resource descriptor: Type 0x%2.2X",
  111.                             resource_index));
  112.                 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
  113.         }
  114.  
  115.         /* Convert the AML byte stream resource to a local resource struct */
  116.  
  117.         status =
  118.             acpi_rs_convert_aml_to_resource(resource, aml_resource,
  119.                                             conversion_table);
  120.         if (ACPI_FAILURE(status)) {
  121.                 ACPI_EXCEPTION((AE_INFO, status,
  122.                                 "Could not convert AML resource (Type 0x%X)",
  123.                                 *aml));
  124.                 return_ACPI_STATUS(status);
  125.         }
  126.  
  127.         ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  128.                           "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
  129.                           acpi_ut_get_resource_type(aml), length,
  130.                           resource->length));
  131.  
  132.         /* Point to the next structure in the output buffer */
  133.  
  134.         *resource_ptr = ACPI_NEXT_RESOURCE(resource);
  135.         return_ACPI_STATUS(AE_OK);
  136. }
  137.  
  138. /*******************************************************************************
  139.  *
  140.  * FUNCTION:    acpi_rs_convert_resources_to_aml
  141.  *
  142.  * PARAMETERS:  resource            - Pointer to the resource linked list
  143.  *              aml_size_needed     - Calculated size of the byte stream
  144.  *                                    needed from calling acpi_rs_get_aml_length()
  145.  *                                    The size of the output_buffer is
  146.  *                                    guaranteed to be >= aml_size_needed
  147.  *              output_buffer       - Pointer to the buffer that will
  148.  *                                    contain the byte stream
  149.  *
  150.  * RETURN:      Status
  151.  *
  152.  * DESCRIPTION: Takes the resource linked list and parses it, creating a
  153.  *              byte stream of resources in the caller's output buffer
  154.  *
  155.  ******************************************************************************/
  156.  
  157. acpi_status
  158. acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
  159.                                  acpi_size aml_size_needed, u8 * output_buffer)
  160. {
  161.         u8 *aml = output_buffer;
  162.         u8 *end_aml = output_buffer + aml_size_needed;
  163.         struct acpi_rsconvert_info *conversion_table;
  164.         acpi_status status;
  165.  
  166.         ACPI_FUNCTION_TRACE(rs_convert_resources_to_aml);
  167.  
  168.         /* Walk the resource descriptor list, convert each descriptor */
  169.  
  170.         while (aml < end_aml) {
  171.  
  172.                 /* Validate the (internal) Resource Type */
  173.  
  174.                 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
  175.                         ACPI_ERROR((AE_INFO,
  176.                                     "Invalid descriptor type (0x%X) in resource list",
  177.                                     resource->type));
  178.                         return_ACPI_STATUS(AE_BAD_DATA);
  179.                 }
  180.  
  181.                 /* Sanity check the length. It must not be zero, or we loop forever */
  182.  
  183.                 if (!resource->length) {
  184.                         ACPI_ERROR((AE_INFO,
  185.                                     "Invalid zero length descriptor in resource list\n"));
  186.                         return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
  187.                 }
  188.  
  189.                 /* Perform the conversion */
  190.  
  191.                 if (resource->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
  192.                         if (resource->data.common_serial_bus.type >
  193.                             AML_RESOURCE_MAX_SERIALBUSTYPE) {
  194.                                 conversion_table = NULL;
  195.                         } else {
  196.                                 /* This is an I2C, SPI, or UART serial_bus descriptor */
  197.  
  198.                                 conversion_table =
  199.                                     acpi_gbl_convert_resource_serial_bus_dispatch
  200.                                     [resource->data.common_serial_bus.type];
  201.                         }
  202.                 } else {
  203.                         conversion_table =
  204.                             acpi_gbl_set_resource_dispatch[resource->type];
  205.                 }
  206.  
  207.                 if (!conversion_table) {
  208.                         ACPI_ERROR((AE_INFO,
  209.                                     "Invalid/unsupported resource descriptor: Type 0x%2.2X",
  210.                                     resource->type));
  211.                         return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
  212.                 }
  213.  
  214.                 status = acpi_rs_convert_resource_to_aml(resource,
  215.                                                          ACPI_CAST_PTR(union
  216.                                                                        aml_resource,
  217.                                                                        aml),
  218.                                                          conversion_table);
  219.                 if (ACPI_FAILURE(status)) {
  220.                         ACPI_EXCEPTION((AE_INFO, status,
  221.                                         "Could not convert resource (type 0x%X) to AML",
  222.                                         resource->type));
  223.                         return_ACPI_STATUS(status);
  224.                 }
  225.  
  226.                 /* Perform final sanity check on the new AML resource descriptor */
  227.  
  228.                 status = acpi_ut_validate_resource(NULL,
  229.                                                    ACPI_CAST_PTR(union
  230.                                                                  aml_resource,
  231.                                                                  aml), NULL);
  232.                 if (ACPI_FAILURE(status)) {
  233.                         return_ACPI_STATUS(status);
  234.                 }
  235.  
  236.                 /* Check for end-of-list, normal exit */
  237.  
  238.                 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
  239.  
  240.                         /* An End Tag indicates the end of the input Resource Template */
  241.  
  242.                         return_ACPI_STATUS(AE_OK);
  243.                 }
  244.  
  245.                 /*
  246.                  * Extract the total length of the new descriptor and set the
  247.                  * Aml to point to the next (output) resource descriptor
  248.                  */
  249.                 aml += acpi_ut_get_descriptor_length(aml);
  250.  
  251.                 /* Point to the next input resource descriptor */
  252.  
  253.                 resource = ACPI_NEXT_RESOURCE(resource);
  254.         }
  255.  
  256.         /* Completed buffer, but did not find an end_tag resource descriptor */
  257.  
  258.         return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
  259. }
  260.