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
51#define _COMPONENT ACPI_TABLES
52ACPI_MODULE_NAME("tbxfload")
53
54
55static acpi_status acpi_tb_load_namespace(void);
56
57
58
59
60
61
62
63
64
65
66
67
68
69acpi_status acpi_load_tables(void)
70{
71 acpi_status status;
72
73 ACPI_FUNCTION_TRACE(acpi_load_tables);
74
75
76
77 status = acpi_tb_load_namespace();
78 if (ACPI_FAILURE(status)) {
79 ACPI_EXCEPTION((AE_INFO, status,
80 "While loading namespace from ACPI tables"));
81 }
82
83 return_ACPI_STATUS(status);
84}
85
86ACPI_EXPORT_SYMBOL(acpi_load_tables)
87
88
89
90
91
92
93
94
95
96
97
98
99
100static acpi_status acpi_tb_load_namespace(void)
101{
102 acpi_status status;
103 u32 i;
104 struct acpi_table_header *new_dsdt;
105
106 ACPI_FUNCTION_TRACE(tb_load_namespace);
107
108 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
109
110
111
112
113
114 if (!acpi_gbl_root_table_list.current_table_count ||
115 !ACPI_COMPARE_NAME(&
116 (acpi_gbl_root_table_list.
117 tables[ACPI_TABLE_INDEX_DSDT].signature),
118 ACPI_SIG_DSDT)
119 ||
120 ACPI_FAILURE(acpi_tb_validate_table
121 (&acpi_gbl_root_table_list.
122 tables[ACPI_TABLE_INDEX_DSDT]))) {
123 status = AE_NO_ACPI_TABLES;
124 goto unlock_and_exit;
125 }
126
127
128
129
130
131
132
133 acpi_gbl_DSDT =
134 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer;
135
136
137
138
139
140
141
142 if (acpi_gbl_copy_dsdt_locally) {
143 new_dsdt = acpi_tb_copy_dsdt(ACPI_TABLE_INDEX_DSDT);
144 if (new_dsdt) {
145 acpi_gbl_DSDT = new_dsdt;
146 }
147 }
148
149
150
151
152
153 memcpy(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT,
154 sizeof(struct acpi_table_header));
155
156 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
157
158
159
160 status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
161 if (ACPI_FAILURE(status)) {
162 return_ACPI_STATUS(status);
163 }
164
165
166
167 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
168 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
169 if ((!ACPI_COMPARE_NAME
170 (&(acpi_gbl_root_table_list.tables[i].signature),
171 ACPI_SIG_SSDT)
172 &&
173 !ACPI_COMPARE_NAME(&
174 (acpi_gbl_root_table_list.tables[i].
175 signature), ACPI_SIG_PSDT))
176 ||
177 ACPI_FAILURE(acpi_tb_validate_table
178 (&acpi_gbl_root_table_list.tables[i]))) {
179 continue;
180 }
181
182
183
184 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
185 (void)acpi_ns_load_table(i, acpi_gbl_root_node);
186 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
187 }
188
189 ACPI_INFO((AE_INFO, "All ACPI Tables successfully acquired"));
190
191 unlock_and_exit:
192 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
193 return_ACPI_STATUS(status);
194}
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212acpi_status __init
213acpi_install_table(acpi_physical_address address, u8 physical)
214{
215 acpi_status status;
216 u8 flags;
217 u32 table_index;
218
219 ACPI_FUNCTION_TRACE(acpi_install_table);
220
221 if (physical) {
222 flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
223 } else {
224 flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
225 }
226
227 status = acpi_tb_install_standard_table(address, flags,
228 FALSE, FALSE, &table_index);
229
230 return_ACPI_STATUS(status);
231}
232
233ACPI_EXPORT_SYMBOL(acpi_install_table)
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251acpi_status acpi_load_table(struct acpi_table_header *table)
252{
253 acpi_status status;
254 u32 table_index;
255
256 ACPI_FUNCTION_TRACE(acpi_load_table);
257
258
259
260 if (!table) {
261 return_ACPI_STATUS(AE_BAD_PARAMETER);
262 }
263
264
265
266 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
267 if (ACPI_FAILURE(status)) {
268 return_ACPI_STATUS(status);
269 }
270
271
272
273 ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
274 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
275
276 status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
277 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
278 TRUE, FALSE, &table_index);
279
280 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
281 if (ACPI_FAILURE(status)) {
282 goto unlock_and_exit;
283 }
284
285
286
287
288
289 status =
290 acpi_tb_validate_table(&acpi_gbl_root_table_list.
291 tables[table_index]);
292 if (ACPI_FAILURE(status)) {
293 goto unlock_and_exit;
294 }
295
296 status = acpi_ns_load_table(table_index, acpi_gbl_root_node);
297
298
299
300 if (acpi_gbl_table_handler) {
301 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
302 acpi_gbl_table_handler_context);
303 }
304
305 unlock_and_exit:
306 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
307 return_ACPI_STATUS(status);
308}
309
310ACPI_EXPORT_SYMBOL(acpi_load_table)
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327acpi_status acpi_unload_parent_table(acpi_handle object)
328{
329 struct acpi_namespace_node *node =
330 ACPI_CAST_PTR(struct acpi_namespace_node, object);
331 acpi_status status = AE_NOT_EXIST;
332 acpi_owner_id owner_id;
333 u32 i;
334
335 ACPI_FUNCTION_TRACE(acpi_unload_parent_table);
336
337
338
339 if (!object) {
340 return_ACPI_STATUS(AE_BAD_PARAMETER);
341 }
342
343
344
345
346
347 owner_id = node->owner_id;
348 if (!owner_id) {
349
350
351
352 return_ACPI_STATUS(AE_TYPE);
353 }
354
355
356
357 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
358 if (ACPI_FAILURE(status)) {
359 return_ACPI_STATUS(status);
360 }
361
362
363
364 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
365 if (owner_id != acpi_gbl_root_table_list.tables[i].owner_id) {
366 continue;
367 }
368
369
370
371
372
373
374
375 if (ACPI_COMPARE_NAME
376 (acpi_gbl_root_table_list.tables[i].signature.ascii,
377 ACPI_SIG_DSDT)) {
378 status = AE_TYPE;
379 break;
380 }
381
382
383
384 if (!acpi_tb_is_table_loaded(i)) {
385 status = AE_NOT_EXIST;
386 break;
387 }
388
389
390
391 if (acpi_gbl_table_handler) {
392 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
393 acpi_gbl_root_table_list.
394 tables[i].pointer,
395 acpi_gbl_table_handler_context);
396 }
397
398
399
400
401
402
403
404 status = acpi_tb_delete_namespace_by_owner(i);
405 if (ACPI_FAILURE(status)) {
406 break;
407 }
408
409 status = acpi_tb_release_owner_id(i);
410 acpi_tb_set_table_loaded_flag(i, FALSE);
411 break;
412 }
413
414 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
415 return_ACPI_STATUS(status);
416}
417
418ACPI_EXPORT_SYMBOL(acpi_unload_parent_table)
419