1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Module Name: tbxfload - Table load/unload external interfaces
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copyright (C) 2000 - 2020, Intel Corp.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun *****************************************************************************/
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #define EXPORT_ACPI_INTERFACES
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <acpi/acpi.h>
13*4882a593Smuzhiyun #include "accommon.h"
14*4882a593Smuzhiyun #include "acnamesp.h"
15*4882a593Smuzhiyun #include "actables.h"
16*4882a593Smuzhiyun #include "acevents.h"
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #define _COMPONENT ACPI_TABLES
19*4882a593Smuzhiyun ACPI_MODULE_NAME("tbxfload")
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun /*******************************************************************************
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * FUNCTION: acpi_load_tables
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * PARAMETERS: None
26*4882a593Smuzhiyun *
27*4882a593Smuzhiyun * RETURN: Status
28*4882a593Smuzhiyun *
29*4882a593Smuzhiyun * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
30*4882a593Smuzhiyun *
31*4882a593Smuzhiyun ******************************************************************************/
acpi_load_tables(void)32*4882a593Smuzhiyun acpi_status ACPI_INIT_FUNCTION acpi_load_tables(void)
33*4882a593Smuzhiyun {
34*4882a593Smuzhiyun acpi_status status;
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(acpi_load_tables);
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun /*
39*4882a593Smuzhiyun * Install the default operation region handlers. These are the
40*4882a593Smuzhiyun * handlers that are defined by the ACPI specification to be
41*4882a593Smuzhiyun * "always accessible" -- namely, system_memory, system_IO, and
42*4882a593Smuzhiyun * PCI_Config. This also means that no _REG methods need to be
43*4882a593Smuzhiyun * run for these address spaces. We need to have these handlers
44*4882a593Smuzhiyun * installed before any AML code can be executed, especially any
45*4882a593Smuzhiyun * module-level code (11/2015).
46*4882a593Smuzhiyun * Note that we allow OSPMs to install their own region handlers
47*4882a593Smuzhiyun * between acpi_initialize_subsystem() and acpi_load_tables() to use
48*4882a593Smuzhiyun * their customized default region handlers.
49*4882a593Smuzhiyun */
50*4882a593Smuzhiyun status = acpi_ev_install_region_handlers();
51*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
52*4882a593Smuzhiyun ACPI_EXCEPTION((AE_INFO, status,
53*4882a593Smuzhiyun "During Region initialization"));
54*4882a593Smuzhiyun return_ACPI_STATUS(status);
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun /* Load the namespace from the tables */
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun status = acpi_tb_load_namespace();
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* Don't let single failures abort the load */
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun if (status == AE_CTRL_TERMINATE) {
64*4882a593Smuzhiyun status = AE_OK;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
68*4882a593Smuzhiyun ACPI_EXCEPTION((AE_INFO, status,
69*4882a593Smuzhiyun "While loading namespace from ACPI tables"));
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /*
73*4882a593Smuzhiyun * Initialize the objects in the namespace that remain uninitialized.
74*4882a593Smuzhiyun * This runs the executable AML that may be part of the declaration of
75*4882a593Smuzhiyun * these name objects:
76*4882a593Smuzhiyun * operation_regions, buffer_fields, Buffers, and Packages.
77*4882a593Smuzhiyun *
78*4882a593Smuzhiyun */
79*4882a593Smuzhiyun status = acpi_ns_initialize_objects();
80*4882a593Smuzhiyun if (ACPI_SUCCESS(status)) {
81*4882a593Smuzhiyun acpi_gbl_namespace_initialized = TRUE;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun return_ACPI_STATUS(status);
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun
ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)87*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /*******************************************************************************
90*4882a593Smuzhiyun *
91*4882a593Smuzhiyun * FUNCTION: acpi_tb_load_namespace
92*4882a593Smuzhiyun *
93*4882a593Smuzhiyun * PARAMETERS: None
94*4882a593Smuzhiyun *
95*4882a593Smuzhiyun * RETURN: Status
96*4882a593Smuzhiyun *
97*4882a593Smuzhiyun * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
98*4882a593Smuzhiyun * the RSDT/XSDT.
99*4882a593Smuzhiyun *
100*4882a593Smuzhiyun ******************************************************************************/
101*4882a593Smuzhiyun acpi_status acpi_tb_load_namespace(void)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun acpi_status status;
104*4882a593Smuzhiyun u32 i;
105*4882a593Smuzhiyun struct acpi_table_header *new_dsdt;
106*4882a593Smuzhiyun struct acpi_table_desc *table;
107*4882a593Smuzhiyun u32 tables_loaded = 0;
108*4882a593Smuzhiyun u32 tables_failed = 0;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(tb_load_namespace);
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun /*
115*4882a593Smuzhiyun * Load the namespace. The DSDT is required, but any SSDT and
116*4882a593Smuzhiyun * PSDT tables are optional. Verify the DSDT.
117*4882a593Smuzhiyun */
118*4882a593Smuzhiyun table = &acpi_gbl_root_table_list.tables[acpi_gbl_dsdt_index];
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun if (!acpi_gbl_root_table_list.current_table_count ||
121*4882a593Smuzhiyun !ACPI_COMPARE_NAMESEG(table->signature.ascii, ACPI_SIG_DSDT) ||
122*4882a593Smuzhiyun ACPI_FAILURE(acpi_tb_validate_table(table))) {
123*4882a593Smuzhiyun status = AE_NO_ACPI_TABLES;
124*4882a593Smuzhiyun goto unlock_and_exit;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun /*
128*4882a593Smuzhiyun * Save the DSDT pointer for simple access. This is the mapped memory
129*4882a593Smuzhiyun * address. We must take care here because the address of the .Tables
130*4882a593Smuzhiyun * array can change dynamically as tables are loaded at run-time. Note:
131*4882a593Smuzhiyun * .Pointer field is not validated until after call to acpi_tb_validate_table.
132*4882a593Smuzhiyun */
133*4882a593Smuzhiyun acpi_gbl_DSDT = table->pointer;
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun /*
136*4882a593Smuzhiyun * Optionally copy the entire DSDT to local memory (instead of simply
137*4882a593Smuzhiyun * mapping it.) There are some BIOSs that corrupt or replace the original
138*4882a593Smuzhiyun * DSDT, creating the need for this option. Default is FALSE, do not copy
139*4882a593Smuzhiyun * the DSDT.
140*4882a593Smuzhiyun */
141*4882a593Smuzhiyun if (acpi_gbl_copy_dsdt_locally) {
142*4882a593Smuzhiyun new_dsdt = acpi_tb_copy_dsdt(acpi_gbl_dsdt_index);
143*4882a593Smuzhiyun if (new_dsdt) {
144*4882a593Smuzhiyun acpi_gbl_DSDT = new_dsdt;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun /*
149*4882a593Smuzhiyun * Save the original DSDT header for detection of table corruption
150*4882a593Smuzhiyun * and/or replacement of the DSDT from outside the OS.
151*4882a593Smuzhiyun */
152*4882a593Smuzhiyun memcpy(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT,
153*4882a593Smuzhiyun sizeof(struct acpi_table_header));
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun /* Load and parse tables */
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
158*4882a593Smuzhiyun status = acpi_ns_load_table(acpi_gbl_dsdt_index, acpi_gbl_root_node);
159*4882a593Smuzhiyun (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
160*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
161*4882a593Smuzhiyun ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed"));
162*4882a593Smuzhiyun tables_failed++;
163*4882a593Smuzhiyun } else {
164*4882a593Smuzhiyun tables_loaded++;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
170*4882a593Smuzhiyun table = &acpi_gbl_root_table_list.tables[i];
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun if (!table->address ||
173*4882a593Smuzhiyun (!ACPI_COMPARE_NAMESEG
174*4882a593Smuzhiyun (table->signature.ascii, ACPI_SIG_SSDT)
175*4882a593Smuzhiyun && !ACPI_COMPARE_NAMESEG(table->signature.ascii,
176*4882a593Smuzhiyun ACPI_SIG_PSDT)
177*4882a593Smuzhiyun && !ACPI_COMPARE_NAMESEG(table->signature.ascii,
178*4882a593Smuzhiyun ACPI_SIG_OSDT))
179*4882a593Smuzhiyun || ACPI_FAILURE(acpi_tb_validate_table(table))) {
180*4882a593Smuzhiyun continue;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun /* Ignore errors while loading tables, get as many as possible */
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
186*4882a593Smuzhiyun status = acpi_ns_load_table(i, acpi_gbl_root_node);
187*4882a593Smuzhiyun (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
188*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
189*4882a593Smuzhiyun ACPI_EXCEPTION((AE_INFO, status,
190*4882a593Smuzhiyun "(%4.4s:%8.8s) while loading table",
191*4882a593Smuzhiyun table->signature.ascii,
192*4882a593Smuzhiyun table->pointer->oem_table_id));
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun tables_failed++;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
197*4882a593Smuzhiyun "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n",
198*4882a593Smuzhiyun table->signature.ascii,
199*4882a593Smuzhiyun table->pointer->oem_table_id));
200*4882a593Smuzhiyun } else {
201*4882a593Smuzhiyun tables_loaded++;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun if (!tables_failed) {
206*4882a593Smuzhiyun ACPI_INFO(("%u ACPI AML tables successfully acquired and loaded", tables_loaded));
207*4882a593Smuzhiyun } else {
208*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
209*4882a593Smuzhiyun "%u table load failures, %u successful",
210*4882a593Smuzhiyun tables_failed, tables_loaded));
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun /* Indicate at least one failure */
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun status = AE_CTRL_TERMINATE;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun #ifdef ACPI_APPLICATION
218*4882a593Smuzhiyun ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "\n"));
219*4882a593Smuzhiyun #endif
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun unlock_and_exit:
222*4882a593Smuzhiyun (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
223*4882a593Smuzhiyun return_ACPI_STATUS(status);
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun /*******************************************************************************
227*4882a593Smuzhiyun *
228*4882a593Smuzhiyun * FUNCTION: acpi_install_table
229*4882a593Smuzhiyun *
230*4882a593Smuzhiyun * PARAMETERS: address - Address of the ACPI table to be installed.
231*4882a593Smuzhiyun * physical - Whether the address is a physical table
232*4882a593Smuzhiyun * address or not
233*4882a593Smuzhiyun *
234*4882a593Smuzhiyun * RETURN: Status
235*4882a593Smuzhiyun *
236*4882a593Smuzhiyun * DESCRIPTION: Dynamically install an ACPI table.
237*4882a593Smuzhiyun * Note: This function should only be invoked after
238*4882a593Smuzhiyun * acpi_initialize_tables() and before acpi_load_tables().
239*4882a593Smuzhiyun *
240*4882a593Smuzhiyun ******************************************************************************/
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun acpi_status ACPI_INIT_FUNCTION
acpi_install_table(acpi_physical_address address,u8 physical)243*4882a593Smuzhiyun acpi_install_table(acpi_physical_address address, u8 physical)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun acpi_status status;
246*4882a593Smuzhiyun u8 flags;
247*4882a593Smuzhiyun u32 table_index;
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(acpi_install_table);
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun if (physical) {
252*4882a593Smuzhiyun flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
253*4882a593Smuzhiyun } else {
254*4882a593Smuzhiyun flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun status = acpi_tb_install_standard_table(address, flags,
258*4882a593Smuzhiyun FALSE, FALSE, &table_index);
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun return_ACPI_STATUS(status);
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
ACPI_EXPORT_SYMBOL_INIT(acpi_install_table)263*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL_INIT(acpi_install_table)
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun /*******************************************************************************
266*4882a593Smuzhiyun *
267*4882a593Smuzhiyun * FUNCTION: acpi_load_table
268*4882a593Smuzhiyun *
269*4882a593Smuzhiyun * PARAMETERS: table - Pointer to a buffer containing the ACPI
270*4882a593Smuzhiyun * table to be loaded.
271*4882a593Smuzhiyun * table_idx - Pointer to a u32 for storing the table
272*4882a593Smuzhiyun * index, might be NULL
273*4882a593Smuzhiyun *
274*4882a593Smuzhiyun * RETURN: Status
275*4882a593Smuzhiyun *
276*4882a593Smuzhiyun * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must
277*4882a593Smuzhiyun * be a valid ACPI table with a valid ACPI table header.
278*4882a593Smuzhiyun * Note1: Mainly intended to support hotplug addition of SSDTs.
279*4882a593Smuzhiyun * Note2: Does not copy the incoming table. User is responsible
280*4882a593Smuzhiyun * to ensure that the table is not deleted or unmapped.
281*4882a593Smuzhiyun *
282*4882a593Smuzhiyun ******************************************************************************/
283*4882a593Smuzhiyun acpi_status acpi_load_table(struct acpi_table_header *table, u32 *table_idx)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun acpi_status status;
286*4882a593Smuzhiyun u32 table_index;
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(acpi_load_table);
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun /* Parameter validation */
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun if (!table) {
293*4882a593Smuzhiyun return_ACPI_STATUS(AE_BAD_PARAMETER);
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun /* Install the table and load it into the namespace */
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun ACPI_INFO(("Host-directed Dynamic ACPI Table Load:"));
299*4882a593Smuzhiyun status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table),
300*4882a593Smuzhiyun ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
301*4882a593Smuzhiyun FALSE, &table_index);
302*4882a593Smuzhiyun if (table_idx) {
303*4882a593Smuzhiyun *table_idx = table_index;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun if (ACPI_SUCCESS(status)) {
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun /* Complete the initialization/resolution of new objects */
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun acpi_ns_initialize_objects();
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun return_ACPI_STATUS(status);
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun
ACPI_EXPORT_SYMBOL(acpi_load_table)316*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_load_table)
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun /*******************************************************************************
319*4882a593Smuzhiyun *
320*4882a593Smuzhiyun * FUNCTION: acpi_unload_parent_table
321*4882a593Smuzhiyun *
322*4882a593Smuzhiyun * PARAMETERS: object - Handle to any namespace object owned by
323*4882a593Smuzhiyun * the table to be unloaded
324*4882a593Smuzhiyun *
325*4882a593Smuzhiyun * RETURN: Status
326*4882a593Smuzhiyun *
327*4882a593Smuzhiyun * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads
328*4882a593Smuzhiyun * the table and deletes all namespace objects associated with
329*4882a593Smuzhiyun * that table. Unloading of the DSDT is not allowed.
330*4882a593Smuzhiyun * Note: Mainly intended to support hotplug removal of SSDTs.
331*4882a593Smuzhiyun *
332*4882a593Smuzhiyun ******************************************************************************/
333*4882a593Smuzhiyun acpi_status acpi_unload_parent_table(acpi_handle object)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun struct acpi_namespace_node *node =
336*4882a593Smuzhiyun ACPI_CAST_PTR(struct acpi_namespace_node, object);
337*4882a593Smuzhiyun acpi_status status = AE_NOT_EXIST;
338*4882a593Smuzhiyun acpi_owner_id owner_id;
339*4882a593Smuzhiyun u32 i;
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(acpi_unload_parent_table);
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun /* Parameter validation */
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun if (!object) {
346*4882a593Smuzhiyun return_ACPI_STATUS(AE_BAD_PARAMETER);
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun /*
350*4882a593Smuzhiyun * The node owner_id is currently the same as the parent table ID.
351*4882a593Smuzhiyun * However, this could change in the future.
352*4882a593Smuzhiyun */
353*4882a593Smuzhiyun owner_id = node->owner_id;
354*4882a593Smuzhiyun if (!owner_id) {
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun /* owner_id==0 means DSDT is the owner. DSDT cannot be unloaded */
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun return_ACPI_STATUS(AE_TYPE);
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun /* Must acquire the table lock during this operation */
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
364*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
365*4882a593Smuzhiyun return_ACPI_STATUS(status);
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun /* Find the table in the global table list */
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
371*4882a593Smuzhiyun if (owner_id != acpi_gbl_root_table_list.tables[i].owner_id) {
372*4882a593Smuzhiyun continue;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun /*
376*4882a593Smuzhiyun * Allow unload of SSDT and OEMx tables only. Do not allow unload
377*4882a593Smuzhiyun * of the DSDT. No other types of tables should get here, since
378*4882a593Smuzhiyun * only these types can contain AML and thus are the only types
379*4882a593Smuzhiyun * that can create namespace objects.
380*4882a593Smuzhiyun */
381*4882a593Smuzhiyun if (ACPI_COMPARE_NAMESEG
382*4882a593Smuzhiyun (acpi_gbl_root_table_list.tables[i].signature.ascii,
383*4882a593Smuzhiyun ACPI_SIG_DSDT)) {
384*4882a593Smuzhiyun status = AE_TYPE;
385*4882a593Smuzhiyun break;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
389*4882a593Smuzhiyun status = acpi_tb_unload_table(i);
390*4882a593Smuzhiyun (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
391*4882a593Smuzhiyun break;
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
395*4882a593Smuzhiyun return_ACPI_STATUS(status);
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun
ACPI_EXPORT_SYMBOL(acpi_unload_parent_table)398*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_unload_parent_table)
399*4882a593Smuzhiyun /*******************************************************************************
400*4882a593Smuzhiyun *
401*4882a593Smuzhiyun * FUNCTION: acpi_unload_table
402*4882a593Smuzhiyun *
403*4882a593Smuzhiyun * PARAMETERS: table_index - Index as returned by acpi_load_table
404*4882a593Smuzhiyun *
405*4882a593Smuzhiyun * RETURN: Status
406*4882a593Smuzhiyun *
407*4882a593Smuzhiyun * DESCRIPTION: Via the table_index representing an SSDT or OEMx table, unloads
408*4882a593Smuzhiyun * the table and deletes all namespace objects associated with
409*4882a593Smuzhiyun * that table. Unloading of the DSDT is not allowed.
410*4882a593Smuzhiyun * Note: Mainly intended to support hotplug removal of SSDTs.
411*4882a593Smuzhiyun *
412*4882a593Smuzhiyun ******************************************************************************/
413*4882a593Smuzhiyun acpi_status acpi_unload_table(u32 table_index)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun acpi_status status;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(acpi_unload_table);
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun if (table_index == 1) {
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun /* table_index==1 means DSDT is the owner. DSDT cannot be unloaded */
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun return_ACPI_STATUS(AE_TYPE);
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun status = acpi_tb_unload_table(table_index);
427*4882a593Smuzhiyun return_ACPI_STATUS(status);
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_unload_table)
431