brintos

brintos / linux-shallow public Read only

0
0
Text · 7.5 KiB · fcb9de0 Raw
287 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: nsload - namespace loading/expanding/contracting procedures5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#include <acpi/acpi.h>11#include "accommon.h"12#include "acnamesp.h"13#include "acdispat.h"14#include "actables.h"15#include "acinterp.h"16 17#define _COMPONENT          ACPI_NAMESPACE18ACPI_MODULE_NAME("nsload")19 20/* Local prototypes */21#ifdef ACPI_FUTURE_IMPLEMENTATION22acpi_status acpi_ns_unload_namespace(acpi_handle handle);23 24static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);25#endif26 27/*******************************************************************************28 *29 * FUNCTION:    acpi_ns_load_table30 *31 * PARAMETERS:  table_index     - Index for table to be loaded32 *              node            - Owning NS node33 *34 * RETURN:      Status35 *36 * DESCRIPTION: Load one ACPI table into the namespace37 *38 ******************************************************************************/39 40acpi_status41acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)42{43	acpi_status status;44 45	ACPI_FUNCTION_TRACE(ns_load_table);46 47	/* If table already loaded into namespace, just return */48 49	if (acpi_tb_is_table_loaded(table_index)) {50		status = AE_ALREADY_EXISTS;51		goto unlock;52	}53 54	ACPI_DEBUG_PRINT((ACPI_DB_INFO,55			  "**** Loading table into namespace ****\n"));56 57	status = acpi_tb_allocate_owner_id(table_index);58	if (ACPI_FAILURE(status)) {59		goto unlock;60	}61 62	/*63	 * Parse the table and load the namespace with all named64	 * objects found within. Control methods are NOT parsed65	 * at this time. In fact, the control methods cannot be66	 * parsed until the entire namespace is loaded, because67	 * if a control method makes a forward reference (call)68	 * to another control method, we can't continue parsing69	 * because we don't know how many arguments to parse next!70	 */71	status = acpi_ns_parse_table(table_index, node);72	if (ACPI_SUCCESS(status)) {73		acpi_tb_set_table_loaded_flag(table_index, TRUE);74	} else {75		/*76		 * On error, delete any namespace objects created by this table.77		 * We cannot initialize these objects, so delete them. There are78		 * a couple of especially bad cases:79		 * AE_ALREADY_EXISTS - namespace collision.80		 * AE_NOT_FOUND - the target of a Scope operator does not81		 * exist. This target of Scope must already exist in the82		 * namespace, as per the ACPI specification.83		 */84		acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list.85						  tables[table_index].owner_id);86 87		acpi_tb_release_owner_id(table_index);88		return_ACPI_STATUS(status);89	}90 91unlock:92	if (ACPI_FAILURE(status)) {93		return_ACPI_STATUS(status);94	}95 96	/*97	 * Now we can parse the control methods. We always parse98	 * them here for a sanity check, and if configured for99	 * just-in-time parsing, we delete the control method100	 * parse trees.101	 */102	ACPI_DEBUG_PRINT((ACPI_DB_INFO,103			  "**** Begin Table Object Initialization\n"));104 105	acpi_ex_enter_interpreter();106	status = acpi_ds_initialize_objects(table_index, node);107	acpi_ex_exit_interpreter();108 109	ACPI_DEBUG_PRINT((ACPI_DB_INFO,110			  "**** Completed Table Object Initialization\n"));111 112	return_ACPI_STATUS(status);113}114 115#ifdef ACPI_OBSOLETE_FUNCTIONS116/*******************************************************************************117 *118 * FUNCTION:    acpi_load_namespace119 *120 * PARAMETERS:  None121 *122 * RETURN:      Status123 *124 * DESCRIPTION: Load the name space from what ever is pointed to by DSDT.125 *              (DSDT points to either the BIOS or a buffer.)126 *127 ******************************************************************************/128 129acpi_status acpi_ns_load_namespace(void)130{131	acpi_status status;132 133	ACPI_FUNCTION_TRACE(acpi_load_name_space);134 135	/* There must be at least a DSDT installed */136 137	if (acpi_gbl_DSDT == NULL) {138		ACPI_ERROR((AE_INFO, "DSDT is not in memory"));139		return_ACPI_STATUS(AE_NO_ACPI_TABLES);140	}141 142	/*143	 * Load the namespace. The DSDT is required,144	 * but the SSDT and PSDT tables are optional.145	 */146	status = acpi_ns_load_table_by_type(ACPI_TABLE_ID_DSDT);147	if (ACPI_FAILURE(status)) {148		return_ACPI_STATUS(status);149	}150 151	/* Ignore exceptions from these */152 153	(void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_SSDT);154	(void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_PSDT);155 156	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,157			      "ACPI Namespace successfully loaded at root %p\n",158			      acpi_gbl_root_node));159 160	return_ACPI_STATUS(status);161}162#endif163 164#ifdef ACPI_FUTURE_IMPLEMENTATION165/*******************************************************************************166 *167 * FUNCTION:    acpi_ns_delete_subtree168 *169 * PARAMETERS:  start_handle        - Handle in namespace where search begins170 *171 * RETURNS      Status172 *173 * DESCRIPTION: Walks the namespace starting at the given handle and deletes174 *              all objects, entries, and scopes in the entire subtree.175 *176 *              Namespace/Interpreter should be locked or the subsystem should177 *              be in shutdown before this routine is called.178 *179 ******************************************************************************/180 181static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle)182{183	acpi_status status;184	acpi_handle child_handle;185	acpi_handle parent_handle;186	acpi_handle next_child_handle;187	acpi_handle dummy;188	u32 level;189 190	ACPI_FUNCTION_TRACE(ns_delete_subtree);191 192	parent_handle = start_handle;193	child_handle = NULL;194	level = 1;195 196	/*197	 * Traverse the tree of objects until we bubble back up198	 * to where we started.199	 */200	while (level > 0) {201 202		/* Attempt to get the next object in this scope */203 204		status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle,205					      child_handle, &next_child_handle);206 207		child_handle = next_child_handle;208 209		/* Did we get a new object? */210 211		if (ACPI_SUCCESS(status)) {212 213			/* Check if this object has any children */214 215			if (ACPI_SUCCESS216			    (acpi_get_next_object217			     (ACPI_TYPE_ANY, child_handle, NULL, &dummy))) {218				/*219				 * There is at least one child of this object,220				 * visit the object221				 */222				level++;223				parent_handle = child_handle;224				child_handle = NULL;225			}226		} else {227			/*228			 * No more children in this object, go back up to229			 * the object's parent230			 */231			level--;232 233			/* Delete all children now */234 235			acpi_ns_delete_children(child_handle);236 237			child_handle = parent_handle;238			status = acpi_get_parent(parent_handle, &parent_handle);239			if (ACPI_FAILURE(status)) {240				return_ACPI_STATUS(status);241			}242		}243	}244 245	/* Now delete the starting object, and we are done */246 247	acpi_ns_remove_node(child_handle);248	return_ACPI_STATUS(AE_OK);249}250 251/*******************************************************************************252 *253 *  FUNCTION:       acpi_ns_unload_name_space254 *255 *  PARAMETERS:     handle          - Root of namespace subtree to be deleted256 *257 *  RETURN:         Status258 *259 *  DESCRIPTION:    Shrinks the namespace, typically in response to an undocking260 *                  event. Deletes an entire subtree starting from (and261 *                  including) the given handle.262 *263 ******************************************************************************/264 265acpi_status acpi_ns_unload_namespace(acpi_handle handle)266{267	acpi_status status;268 269	ACPI_FUNCTION_TRACE(ns_unload_name_space);270 271	/* Parameter validation */272 273	if (!acpi_gbl_root_node) {274		return_ACPI_STATUS(AE_NO_NAMESPACE);275	}276 277	if (!handle) {278		return_ACPI_STATUS(AE_BAD_PARAMETER);279	}280 281	/* This function does the real work */282 283	status = acpi_ns_delete_subtree(handle);284	return_ACPI_STATUS(status);285}286#endif287