Subversion Repositories Kolibri OS

Rev

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

  1. /******************************************************************************
  2.  *
  3.  * Module Name: nsload - namespace loading/expanding/contracting procedures
  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 "acnamesp.h"
  47. #include "acdispat.h"
  48. #include "actables.h"
  49.  
  50. #define _COMPONENT          ACPI_NAMESPACE
  51. ACPI_MODULE_NAME("nsload")
  52.  
  53. /* Local prototypes */
  54. #ifdef ACPI_FUTURE_IMPLEMENTATION
  55. acpi_status acpi_ns_unload_namespace(acpi_handle handle);
  56.  
  57. static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
  58. #endif
  59.  
  60. #ifndef ACPI_NO_METHOD_EXECUTION
  61. /*******************************************************************************
  62.  *
  63.  * FUNCTION:    acpi_ns_load_table
  64.  *
  65.  * PARAMETERS:  table_index     - Index for table to be loaded
  66.  *              node            - Owning NS node
  67.  *
  68.  * RETURN:      Status
  69.  *
  70.  * DESCRIPTION: Load one ACPI table into the namespace
  71.  *
  72.  ******************************************************************************/
  73.  
  74. acpi_status
  75. acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
  76. {
  77.         acpi_status status;
  78.  
  79.         ACPI_FUNCTION_TRACE(ns_load_table);
  80.  
  81.         /*
  82.          * Parse the table and load the namespace with all named
  83.          * objects found within. Control methods are NOT parsed
  84.          * at this time. In fact, the control methods cannot be
  85.          * parsed until the entire namespace is loaded, because
  86.          * if a control method makes a forward reference (call)
  87.          * to another control method, we can't continue parsing
  88.          * because we don't know how many arguments to parse next!
  89.          */
  90.         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  91.         if (ACPI_FAILURE(status)) {
  92.                 return_ACPI_STATUS(status);
  93.         }
  94.  
  95.         /* If table already loaded into namespace, just return */
  96.  
  97.         if (acpi_tb_is_table_loaded(table_index)) {
  98.                 status = AE_ALREADY_EXISTS;
  99.                 goto unlock;
  100.         }
  101.  
  102.         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  103.                           "**** Loading table into namespace ****\n"));
  104.  
  105.         status = acpi_tb_allocate_owner_id(table_index);
  106.         if (ACPI_FAILURE(status)) {
  107.                 goto unlock;
  108.         }
  109.  
  110.         status = acpi_ns_parse_table(table_index, node);
  111.         if (ACPI_SUCCESS(status)) {
  112.                 acpi_tb_set_table_loaded_flag(table_index, TRUE);
  113.         } else {
  114.                 /*
  115.                  * On error, delete any namespace objects created by this table.
  116.                  * We cannot initialize these objects, so delete them. There are
  117.                  * a couple of expecially bad cases:
  118.                  * AE_ALREADY_EXISTS - namespace collision.
  119.                  * AE_NOT_FOUND - the target of a Scope operator does not
  120.                  * exist. This target of Scope must already exist in the
  121.                  * namespace, as per the ACPI specification.
  122.                  */
  123.                 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  124.                 acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list.
  125.                                                   tables[table_index].owner_id);
  126.                 acpi_tb_release_owner_id(table_index);
  127.  
  128.                 return_ACPI_STATUS(status);
  129.         }
  130.  
  131. unlock:
  132.         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  133.  
  134.         if (ACPI_FAILURE(status)) {
  135.                 return_ACPI_STATUS(status);
  136.         }
  137.  
  138.         /*
  139.          * Now we can parse the control methods. We always parse
  140.          * them here for a sanity check, and if configured for
  141.          * just-in-time parsing, we delete the control method
  142.          * parse trees.
  143.          */
  144.         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  145.                           "**** Begin Table Object Initialization\n"));
  146.  
  147.         status = acpi_ds_initialize_objects(table_index, node);
  148.  
  149.         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  150.                           "**** Completed Table Object Initialization\n"));
  151.  
  152.         return_ACPI_STATUS(status);
  153. }
  154.  
  155. #ifdef ACPI_OBSOLETE_FUNCTIONS
  156. /*******************************************************************************
  157.  *
  158.  * FUNCTION:    acpi_load_namespace
  159.  *
  160.  * PARAMETERS:  None
  161.  *
  162.  * RETURN:      Status
  163.  *
  164.  * DESCRIPTION: Load the name space from what ever is pointed to by DSDT.
  165.  *              (DSDT points to either the BIOS or a buffer.)
  166.  *
  167.  ******************************************************************************/
  168.  
  169. acpi_status acpi_ns_load_namespace(void)
  170. {
  171.         acpi_status status;
  172.  
  173.         ACPI_FUNCTION_TRACE(acpi_load_name_space);
  174.  
  175.         /* There must be at least a DSDT installed */
  176.  
  177.         if (acpi_gbl_DSDT == NULL) {
  178.                 ACPI_ERROR((AE_INFO, "DSDT is not in memory"));
  179.                 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
  180.         }
  181.  
  182.         /*
  183.          * Load the namespace. The DSDT is required,
  184.          * but the SSDT and PSDT tables are optional.
  185.          */
  186.         status = acpi_ns_load_table_by_type(ACPI_TABLE_ID_DSDT);
  187.         if (ACPI_FAILURE(status)) {
  188.                 return_ACPI_STATUS(status);
  189.         }
  190.  
  191.         /* Ignore exceptions from these */
  192.  
  193.         (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_SSDT);
  194.         (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_PSDT);
  195.  
  196.         ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
  197.                               "ACPI Namespace successfully loaded at root %p\n",
  198.                               acpi_gbl_root_node));
  199.  
  200.         return_ACPI_STATUS(status);
  201. }
  202. #endif
  203.  
  204. #ifdef ACPI_FUTURE_IMPLEMENTATION
  205. /*******************************************************************************
  206.  *
  207.  * FUNCTION:    acpi_ns_delete_subtree
  208.  *
  209.  * PARAMETERS:  start_handle        - Handle in namespace where search begins
  210.  *
  211.  * RETURNS      Status
  212.  *
  213.  * DESCRIPTION: Walks the namespace starting at the given handle and deletes
  214.  *              all objects, entries, and scopes in the entire subtree.
  215.  *
  216.  *              Namespace/Interpreter should be locked or the subsystem should
  217.  *              be in shutdown before this routine is called.
  218.  *
  219.  ******************************************************************************/
  220.  
  221. static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle)
  222. {
  223.         acpi_status status;
  224.         acpi_handle child_handle;
  225.         acpi_handle parent_handle;
  226.         acpi_handle next_child_handle;
  227.         acpi_handle dummy;
  228.         u32 level;
  229.  
  230.         ACPI_FUNCTION_TRACE(ns_delete_subtree);
  231.  
  232.         parent_handle = start_handle;
  233.         child_handle = NULL;
  234.         level = 1;
  235.  
  236.         /*
  237.          * Traverse the tree of objects until we bubble back up
  238.          * to where we started.
  239.          */
  240.         while (level > 0) {
  241.  
  242.                 /* Attempt to get the next object in this scope */
  243.  
  244.                 status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle,
  245.                                               child_handle, &next_child_handle);
  246.  
  247.                 child_handle = next_child_handle;
  248.  
  249.                 /* Did we get a new object? */
  250.  
  251.                 if (ACPI_SUCCESS(status)) {
  252.  
  253.                         /* Check if this object has any children */
  254.  
  255.                         if (ACPI_SUCCESS
  256.                             (acpi_get_next_object
  257.                              (ACPI_TYPE_ANY, child_handle, NULL, &dummy))) {
  258.                                 /*
  259.                                  * There is at least one child of this object,
  260.                                  * visit the object
  261.                                  */
  262.                                 level++;
  263.                                 parent_handle = child_handle;
  264.                                 child_handle = NULL;
  265.                         }
  266.                 } else {
  267.                         /*
  268.                          * No more children in this object, go back up to
  269.                          * the object's parent
  270.                          */
  271.                         level--;
  272.  
  273.                         /* Delete all children now */
  274.  
  275.                         acpi_ns_delete_children(child_handle);
  276.  
  277.                         child_handle = parent_handle;
  278.                         status = acpi_get_parent(parent_handle, &parent_handle);
  279.                         if (ACPI_FAILURE(status)) {
  280.                                 return_ACPI_STATUS(status);
  281.                         }
  282.                 }
  283.         }
  284.  
  285.         /* Now delete the starting object, and we are done */
  286.  
  287.         acpi_ns_remove_node(child_handle);
  288.         return_ACPI_STATUS(AE_OK);
  289. }
  290.  
  291. /*******************************************************************************
  292.  *
  293.  *  FUNCTION:       acpi_ns_unload_name_space
  294.  *
  295.  *  PARAMETERS:     handle          - Root of namespace subtree to be deleted
  296.  *
  297.  *  RETURN:         Status
  298.  *
  299.  *  DESCRIPTION:    Shrinks the namespace, typically in response to an undocking
  300.  *                  event. Deletes an entire subtree starting from (and
  301.  *                  including) the given handle.
  302.  *
  303.  ******************************************************************************/
  304.  
  305. acpi_status acpi_ns_unload_namespace(acpi_handle handle)
  306. {
  307.         acpi_status status;
  308.  
  309.         ACPI_FUNCTION_TRACE(ns_unload_name_space);
  310.  
  311.         /* Parameter validation */
  312.  
  313.         if (!acpi_gbl_root_node) {
  314.                 return_ACPI_STATUS(AE_NO_NAMESPACE);
  315.         }
  316.  
  317.         if (!handle) {
  318.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  319.         }
  320.  
  321.         /* This function does the real work */
  322.  
  323.         status = acpi_ns_delete_subtree(handle);
  324.  
  325.         return_ACPI_STATUS(status);
  326. }
  327. #endif
  328. #endif
  329.