1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#define EXPORT_ACPI_INTERFACES
45
46#include <acpi/acpi.h>
47#include "accommon.h"
48#include "acnamesp.h"
49#include "actables.h"
50#include "acevents.h"
51
52#define _COMPONENT ACPI_TABLES
53ACPI_MODULE_NAME("tbxfload")
54
55
56
57
58
59
60
61
62
63
64
65
66acpi_status __init acpi_load_tables(void)
67{
68 acpi_status status;
69
70 ACPI_FUNCTION_TRACE(acpi_load_tables);
71
72
73
74
75
76
77
78
79
80
81
82
83
84 status = acpi_ev_install_region_handlers();
85 if (ACPI_FAILURE(status)) {
86 ACPI_EXCEPTION((AE_INFO, status,
87 "During Region initialization"));
88 return_ACPI_STATUS(status);
89 }
90
91
92
93 status = acpi_tb_load_namespace();
94
95
96
97 if (status == AE_CTRL_TERMINATE) {
98 status = AE_OK;
99 }
100
101 if (ACPI_FAILURE(status)) {
102 ACPI_EXCEPTION((AE_INFO, status,
103 "While loading namespace from ACPI tables"));
104 }
105
106 if (!acpi_gbl_group_module_level_code) {
107
108
109
110
111
112
113 status = acpi_ns_initialize_objects();
114 if (ACPI_FAILURE(status)) {
115 return_ACPI_STATUS(status);
116 }
117 }
118
119 acpi_gbl_namespace_initialized = TRUE;
120 return_ACPI_STATUS(status);
121}
122
123ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
124
125
126
127
128
129
130
131
132
133
134
135
136
137acpi_status acpi_tb_load_namespace(void)
138{
139 acpi_status status;
140 u32 i;
141 struct acpi_table_header *new_dsdt;
142 struct acpi_table_desc *table;
143 u32 tables_loaded = 0;
144 u32 tables_failed = 0;
145
146 ACPI_FUNCTION_TRACE(tb_load_namespace);
147
148 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
149
150
151
152
153
154 table = &acpi_gbl_root_table_list.tables[acpi_gbl_dsdt_index];
155
156 if (!acpi_gbl_root_table_list.current_table_count ||
157 !ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_DSDT) ||
158 ACPI_FAILURE(acpi_tb_validate_table(table))) {
159 status = AE_NO_ACPI_TABLES;
160 goto unlock_and_exit;
161 }
162
163
164
165
166
167
168
169 acpi_gbl_DSDT = table->pointer;
170
171
172
173
174
175
176
177 if (acpi_gbl_copy_dsdt_locally) {
178 new_dsdt = acpi_tb_copy_dsdt(acpi_gbl_dsdt_index);
179 if (new_dsdt) {
180 acpi_gbl_DSDT = new_dsdt;
181 }
182 }
183
184
185
186
187
188 memcpy(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT,
189 sizeof(struct acpi_table_header));
190
191 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
192
193
194
195 status = acpi_ns_load_table(acpi_gbl_dsdt_index, acpi_gbl_root_node);
196 if (ACPI_FAILURE(status)) {
197 ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed"));
198 tables_failed++;
199 } else {
200 tables_loaded++;
201 }
202
203
204
205 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
206 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
207 table = &acpi_gbl_root_table_list.tables[i];
208
209 if (!acpi_gbl_root_table_list.tables[i].address ||
210 (!ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_SSDT)
211 && !ACPI_COMPARE_NAME(table->signature.ascii,
212 ACPI_SIG_PSDT)
213 && !ACPI_COMPARE_NAME(table->signature.ascii,
214 ACPI_SIG_OSDT))
215 || ACPI_FAILURE(acpi_tb_validate_table(table))) {
216 continue;
217 }
218
219
220
221 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
222 status = acpi_ns_load_table(i, acpi_gbl_root_node);
223 if (ACPI_FAILURE(status)) {
224 ACPI_EXCEPTION((AE_INFO, status,
225 "(%4.4s:%8.8s) while loading table",
226 table->signature.ascii,
227 table->pointer->oem_table_id));
228
229 tables_failed++;
230
231 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
232 "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n",
233 table->signature.ascii,
234 table->pointer->oem_table_id));
235 } else {
236 tables_loaded++;
237 }
238
239 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
240 }
241
242 if (!tables_failed) {
243 ACPI_INFO(("%u ACPI AML tables successfully acquired and loaded\n", tables_loaded));
244 } else {
245 ACPI_ERROR((AE_INFO,
246 "%u table load failures, %u successful",
247 tables_failed, tables_loaded));
248
249
250
251 status = AE_CTRL_TERMINATE;
252 }
253
254unlock_and_exit:
255 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
256 return_ACPI_STATUS(status);
257}
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275acpi_status __init
276acpi_install_table(acpi_physical_address address, u8 physical)
277{
278 acpi_status status;
279 u8 flags;
280 u32 table_index;
281
282 ACPI_FUNCTION_TRACE(acpi_install_table);
283
284 if (physical) {
285 flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
286 } else {
287 flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
288 }
289
290 status = acpi_tb_install_standard_table(address, flags,
291 FALSE, FALSE, &table_index);
292
293 return_ACPI_STATUS(status);
294}
295
296ACPI_EXPORT_SYMBOL_INIT(acpi_install_table)
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314acpi_status acpi_load_table(struct acpi_table_header *table)
315{
316 acpi_status status;
317 u32 table_index;
318
319 ACPI_FUNCTION_TRACE(acpi_load_table);
320
321
322
323 if (!table) {
324 return_ACPI_STATUS(AE_BAD_PARAMETER);
325 }
326
327
328
329 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
330 if (ACPI_FAILURE(status)) {
331 return_ACPI_STATUS(status);
332 }
333
334
335
336 ACPI_INFO(("Host-directed Dynamic ACPI Table Load:"));
337 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
338
339 status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
340 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
341 TRUE, FALSE, &table_index);
342
343 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
344 if (ACPI_FAILURE(status)) {
345 goto unlock_and_exit;
346 }
347
348
349
350
351
352 status =
353 acpi_tb_validate_table(&acpi_gbl_root_table_list.
354 tables[table_index]);
355 if (ACPI_FAILURE(status)) {
356 goto unlock_and_exit;
357 }
358
359 status = acpi_ns_load_table(table_index, acpi_gbl_root_node);
360
361
362
363 if (acpi_gbl_table_handler) {
364 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
365 acpi_gbl_table_handler_context);
366 }
367
368unlock_and_exit:
369 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
370 return_ACPI_STATUS(status);
371}
372
373ACPI_EXPORT_SYMBOL(acpi_load_table)
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390acpi_status acpi_unload_parent_table(acpi_handle object)
391{
392 struct acpi_namespace_node *node =
393 ACPI_CAST_PTR(struct acpi_namespace_node, object);
394 acpi_status status = AE_NOT_EXIST;
395 acpi_owner_id owner_id;
396 u32 i;
397
398 ACPI_FUNCTION_TRACE(acpi_unload_parent_table);
399
400
401
402 if (!object) {
403 return_ACPI_STATUS(AE_BAD_PARAMETER);
404 }
405
406
407
408
409
410 owner_id = node->owner_id;
411 if (!owner_id) {
412
413
414
415 return_ACPI_STATUS(AE_TYPE);
416 }
417
418
419
420 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
421 if (ACPI_FAILURE(status)) {
422 return_ACPI_STATUS(status);
423 }
424
425
426
427 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
428 if (owner_id != acpi_gbl_root_table_list.tables[i].owner_id) {
429 continue;
430 }
431
432
433
434
435
436
437
438 if (ACPI_COMPARE_NAME
439 (acpi_gbl_root_table_list.tables[i].signature.ascii,
440 ACPI_SIG_DSDT)) {
441 status = AE_TYPE;
442 break;
443 }
444
445
446
447 if (!acpi_tb_is_table_loaded(i)) {
448 status = AE_NOT_EXIST;
449 break;
450 }
451
452
453
454 if (acpi_gbl_table_handler) {
455 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
456 acpi_gbl_root_table_list.
457 tables[i].pointer,
458 acpi_gbl_table_handler_context);
459 }
460
461
462
463
464
465
466
467 status = acpi_tb_delete_namespace_by_owner(i);
468 if (ACPI_FAILURE(status)) {
469 break;
470 }
471
472 status = acpi_tb_release_owner_id(i);
473 acpi_tb_set_table_loaded_flag(i, FALSE);
474 break;
475 }
476
477 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
478 return_ACPI_STATUS(status);
479}
480
481ACPI_EXPORT_SYMBOL(acpi_unload_parent_table)
482