0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acnamesp.h"
0013 #include "actables.h"
0014 #include "acevents.h"
0015
0016 #define _COMPONENT ACPI_TABLES
0017 ACPI_MODULE_NAME("tbdata")
0018
0019
0020 static acpi_status
0021 acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index);
0022
0023 static u8
0024 acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 static u8
0041 acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
0042 {
0043 acpi_status status = AE_OK;
0044 u8 is_identical;
0045 struct acpi_table_header *table;
0046 u32 table_length;
0047 u8 table_flags;
0048
0049 status =
0050 acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
0051 &table, &table_length, &table_flags);
0052 if (ACPI_FAILURE(status)) {
0053 return (FALSE);
0054 }
0055
0056
0057
0058
0059
0060 is_identical = (u8)((table_desc->length != table_length ||
0061 memcmp(table_desc->pointer, table, table_length)) ?
0062 FALSE : TRUE);
0063
0064
0065
0066 acpi_tb_release_table(table, table_length, table_flags);
0067 return (is_identical);
0068 }
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 void
0086 acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
0087 acpi_physical_address address,
0088 u8 flags, struct acpi_table_header *table)
0089 {
0090
0091
0092
0093
0094
0095 memset(table_desc, 0, sizeof(struct acpi_table_desc));
0096 table_desc->address = address;
0097 table_desc->length = table->length;
0098 table_desc->flags = flags;
0099 ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
0100
0101 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
0102 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0103 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0104
0105 table_desc->pointer = table;
0106 break;
0107
0108 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0109 default:
0110
0111 break;
0112 }
0113 }
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 acpi_status
0132 acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
0133 struct acpi_table_header **table_ptr,
0134 u32 *table_length, u8 *table_flags)
0135 {
0136 struct acpi_table_header *table = NULL;
0137
0138 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
0139 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0140
0141 table =
0142 acpi_os_map_memory(table_desc->address, table_desc->length);
0143 break;
0144
0145 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0146 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0147
0148 table = table_desc->pointer;
0149 break;
0150
0151 default:
0152
0153 break;
0154 }
0155
0156
0157
0158 if (!table) {
0159 return (AE_NO_MEMORY);
0160 }
0161
0162
0163
0164 *table_ptr = table;
0165 *table_length = table_desc->length;
0166 *table_flags = table_desc->flags;
0167 return (AE_OK);
0168 }
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184 void
0185 acpi_tb_release_table(struct acpi_table_header *table,
0186 u32 table_length, u8 table_flags)
0187 {
0188
0189 switch (table_flags & ACPI_TABLE_ORIGIN_MASK) {
0190 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0191
0192 acpi_os_unmap_memory(table, table_length);
0193 break;
0194
0195 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0196 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0197 default:
0198
0199 break;
0200 }
0201 }
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 acpi_status
0223 acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc,
0224 acpi_physical_address address,
0225 u8 flags, struct acpi_table_header *table)
0226 {
0227 u8 mapped_table = FALSE;
0228
0229 switch (flags & ACPI_TABLE_ORIGIN_MASK) {
0230 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0231
0232
0233
0234 if (!table) {
0235 table =
0236 acpi_os_map_memory(address,
0237 sizeof(struct
0238 acpi_table_header));
0239 if (!table) {
0240 return (AE_NO_MEMORY);
0241 }
0242
0243 mapped_table = TRUE;
0244 }
0245
0246 break;
0247
0248 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0249 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0250
0251 if (!table) {
0252 return (AE_BAD_PARAMETER);
0253 }
0254
0255 break;
0256
0257 default:
0258
0259
0260
0261 return (AE_NO_MEMORY);
0262 }
0263
0264 acpi_tb_init_table_descriptor(table_desc, address, flags, table);
0265 if (mapped_table) {
0266 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
0267 }
0268
0269 return (AE_OK);
0270 }
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc)
0285 {
0286
0287
0288
0289
0290
0291
0292 acpi_tb_invalidate_table(table_desc);
0293 }
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc)
0309 {
0310 acpi_status status = AE_OK;
0311
0312 ACPI_FUNCTION_TRACE(tb_validate_table);
0313
0314
0315
0316 if (!table_desc->pointer) {
0317 status = acpi_tb_acquire_table(table_desc, &table_desc->pointer,
0318 &table_desc->length,
0319 &table_desc->flags);
0320 if (!table_desc->pointer) {
0321 status = AE_NO_MEMORY;
0322 }
0323 }
0324
0325 return_ACPI_STATUS(status);
0326 }
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341 void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
0342 {
0343
0344 ACPI_FUNCTION_TRACE(tb_invalidate_table);
0345
0346
0347
0348 if (!table_desc->pointer) {
0349 return_VOID;
0350 }
0351
0352 acpi_tb_release_table(table_desc->pointer, table_desc->length,
0353 table_desc->flags);
0354
0355 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
0356 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0357
0358 table_desc->pointer = NULL;
0359 break;
0360
0361 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0362 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0363 default:
0364
0365 break;
0366 }
0367
0368 return_VOID;
0369 }
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384 acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
0385 {
0386
0387 if (!table_desc->pointer && !acpi_gbl_enable_table_validation) {
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397 table_desc->length = sizeof(struct acpi_table_header);
0398 }
0399
0400 return (acpi_tb_validate_table(table_desc));
0401 }
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419 static acpi_status
0420 acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
0421 {
0422 u32 i;
0423
0424 ACPI_FUNCTION_TRACE(tb_check_duplication);
0425
0426
0427
0428 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
0429
0430
0431
0432 if (!
0433 (acpi_gbl_root_table_list.tables[i].
0434 flags & ACPI_TABLE_IS_VERIFIED)) {
0435 continue;
0436 }
0437
0438
0439
0440
0441
0442 if (!acpi_tb_compare_tables(table_desc, i)) {
0443 continue;
0444 }
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460 if (acpi_gbl_root_table_list.tables[i].flags &
0461 ACPI_TABLE_IS_LOADED) {
0462
0463
0464
0465 return_ACPI_STATUS(AE_ALREADY_EXISTS);
0466 } else {
0467 *table_index = i;
0468 return_ACPI_STATUS(AE_CTRL_TERMINATE);
0469 }
0470 }
0471
0472
0473
0474 return_ACPI_STATUS(AE_OK);
0475 }
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494 acpi_status
0495 acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
0496 char *signature, u32 *table_index)
0497 {
0498 acpi_status status = AE_OK;
0499
0500 ACPI_FUNCTION_TRACE(tb_verify_temp_table);
0501
0502
0503
0504 status = acpi_tb_validate_temp_table(table_desc);
0505 if (ACPI_FAILURE(status)) {
0506 return_ACPI_STATUS(AE_NO_MEMORY);
0507 }
0508
0509
0510
0511 if (signature &&
0512 !ACPI_COMPARE_NAMESEG(&table_desc->signature, signature)) {
0513 ACPI_BIOS_ERROR((AE_INFO,
0514 "Invalid signature 0x%X for ACPI table, expected [%s]",
0515 table_desc->signature.integer, signature));
0516 status = AE_BAD_SIGNATURE;
0517 goto invalidate_and_exit;
0518 }
0519
0520 if (acpi_gbl_enable_table_validation) {
0521
0522
0523
0524 status =
0525 acpi_tb_verify_checksum(table_desc->pointer,
0526 table_desc->length);
0527 if (ACPI_FAILURE(status)) {
0528 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
0529 "%4.4s 0x%8.8X%8.8X"
0530 " Attempted table install failed",
0531 acpi_ut_valid_nameseg(table_desc->
0532 signature.
0533 ascii) ?
0534 table_desc->signature.ascii : "????",
0535 ACPI_FORMAT_UINT64(table_desc->
0536 address)));
0537
0538 goto invalidate_and_exit;
0539 }
0540
0541
0542
0543 if (table_index) {
0544 status =
0545 acpi_tb_check_duplication(table_desc, table_index);
0546 if (ACPI_FAILURE(status)) {
0547 if (status != AE_CTRL_TERMINATE) {
0548 ACPI_EXCEPTION((AE_INFO, status,
0549 "%4.4s 0x%8.8X%8.8X"
0550 " Table is already loaded",
0551 acpi_ut_valid_nameseg
0552 (table_desc->signature.
0553 ascii) ? table_desc->
0554 signature.
0555 ascii : "????",
0556 ACPI_FORMAT_UINT64
0557 (table_desc->address)));
0558 }
0559
0560 goto invalidate_and_exit;
0561 }
0562 }
0563
0564 table_desc->flags |= ACPI_TABLE_IS_VERIFIED;
0565 }
0566
0567 return_ACPI_STATUS(status);
0568
0569 invalidate_and_exit:
0570 acpi_tb_invalidate_table(table_desc);
0571 return_ACPI_STATUS(status);
0572 }
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586 acpi_status acpi_tb_resize_root_table_list(void)
0587 {
0588 struct acpi_table_desc *tables;
0589 u32 table_count;
0590 u32 current_table_count, max_table_count;
0591 u32 i;
0592
0593 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
0594
0595
0596
0597 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
0598 ACPI_ERROR((AE_INFO,
0599 "Resize of Root Table Array is not allowed"));
0600 return_ACPI_STATUS(AE_SUPPORT);
0601 }
0602
0603
0604
0605 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
0606 table_count = acpi_gbl_root_table_list.max_table_count;
0607 } else {
0608 table_count = acpi_gbl_root_table_list.current_table_count;
0609 }
0610
0611 max_table_count = table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
0612 tables = ACPI_ALLOCATE_ZEROED(((acpi_size)max_table_count) *
0613 sizeof(struct acpi_table_desc));
0614 if (!tables) {
0615 ACPI_ERROR((AE_INFO,
0616 "Could not allocate new root table array"));
0617 return_ACPI_STATUS(AE_NO_MEMORY);
0618 }
0619
0620
0621
0622 current_table_count = 0;
0623 if (acpi_gbl_root_table_list.tables) {
0624 for (i = 0; i < table_count; i++) {
0625 if (acpi_gbl_root_table_list.tables[i].address) {
0626 memcpy(tables + current_table_count,
0627 acpi_gbl_root_table_list.tables + i,
0628 sizeof(struct acpi_table_desc));
0629 current_table_count++;
0630 }
0631 }
0632
0633 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
0634 ACPI_FREE(acpi_gbl_root_table_list.tables);
0635 }
0636 }
0637
0638 acpi_gbl_root_table_list.tables = tables;
0639 acpi_gbl_root_table_list.max_table_count = max_table_count;
0640 acpi_gbl_root_table_list.current_table_count = current_table_count;
0641 acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
0642
0643 return_ACPI_STATUS(AE_OK);
0644 }
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659 acpi_status
0660 acpi_tb_get_next_table_descriptor(u32 *table_index,
0661 struct acpi_table_desc **table_desc)
0662 {
0663 acpi_status status;
0664 u32 i;
0665
0666
0667
0668 if (acpi_gbl_root_table_list.current_table_count >=
0669 acpi_gbl_root_table_list.max_table_count) {
0670 status = acpi_tb_resize_root_table_list();
0671 if (ACPI_FAILURE(status)) {
0672 return (status);
0673 }
0674 }
0675
0676 i = acpi_gbl_root_table_list.current_table_count;
0677 acpi_gbl_root_table_list.current_table_count++;
0678
0679 if (table_index) {
0680 *table_index = i;
0681 }
0682 if (table_desc) {
0683 *table_desc = &acpi_gbl_root_table_list.tables[i];
0684 }
0685
0686 return (AE_OK);
0687 }
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701 void acpi_tb_terminate(void)
0702 {
0703 u32 i;
0704
0705 ACPI_FUNCTION_TRACE(tb_terminate);
0706
0707 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0708
0709
0710
0711 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
0712 acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]);
0713 }
0714
0715
0716
0717
0718
0719 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
0720 ACPI_FREE(acpi_gbl_root_table_list.tables);
0721 }
0722
0723 acpi_gbl_root_table_list.tables = NULL;
0724 acpi_gbl_root_table_list.flags = 0;
0725 acpi_gbl_root_table_list.current_table_count = 0;
0726
0727 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
0728
0729 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0730 return_VOID;
0731 }
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745 acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
0746 {
0747 acpi_owner_id owner_id;
0748 acpi_status status;
0749
0750 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
0751
0752 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0753 if (ACPI_FAILURE(status)) {
0754 return_ACPI_STATUS(status);
0755 }
0756
0757 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
0758
0759
0760
0761 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0762 return_ACPI_STATUS(AE_NOT_EXIST);
0763 }
0764
0765
0766
0767 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
0768 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0769
0770
0771
0772
0773
0774
0775
0776
0777 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
0778 if (ACPI_FAILURE(status)) {
0779 return_ACPI_STATUS(status);
0780 }
0781
0782 acpi_ns_delete_namespace_by_owner(owner_id);
0783 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
0784 return_ACPI_STATUS(status);
0785 }
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798
0799 acpi_status acpi_tb_allocate_owner_id(u32 table_index)
0800 {
0801 acpi_status status = AE_BAD_PARAMETER;
0802
0803 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
0804
0805 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0806 if (table_index < acpi_gbl_root_table_list.current_table_count) {
0807 status =
0808 acpi_ut_allocate_owner_id(&
0809 (acpi_gbl_root_table_list.
0810 tables[table_index].owner_id));
0811 }
0812
0813 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0814 return_ACPI_STATUS(status);
0815 }
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829 acpi_status acpi_tb_release_owner_id(u32 table_index)
0830 {
0831 acpi_status status = AE_BAD_PARAMETER;
0832
0833 ACPI_FUNCTION_TRACE(tb_release_owner_id);
0834
0835 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0836 if (table_index < acpi_gbl_root_table_list.current_table_count) {
0837 acpi_ut_release_owner_id(&
0838 (acpi_gbl_root_table_list.
0839 tables[table_index].owner_id));
0840 status = AE_OK;
0841 }
0842
0843 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0844 return_ACPI_STATUS(status);
0845 }
0846
0847
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860 acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
0861 {
0862 acpi_status status = AE_BAD_PARAMETER;
0863
0864 ACPI_FUNCTION_TRACE(tb_get_owner_id);
0865
0866 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0867 if (table_index < acpi_gbl_root_table_list.current_table_count) {
0868 *owner_id =
0869 acpi_gbl_root_table_list.tables[table_index].owner_id;
0870 status = AE_OK;
0871 }
0872
0873 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0874 return_ACPI_STATUS(status);
0875 }
0876
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887 u8 acpi_tb_is_table_loaded(u32 table_index)
0888 {
0889 u8 is_loaded = FALSE;
0890
0891 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0892 if (table_index < acpi_gbl_root_table_list.current_table_count) {
0893 is_loaded = (u8)
0894 (acpi_gbl_root_table_list.tables[table_index].flags &
0895 ACPI_TABLE_IS_LOADED);
0896 }
0897
0898 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0899 return (is_loaded);
0900 }
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915 void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
0916 {
0917
0918 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0919 if (table_index < acpi_gbl_root_table_list.current_table_count) {
0920 if (is_loaded) {
0921 acpi_gbl_root_table_list.tables[table_index].flags |=
0922 ACPI_TABLE_IS_LOADED;
0923 } else {
0924 acpi_gbl_root_table_list.tables[table_index].flags &=
0925 ~ACPI_TABLE_IS_LOADED;
0926 }
0927 }
0928
0929 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0930 }
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943
0944
0945 acpi_status
0946 acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
0947 {
0948 struct acpi_table_header *table;
0949 acpi_status status;
0950 acpi_owner_id owner_id;
0951
0952 ACPI_FUNCTION_TRACE(tb_load_table);
0953
0954
0955
0956
0957
0958 status = acpi_get_table_by_index(table_index, &table);
0959 if (ACPI_FAILURE(status)) {
0960 return_ACPI_STATUS(status);
0961 }
0962
0963 status = acpi_ns_load_table(table_index, parent_node);
0964 if (ACPI_FAILURE(status)) {
0965 return_ACPI_STATUS(status);
0966 }
0967
0968
0969
0970
0971
0972
0973 status = acpi_tb_get_owner_id(table_index, &owner_id);
0974 if (ACPI_SUCCESS(status)) {
0975 acpi_ev_update_gpes(owner_id);
0976 }
0977
0978
0979
0980 acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table);
0981 return_ACPI_STATUS(status);
0982 }
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002 acpi_status
1003 acpi_tb_install_and_load_table(acpi_physical_address address,
1004 u8 flags,
1005 struct acpi_table_header *table,
1006 u8 override, u32 *table_index)
1007 {
1008 acpi_status status;
1009 u32 i;
1010
1011 ACPI_FUNCTION_TRACE(tb_install_and_load_table);
1012
1013
1014
1015 status = acpi_tb_install_standard_table(address, flags, table, TRUE,
1016 override, &i);
1017 if (ACPI_FAILURE(status)) {
1018 goto exit;
1019 }
1020
1021 status = acpi_tb_load_table(i, acpi_gbl_root_node);
1022
1023 exit:
1024 *table_index = i;
1025 return_ACPI_STATUS(status);
1026 }
1027
1028 ACPI_EXPORT_SYMBOL(acpi_tb_install_and_load_table)
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042 acpi_status acpi_tb_unload_table(u32 table_index)
1043 {
1044 acpi_status status = AE_OK;
1045 struct acpi_table_header *table;
1046
1047 ACPI_FUNCTION_TRACE(tb_unload_table);
1048
1049
1050
1051 if (!acpi_tb_is_table_loaded(table_index)) {
1052 return_ACPI_STATUS(AE_NOT_EXIST);
1053 }
1054
1055
1056
1057 status = acpi_get_table_by_index(table_index, &table);
1058 if (ACPI_SUCCESS(status)) {
1059 acpi_tb_notify_table(ACPI_TABLE_EVENT_UNLOAD, table);
1060 }
1061
1062
1063
1064 status = acpi_tb_delete_namespace_by_owner(table_index);
1065 if (ACPI_FAILURE(status)) {
1066 return_ACPI_STATUS(status);
1067 }
1068
1069 (void)acpi_tb_release_owner_id(table_index);
1070 acpi_tb_set_table_loaded_flag(table_index, FALSE);
1071 return_ACPI_STATUS(status);
1072 }
1073
1074 ACPI_EXPORT_SYMBOL(acpi_tb_unload_table)
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089 void acpi_tb_notify_table(u32 event, void *table)
1090 {
1091
1092
1093 if (acpi_gbl_table_handler) {
1094 (void)acpi_gbl_table_handler(event, table,
1095 acpi_gbl_table_handler_context);
1096 }
1097 }