0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define EXPORT_ACPI_INTERFACES
0011
0012 #include <acpi/acpi.h>
0013 #include "accommon.h"
0014 #include "acnamesp.h"
0015 #include "actables.h"
0016 #include "acevents.h"
0017
0018 #define _COMPONENT ACPI_TABLES
0019 ACPI_MODULE_NAME("tbxfload")
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 acpi_status ACPI_INIT_FUNCTION acpi_load_tables(void)
0033 {
0034 acpi_status status;
0035
0036 ACPI_FUNCTION_TRACE(acpi_load_tables);
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 status = acpi_ev_install_region_handlers();
0051 if (ACPI_FAILURE(status)) {
0052 ACPI_EXCEPTION((AE_INFO, status,
0053 "During Region initialization"));
0054 return_ACPI_STATUS(status);
0055 }
0056
0057
0058
0059 status = acpi_tb_load_namespace();
0060
0061
0062
0063 if (status == AE_CTRL_TERMINATE) {
0064 status = AE_OK;
0065 }
0066
0067 if (ACPI_FAILURE(status)) {
0068 ACPI_EXCEPTION((AE_INFO, status,
0069 "While loading namespace from ACPI tables"));
0070 }
0071
0072
0073
0074
0075
0076
0077
0078
0079 status = acpi_ns_initialize_objects();
0080 if (ACPI_SUCCESS(status)) {
0081 acpi_gbl_namespace_initialized = TRUE;
0082 }
0083
0084 return_ACPI_STATUS(status);
0085 }
0086
0087 ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables)
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 acpi_status acpi_tb_load_namespace(void)
0102 {
0103 acpi_status status;
0104 u32 i;
0105 struct acpi_table_header *new_dsdt;
0106 struct acpi_table_desc *table;
0107 u32 tables_loaded = 0;
0108 u32 tables_failed = 0;
0109
0110 ACPI_FUNCTION_TRACE(tb_load_namespace);
0111
0112 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0113
0114
0115
0116
0117
0118 table = &acpi_gbl_root_table_list.tables[acpi_gbl_dsdt_index];
0119
0120 if (!acpi_gbl_root_table_list.current_table_count ||
0121 !ACPI_COMPARE_NAMESEG(table->signature.ascii, ACPI_SIG_DSDT) ||
0122 ACPI_FAILURE(acpi_tb_validate_table(table))) {
0123 status = AE_NO_ACPI_TABLES;
0124 goto unlock_and_exit;
0125 }
0126
0127
0128
0129
0130
0131
0132
0133 acpi_gbl_DSDT = table->pointer;
0134
0135
0136
0137
0138
0139
0140
0141 if (acpi_gbl_copy_dsdt_locally) {
0142 new_dsdt = acpi_tb_copy_dsdt(acpi_gbl_dsdt_index);
0143 if (new_dsdt) {
0144 acpi_gbl_DSDT = new_dsdt;
0145 }
0146 }
0147
0148
0149
0150
0151
0152 memcpy(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT,
0153 sizeof(struct acpi_table_header));
0154
0155
0156
0157 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0158 status = acpi_ns_load_table(acpi_gbl_dsdt_index, acpi_gbl_root_node);
0159 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0160 if (ACPI_FAILURE(status)) {
0161 ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed"));
0162 tables_failed++;
0163 } else {
0164 tables_loaded++;
0165 }
0166
0167
0168
0169 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
0170 table = &acpi_gbl_root_table_list.tables[i];
0171
0172 if (!table->address ||
0173 (!ACPI_COMPARE_NAMESEG
0174 (table->signature.ascii, ACPI_SIG_SSDT)
0175 && !ACPI_COMPARE_NAMESEG(table->signature.ascii,
0176 ACPI_SIG_PSDT)
0177 && !ACPI_COMPARE_NAMESEG(table->signature.ascii,
0178 ACPI_SIG_OSDT))
0179 || ACPI_FAILURE(acpi_tb_validate_table(table))) {
0180 continue;
0181 }
0182
0183
0184
0185 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0186 status = acpi_ns_load_table(i, acpi_gbl_root_node);
0187 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0188 if (ACPI_FAILURE(status)) {
0189 ACPI_EXCEPTION((AE_INFO, status,
0190 "(%4.4s:%8.8s) while loading table",
0191 table->signature.ascii,
0192 table->pointer->oem_table_id));
0193
0194 tables_failed++;
0195
0196 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
0197 "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n",
0198 table->signature.ascii,
0199 table->pointer->oem_table_id));
0200 } else {
0201 tables_loaded++;
0202 }
0203 }
0204
0205 if (!tables_failed) {
0206 ACPI_INFO(("%u ACPI AML tables successfully acquired and loaded", tables_loaded));
0207 } else {
0208 ACPI_ERROR((AE_INFO,
0209 "%u table load failures, %u successful",
0210 tables_failed, tables_loaded));
0211
0212
0213
0214 status = AE_CTRL_TERMINATE;
0215 }
0216
0217 #ifdef ACPI_APPLICATION
0218 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "\n"));
0219 #endif
0220
0221 unlock_and_exit:
0222 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0223 return_ACPI_STATUS(status);
0224 }
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 acpi_status ACPI_INIT_FUNCTION
0241 acpi_install_table(struct acpi_table_header *table)
0242 {
0243 acpi_status status;
0244 u32 table_index;
0245
0246 ACPI_FUNCTION_TRACE(acpi_install_table);
0247
0248 status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
0249 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
0250 table, FALSE, FALSE,
0251 &table_index);
0252
0253 return_ACPI_STATUS(status);
0254 }
0255
0256 ACPI_EXPORT_SYMBOL_INIT(acpi_install_table)
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 acpi_status ACPI_INIT_FUNCTION
0272 acpi_install_physical_table(acpi_physical_address address)
0273 {
0274 acpi_status status;
0275 u32 table_index;
0276
0277 ACPI_FUNCTION_TRACE(acpi_install_physical_table);
0278
0279 status = acpi_tb_install_standard_table(address,
0280 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
0281 NULL, FALSE, FALSE,
0282 &table_index);
0283
0284 return_ACPI_STATUS(status);
0285 }
0286
0287 ACPI_EXPORT_SYMBOL_INIT(acpi_install_physical_table)
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307 acpi_status acpi_load_table(struct acpi_table_header *table, u32 *table_idx)
0308 {
0309 acpi_status status;
0310 u32 table_index;
0311
0312 ACPI_FUNCTION_TRACE(acpi_load_table);
0313
0314
0315
0316 if (!table) {
0317 return_ACPI_STATUS(AE_BAD_PARAMETER);
0318 }
0319
0320
0321
0322 ACPI_INFO(("Host-directed Dynamic ACPI Table Load:"));
0323 status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table),
0324 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
0325 table, FALSE, &table_index);
0326 if (table_idx) {
0327 *table_idx = table_index;
0328 }
0329
0330 if (ACPI_SUCCESS(status)) {
0331
0332
0333
0334 acpi_ns_initialize_objects();
0335 }
0336
0337 return_ACPI_STATUS(status);
0338 }
0339
0340 ACPI_EXPORT_SYMBOL(acpi_load_table)
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 acpi_status acpi_unload_parent_table(acpi_handle object)
0358 {
0359 struct acpi_namespace_node *node =
0360 ACPI_CAST_PTR(struct acpi_namespace_node, object);
0361 acpi_status status = AE_NOT_EXIST;
0362 acpi_owner_id owner_id;
0363 u32 i;
0364
0365 ACPI_FUNCTION_TRACE(acpi_unload_parent_table);
0366
0367
0368
0369 if (!object) {
0370 return_ACPI_STATUS(AE_BAD_PARAMETER);
0371 }
0372
0373
0374
0375
0376
0377 owner_id = node->owner_id;
0378 if (!owner_id) {
0379
0380
0381
0382 return_ACPI_STATUS(AE_TYPE);
0383 }
0384
0385
0386
0387 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0388 if (ACPI_FAILURE(status)) {
0389 return_ACPI_STATUS(status);
0390 }
0391
0392
0393
0394 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
0395 if (owner_id != acpi_gbl_root_table_list.tables[i].owner_id) {
0396 continue;
0397 }
0398
0399
0400
0401
0402
0403
0404
0405 if (ACPI_COMPARE_NAMESEG
0406 (acpi_gbl_root_table_list.tables[i].signature.ascii,
0407 ACPI_SIG_DSDT)) {
0408 status = AE_TYPE;
0409 break;
0410 }
0411
0412 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0413 status = acpi_tb_unload_table(i);
0414 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0415 break;
0416 }
0417
0418 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0419 return_ACPI_STATUS(status);
0420 }
0421
0422 ACPI_EXPORT_SYMBOL(acpi_unload_parent_table)
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437 acpi_status acpi_unload_table(u32 table_index)
0438 {
0439 acpi_status status;
0440
0441 ACPI_FUNCTION_TRACE(acpi_unload_table);
0442
0443 if (table_index == 1) {
0444
0445
0446
0447 return_ACPI_STATUS(AE_TYPE);
0448 }
0449
0450 status = acpi_tb_unload_table(table_index);
0451 return_ACPI_STATUS(status);
0452 }
0453
0454 ACPI_EXPORT_SYMBOL(acpi_unload_table)