acpi_status acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) { acpi_status status; ACPI_FUNCTION_TRACE(ns_load_table); status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } if (acpi_tb_is_table_loaded(table_index)) { status = AE_ALREADY_EXISTS; goto unlock; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Loading table into namespace ****\n")); status = acpi_tb_allocate_owner_id(table_index); if (ACPI_FAILURE(status)) { goto unlock; } status = acpi_ns_parse_table(table_index, node); if (ACPI_SUCCESS(status)) { acpi_tb_set_table_loaded_flag(table_index, TRUE); } else { (void)acpi_tb_release_owner_id(table_index); } unlock: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Begin Table Method Parsing and Object Initialization\n")); status = acpi_ds_initialize_objects(table_index, node); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Completed Table Method Parsing and Object Initialization\n")); return_ACPI_STATUS(status); }
acpi_status acpi_ns_load_table(acpi_native_uint table_index, struct acpi_namespace_node *node) { acpi_status status; ACPI_FUNCTION_TRACE(ns_load_table); /* * Parse the table and load the namespace with all named * objects found within. Control methods are NOT parsed * at this time. In fact, the control methods cannot be * parsed until the entire namespace is loaded, because * if a control method makes a forward reference (call) * to another control method, we can't continue parsing * because we don't know how many arguments to parse next! */ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* If table already loaded into namespace, just return */ if (acpi_tb_is_table_loaded(table_index)) { status = AE_ALREADY_EXISTS; goto unlock; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Loading table into namespace ****\n")); status = acpi_tb_allocate_owner_id(table_index); if (ACPI_FAILURE(status)) { goto unlock; } status = acpi_ns_parse_table(table_index, node); if (ACPI_SUCCESS(status)) { acpi_tb_set_table_loaded_flag(table_index, TRUE); } else { (void)acpi_tb_release_owner_id(table_index); } unlock: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* * Now we can parse the control methods. We always parse * them here for a sanity check, and if configured for * just-in-time parsing, we delete the control method * parse trees. */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Begin Table Method Parsing and Object Initialization ****\n")); status = acpi_ds_initialize_objects(table_index, node); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Completed Table Method Parsing and Object Initialization ****\n")); return_ACPI_STATUS(status); }
acpi_status acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) { acpi_status status; ACPI_FUNCTION_TRACE(ns_load_table); /* If table already loaded into namespace, just return */ if (acpi_tb_is_table_loaded(table_index)) { status = AE_ALREADY_EXISTS; goto unlock; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Loading table into namespace ****\n")); status = acpi_tb_allocate_owner_id(table_index); if (ACPI_FAILURE(status)) { goto unlock; } /* * Parse the table and load the namespace with all named * objects found within. Control methods are NOT parsed * at this time. In fact, the control methods cannot be * parsed until the entire namespace is loaded, because * if a control method makes a forward reference (call) * to another control method, we can't continue parsing * because we don't know how many arguments to parse next! */ status = acpi_ns_parse_table(table_index, node); if (ACPI_SUCCESS(status)) { acpi_tb_set_table_loaded_flag(table_index, TRUE); } else { /* * On error, delete any namespace objects created by this table. * We cannot initialize these objects, so delete them. There are * a couple of especially bad cases: * AE_ALREADY_EXISTS - namespace collision. * AE_NOT_FOUND - the target of a Scope operator does not * exist. This target of Scope must already exist in the * namespace, as per the ACPI specification. */ acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list. tables[table_index].owner_id); acpi_tb_release_owner_id(table_index); return_ACPI_STATUS(status); } unlock: if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* * Now we can parse the control methods. We always parse * them here for a sanity check, and if configured for * just-in-time parsing, we delete the control method * parse trees. */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Begin Table Object Initialization\n")); acpi_ex_enter_interpreter(); status = acpi_ds_initialize_objects(table_index, node); acpi_ex_exit_interpreter(); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Completed Table Object Initialization\n")); /* * This case handles the legacy option that groups all module-level * code blocks together and defers execution until all of the tables * are loaded. Execute all of these blocks at this time. * Execute any module-level code that was detected during the table * load phase. * * Note: this option is deprecated and will be eliminated in the * future. Use of this option can cause problems with AML code that * depends upon in-order immediate execution of module-level code. */ acpi_ns_exec_module_code_list(); return_ACPI_STATUS(status); }
acpi_status acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) { acpi_status status; ACPI_FUNCTION_TRACE(ns_load_table); /* * Parse the table and load the namespace with all named * objects found within. Control methods are NOT parsed * at this time. In fact, the control methods cannot be * parsed until the entire namespace is loaded, because * if a control method makes a forward reference (call) * to another control method, we can't continue parsing * because we don't know how many arguments to parse next! */ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* If table already loaded into namespace, just return */ if (acpi_tb_is_table_loaded(table_index)) { status = AE_ALREADY_EXISTS; goto unlock; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Loading table into namespace ****\n")); status = acpi_tb_allocate_owner_id(table_index); if (ACPI_FAILURE(status)) { goto unlock; } status = acpi_ns_parse_table(table_index, node); if (ACPI_SUCCESS(status)) { acpi_tb_set_table_loaded_flag(table_index, TRUE); } else { /* * On error, delete any namespace objects created by this table. * We cannot initialize these objects, so delete them. There are * a couple of expecially bad cases: * AE_ALREADY_EXISTS - namespace collision. * AE_NOT_FOUND - the target of a Scope operator does not * exist. This target of Scope must already exist in the * namespace, as per the ACPI specification. */ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list. tables[table_index].owner_id); acpi_tb_release_owner_id(table_index); return_ACPI_STATUS(status); } unlock: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* * Now we can parse the control methods. We always parse * them here for a sanity check, and if configured for * just-in-time parsing, we delete the control method * parse trees. */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Begin Table Object Initialization\n")); status = acpi_ds_initialize_objects(table_index, node); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Completed Table Object Initialization\n")); /* * Execute any module-level code that was detected during the table load * phase. Although illegal since ACPI 2.0, there are many machines that * contain this type of code. Each block of detected executable AML code * outside of any control method is wrapped with a temporary control * method object and placed on a global list. The methods on this list * are executed below. * * This case executes the module-level code for each table immediately * after the table has been loaded. This provides compatibility with * other ACPI implementations. Optionally, the execution can be deferred * until later, see acpi_initialize_objects. */ if (!acpi_gbl_group_module_level_code) { acpi_ns_exec_module_code_list(); } return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: acpi_unload_parent_table * * PARAMETERS: object - Handle to any namespace object owned by * the table to be unloaded * * RETURN: Status * * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads * the table and deletes all namespace objects associated with * that table. Unloading of the DSDT is not allowed. * Note: Mainly intended to support hotplug removal of SSDTs. * ******************************************************************************/ acpi_status acpi_unload_parent_table(acpi_handle object) { struct acpi_namespace_node *node = ACPI_CAST_PTR(struct acpi_namespace_node, object); acpi_status status = AE_NOT_EXIST; acpi_owner_id owner_id; u32 i; ACPI_FUNCTION_TRACE(acpi_unload_parent_table); /* Parameter validation */ if (!object) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* * The node owner_id is currently the same as the parent table ID. * However, this could change in the future. */ owner_id = node->owner_id; if (!owner_id) { /* owner_id==0 means DSDT is the owner. DSDT cannot be unloaded */ return_ACPI_STATUS(AE_TYPE); } /* Must acquire the interpreter lock during this operation */ status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Find the table in the global table list */ for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { if (owner_id != acpi_gbl_root_table_list.tables[i].owner_id) { continue; } /* * Allow unload of SSDT and OEMx tables only. Do not allow unload * of the DSDT. No other types of tables should get here, since * only these types can contain AML and thus are the only types * that can create namespace objects. */ if (ACPI_COMPARE_NAME (acpi_gbl_root_table_list.tables[i].signature.ascii, ACPI_SIG_DSDT)) { status = AE_TYPE; break; } /* Ensure the table is actually loaded */ if (!acpi_tb_is_table_loaded(i)) { status = AE_NOT_EXIST; break; } /* Invoke table handler if present */ if (acpi_gbl_table_handler) { (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD, acpi_gbl_root_table_list. tables[i].pointer, acpi_gbl_table_handler_context); } /* * Delete all namespace objects owned by this table. Note that * these objects can appear anywhere in the namespace by virtue * of the AML "Scope" operator. Thus, we need to track ownership * by an ID, not simply a position within the hierarchy. */ status = acpi_tb_delete_namespace_by_owner(i); if (ACPI_FAILURE(status)) { break; } status = acpi_tb_release_owner_id(i); acpi_tb_set_table_loaded_flag(i, FALSE); break; } (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); return_ACPI_STATUS(status); }