diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-05-06 18:45:27 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-05-06 18:45:27 -0400 |
commit | 23a75c52bef3ed0b688e45e352ce26069bdfd97f (patch) | |
tree | d9f0348ad9031f8552f6de067c76a6da1e24b03c /drivers/acpi | |
parent | d48dc067450d84324067f4472dc0b169e9af4454 (diff) | |
parent | fd0c940522c5c5b281b7a4fe3497fabf74bd8911 (diff) |
Merge back earlier ACPICA material.
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpica/Makefile | 1 | ||||
-rw-r--r-- | drivers/acpi/acpica/acapps.h | 170 | ||||
-rw-r--r-- | drivers/acpi/acpica/acglobal.h | 9 | ||||
-rw-r--r-- | drivers/acpi/acpica/aclocal.h | 8 | ||||
-rw-r--r-- | drivers/acpi/acpica/actables.h | 60 | ||||
-rw-r--r-- | drivers/acpi/acpica/acutils.h | 10 | ||||
-rw-r--r-- | drivers/acpi/acpica/evmisc.c | 3 | ||||
-rw-r--r-- | drivers/acpi/acpica/evsci.c | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxface.c | 61 | ||||
-rw-r--r-- | drivers/acpi/acpica/exconfig.c | 82 | ||||
-rw-r--r-- | drivers/acpi/acpica/exdump.c | 4 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbdata.c | 723 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbfadt.c | 10 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbfind.c | 4 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbinstal.c | 837 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbutils.c | 171 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbxface.c | 18 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbxfload.c | 87 | ||||
-rw-r--r-- | drivers/acpi/acpica/utdecode.c | 74 | ||||
-rw-r--r-- | drivers/acpi/acpica/utstring.c | 2 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 11 |
21 files changed, 1531 insertions, 816 deletions
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index b7ed86a20427..8bb43f06e11f 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -135,6 +135,7 @@ acpi-y += \ | |||
135 | rsxface.o | 135 | rsxface.o |
136 | 136 | ||
137 | acpi-y += \ | 137 | acpi-y += \ |
138 | tbdata.o \ | ||
138 | tbfadt.o \ | 139 | tbfadt.o \ |
139 | tbfind.o \ | 140 | tbfind.o \ |
140 | tbinstal.o \ | 141 | tbinstal.o \ |
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h new file mode 100644 index 000000000000..8698ffba6f39 --- /dev/null +++ b/drivers/acpi/acpica/acapps.h | |||
@@ -0,0 +1,170 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: acapps - common include for ACPI applications/tools | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #ifndef _ACAPPS | ||
45 | #define _ACAPPS | ||
46 | |||
47 | /* Common info for tool signons */ | ||
48 | |||
49 | #define ACPICA_NAME "Intel ACPI Component Architecture" | ||
50 | #define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2014 Intel Corporation" | ||
51 | |||
52 | #if ACPI_MACHINE_WIDTH == 64 | ||
53 | #define ACPI_WIDTH "-64" | ||
54 | |||
55 | #elif ACPI_MACHINE_WIDTH == 32 | ||
56 | #define ACPI_WIDTH "-32" | ||
57 | |||
58 | #else | ||
59 | #error unknown ACPI_MACHINE_WIDTH | ||
60 | #define ACPI_WIDTH "-??" | ||
61 | |||
62 | #endif | ||
63 | |||
64 | /* Macros for signons and file headers */ | ||
65 | |||
66 | #define ACPI_COMMON_SIGNON(utility_name) \ | ||
67 | "\n%s\n%s version %8.8X%s [%s]\n%s\n\n", \ | ||
68 | ACPICA_NAME, \ | ||
69 | utility_name, ((u32) ACPI_CA_VERSION), ACPI_WIDTH, __DATE__, \ | ||
70 | ACPICA_COPYRIGHT | ||
71 | |||
72 | #define ACPI_COMMON_HEADER(utility_name, prefix) \ | ||
73 | "%s%s\n%s%s version %8.8X%s [%s]\n%s%s\n%s\n", \ | ||
74 | prefix, ACPICA_NAME, \ | ||
75 | prefix, utility_name, ((u32) ACPI_CA_VERSION), ACPI_WIDTH, __DATE__, \ | ||
76 | prefix, ACPICA_COPYRIGHT, \ | ||
77 | prefix | ||
78 | |||
79 | /* Macros for usage messages */ | ||
80 | |||
81 | #define ACPI_USAGE_HEADER(usage) \ | ||
82 | printf ("Usage: %s\nOptions:\n", usage); | ||
83 | |||
84 | #define ACPI_OPTION(name, description) \ | ||
85 | printf (" %-18s%s\n", name, description); | ||
86 | |||
87 | #define FILE_SUFFIX_DISASSEMBLY "dsl" | ||
88 | #define ACPI_TABLE_FILE_SUFFIX ".dat" | ||
89 | |||
90 | /* | ||
91 | * getopt | ||
92 | */ | ||
93 | int acpi_getopt(int argc, char **argv, char *opts); | ||
94 | |||
95 | int acpi_getopt_argument(int argc, char **argv); | ||
96 | |||
97 | extern int acpi_gbl_optind; | ||
98 | extern int acpi_gbl_opterr; | ||
99 | extern int acpi_gbl_sub_opt_char; | ||
100 | extern char *acpi_gbl_optarg; | ||
101 | |||
102 | /* | ||
103 | * cmfsize - Common get file size function | ||
104 | */ | ||
105 | u32 cm_get_file_size(FILE * file); | ||
106 | |||
107 | #ifndef ACPI_DUMP_APP | ||
108 | /* | ||
109 | * adisasm | ||
110 | */ | ||
111 | acpi_status | ||
112 | ad_aml_disassemble(u8 out_to_file, | ||
113 | char *filename, char *prefix, char **out_filename); | ||
114 | |||
115 | void ad_print_statistics(void); | ||
116 | |||
117 | acpi_status ad_find_dsdt(u8 **dsdt_ptr, u32 *dsdt_length); | ||
118 | |||
119 | void ad_dump_tables(void); | ||
120 | |||
121 | acpi_status ad_get_local_tables(void); | ||
122 | |||
123 | acpi_status | ||
124 | ad_parse_table(struct acpi_table_header *table, | ||
125 | acpi_owner_id * owner_id, u8 load_table, u8 external); | ||
126 | |||
127 | acpi_status ad_display_tables(char *filename, struct acpi_table_header *table); | ||
128 | |||
129 | acpi_status ad_display_statistics(void); | ||
130 | |||
131 | /* | ||
132 | * adwalk | ||
133 | */ | ||
134 | void | ||
135 | acpi_dm_cross_reference_namespace(union acpi_parse_object *parse_tree_root, | ||
136 | struct acpi_namespace_node *namespace_root, | ||
137 | acpi_owner_id owner_id); | ||
138 | |||
139 | void acpi_dm_dump_tree(union acpi_parse_object *origin); | ||
140 | |||
141 | void acpi_dm_find_orphan_methods(union acpi_parse_object *origin); | ||
142 | |||
143 | void | ||
144 | acpi_dm_finish_namespace_load(union acpi_parse_object *parse_tree_root, | ||
145 | struct acpi_namespace_node *namespace_root, | ||
146 | acpi_owner_id owner_id); | ||
147 | |||
148 | void | ||
149 | acpi_dm_convert_resource_indexes(union acpi_parse_object *parse_tree_root, | ||
150 | struct acpi_namespace_node *namespace_root); | ||
151 | |||
152 | /* | ||
153 | * adfile | ||
154 | */ | ||
155 | acpi_status ad_initialize(void); | ||
156 | |||
157 | char *fl_generate_filename(char *input_filename, char *suffix); | ||
158 | |||
159 | acpi_status | ||
160 | fl_split_input_pathname(char *input_path, | ||
161 | char **out_directory_path, char **out_filename); | ||
162 | |||
163 | char *ad_generate_filename(char *prefix, char *table_id); | ||
164 | |||
165 | void | ||
166 | ad_write_table(struct acpi_table_header *table, | ||
167 | u32 length, char *table_name, char *oem_table_id); | ||
168 | #endif | ||
169 | |||
170 | #endif /* _ACAPPS */ | ||
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 49bbc71fad54..1f602907dfab 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -103,8 +103,8 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, TRUE); | |||
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Create the predefined _OSI method in the namespace? Default is TRUE | 105 | * Create the predefined _OSI method in the namespace? Default is TRUE |
106 | * because ACPI CA is fully compatible with other ACPI implementations. | 106 | * because ACPICA is fully compatible with other ACPI implementations. |
107 | * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. | 107 | * Changing this will revert ACPICA (and machine ASL) to pre-OSI behavior. |
108 | */ | 108 | */ |
109 | ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE); | 109 | ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE); |
110 | 110 | ||
@@ -160,10 +160,10 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_truncate_io_addresses, FALSE); | |||
160 | ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_auto_repair, FALSE); | 160 | ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_auto_repair, FALSE); |
161 | 161 | ||
162 | /* | 162 | /* |
163 | * Optionally do not load any SSDTs from the RSDT/XSDT during initialization. | 163 | * Optionally do not install any SSDTs from the RSDT/XSDT during initialization. |
164 | * This can be useful for debugging ACPI problems on some machines. | 164 | * This can be useful for debugging ACPI problems on some machines. |
165 | */ | 165 | */ |
166 | ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_ssdt_table_load, FALSE); | 166 | ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_ssdt_table_install, FALSE); |
167 | 167 | ||
168 | /* | 168 | /* |
169 | * We keep track of the latest version of Windows that has been requested by | 169 | * We keep track of the latest version of Windows that has been requested by |
@@ -509,5 +509,6 @@ ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); | |||
509 | ****************************************************************************/ | 509 | ****************************************************************************/ |
510 | 510 | ||
511 | extern const struct ah_predefined_name asl_predefined_info[]; | 511 | extern const struct ah_predefined_name asl_predefined_info[]; |
512 | extern const struct ah_device_id asl_device_ids[]; | ||
512 | 513 | ||
513 | #endif /* __ACGLOBAL_H__ */ | 514 | #endif /* __ACGLOBAL_H__ */ |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 52a21dafb540..f68cb602dc23 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -733,7 +733,8 @@ union acpi_parse_value { | |||
733 | #define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ | 733 | #define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ |
734 | #define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ | 734 | #define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ |
735 | #define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ | 735 | #define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ |
736 | #define ACPI_DASM_IGNORE 0x09 /* Not used at this time */ | 736 | #define ACPI_DASM_HID_STRING 0x09 /* String is a _HID or _CID */ |
737 | #define ACPI_DASM_IGNORE 0x0A /* Not used at this time */ | ||
737 | 738 | ||
738 | /* | 739 | /* |
739 | * Generic operation (for example: If, While, Store) | 740 | * Generic operation (for example: If, While, Store) |
@@ -1147,4 +1148,9 @@ struct ah_predefined_name { | |||
1147 | #endif | 1148 | #endif |
1148 | }; | 1149 | }; |
1149 | 1150 | ||
1151 | struct ah_device_id { | ||
1152 | char *name; | ||
1153 | char *description; | ||
1154 | }; | ||
1155 | |||
1150 | #endif /* __ACLOCAL_H__ */ | 1156 | #endif /* __ACLOCAL_H__ */ |
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 5fa4b2027697..bda9a7eb50c1 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h | |||
@@ -54,6 +54,26 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); | |||
54 | u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); | 54 | u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * tbdata - table data structure management | ||
58 | */ | ||
59 | acpi_status acpi_tb_get_next_root_index(u32 *table_index); | ||
60 | |||
61 | void | ||
62 | acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc, | ||
63 | acpi_physical_address address, | ||
64 | u8 flags, struct acpi_table_header *table); | ||
65 | |||
66 | acpi_status | ||
67 | acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, | ||
68 | acpi_physical_address address, u8 flags); | ||
69 | |||
70 | void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc); | ||
71 | |||
72 | u8 acpi_tb_is_table_loaded(u32 table_index); | ||
73 | |||
74 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded); | ||
75 | |||
76 | /* | ||
57 | * tbfadt - FADT parse/convert/validate | 77 | * tbfadt - FADT parse/convert/validate |
58 | */ | 78 | */ |
59 | void acpi_tb_parse_fadt(u32 table_index); | 79 | void acpi_tb_parse_fadt(u32 table_index); |
@@ -72,22 +92,35 @@ acpi_tb_find_table(char *signature, | |||
72 | */ | 92 | */ |
73 | acpi_status acpi_tb_resize_root_table_list(void); | 93 | acpi_status acpi_tb_resize_root_table_list(void); |
74 | 94 | ||
75 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); | 95 | acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc); |
76 | 96 | ||
77 | struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header | 97 | void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc); |
78 | *table_header, | ||
79 | struct acpi_table_desc | ||
80 | *table_desc); | ||
81 | 98 | ||
82 | acpi_status | 99 | acpi_status |
83 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index); | 100 | acpi_tb_verify_table(struct acpi_table_desc *table_desc, char *signature); |
101 | |||
102 | void acpi_tb_override_table(struct acpi_table_desc *old_table_desc); | ||
103 | |||
104 | acpi_status | ||
105 | acpi_tb_acquire_table(struct acpi_table_desc *table_desc, | ||
106 | struct acpi_table_header **table_ptr, | ||
107 | u32 *table_length, u8 *table_flags); | ||
108 | |||
109 | void | ||
110 | acpi_tb_release_table(struct acpi_table_header *table, | ||
111 | u32 table_length, u8 table_flags); | ||
112 | |||
113 | acpi_status | ||
114 | acpi_tb_install_standard_table(acpi_physical_address address, | ||
115 | u8 flags, | ||
116 | u8 reload, u8 override, u32 *table_index); | ||
84 | 117 | ||
85 | acpi_status | 118 | acpi_status |
86 | acpi_tb_store_table(acpi_physical_address address, | 119 | acpi_tb_store_table(acpi_physical_address address, |
87 | struct acpi_table_header *table, | 120 | struct acpi_table_header *table, |
88 | u32 length, u8 flags, u32 *table_index); | 121 | u32 length, u8 flags, u32 *table_index); |
89 | 122 | ||
90 | void acpi_tb_delete_table(struct acpi_table_desc *table_desc); | 123 | void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc); |
91 | 124 | ||
92 | void acpi_tb_terminate(void); | 125 | void acpi_tb_terminate(void); |
93 | 126 | ||
@@ -99,10 +132,6 @@ acpi_status acpi_tb_release_owner_id(u32 table_index); | |||
99 | 132 | ||
100 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id); | 133 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id); |
101 | 134 | ||
102 | u8 acpi_tb_is_table_loaded(u32 table_index); | ||
103 | |||
104 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded); | ||
105 | |||
106 | /* | 135 | /* |
107 | * tbutils - table manager utilities | 136 | * tbutils - table manager utilities |
108 | */ | 137 | */ |
@@ -124,8 +153,13 @@ void acpi_tb_check_dsdt_header(void); | |||
124 | struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index); | 153 | struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index); |
125 | 154 | ||
126 | void | 155 | void |
127 | acpi_tb_install_table(acpi_physical_address address, | 156 | acpi_tb_install_table_with_override(u32 table_index, |
128 | char *signature, u32 table_index); | 157 | struct acpi_table_desc *new_table_desc, |
158 | u8 override); | ||
159 | |||
160 | acpi_status | ||
161 | acpi_tb_install_fixed_table(acpi_physical_address address, | ||
162 | char *signature, u32 table_index); | ||
129 | 163 | ||
130 | acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); | 164 | acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); |
131 | 165 | ||
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index ceeec0b7ccb1..1e256c5bda20 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -176,8 +176,7 @@ acpi_status acpi_ut_init_globals(void); | |||
176 | 176 | ||
177 | char *acpi_ut_get_mutex_name(u32 mutex_id); | 177 | char *acpi_ut_get_mutex_name(u32 mutex_id); |
178 | 178 | ||
179 | const char *acpi_ut_get_notify_name(u32 notify_value); | 179 | const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type); |
180 | |||
181 | #endif | 180 | #endif |
182 | 181 | ||
183 | char *acpi_ut_get_type_name(acpi_object_type type); | 182 | char *acpi_ut_get_type_name(acpi_object_type type); |
@@ -737,4 +736,11 @@ acpi_ut_method_error(const char *module_name, | |||
737 | struct acpi_namespace_node *node, | 736 | struct acpi_namespace_node *node, |
738 | const char *path, acpi_status lookup_status); | 737 | const char *path, acpi_status lookup_status); |
739 | 738 | ||
739 | /* | ||
740 | * Utility functions for ACPI names and IDs | ||
741 | */ | ||
742 | const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg); | ||
743 | |||
744 | const struct ah_device_id *acpi_ah_match_hardware_id(char *hid); | ||
745 | |||
740 | #endif /* _ACUTILS_H */ | 746 | #endif /* _ACUTILS_H */ |
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 5d594eb2e5ec..24ea3424981b 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -167,7 +167,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
167 | "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", | 167 | "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", |
168 | acpi_ut_get_node_name(node), | 168 | acpi_ut_get_node_name(node), |
169 | acpi_ut_get_type_name(node->type), notify_value, | 169 | acpi_ut_get_type_name(node->type), notify_value, |
170 | acpi_ut_get_notify_name(notify_value), node)); | 170 | acpi_ut_get_notify_name(notify_value, ACPI_TYPE_ANY), |
171 | node)); | ||
171 | 172 | ||
172 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, | 173 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, |
173 | info); | 174 | info); |
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 4d8a709c1fc4..29630e303829 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c | |||
@@ -117,7 +117,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context) | |||
117 | ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler); | 117 | ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler); |
118 | 118 | ||
119 | /* | 119 | /* |
120 | * We are guaranteed by the ACPI CA initialization/shutdown code that | 120 | * We are guaranteed by the ACPICA initialization/shutdown code that |
121 | * if this interrupt handler is installed, ACPI is enabled. | 121 | * if this interrupt handler is installed, ACPI is enabled. |
122 | */ | 122 | */ |
123 | 123 | ||
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index a734b27da061..11e5803b8b41 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -239,7 +239,7 @@ acpi_remove_notify_handler(acpi_handle device, | |||
239 | union acpi_operand_object *obj_desc; | 239 | union acpi_operand_object *obj_desc; |
240 | union acpi_operand_object *handler_obj; | 240 | union acpi_operand_object *handler_obj; |
241 | union acpi_operand_object *previous_handler_obj; | 241 | union acpi_operand_object *previous_handler_obj; |
242 | acpi_status status; | 242 | acpi_status status = AE_OK; |
243 | u32 i; | 243 | u32 i; |
244 | 244 | ||
245 | ACPI_FUNCTION_TRACE(acpi_remove_notify_handler); | 245 | ACPI_FUNCTION_TRACE(acpi_remove_notify_handler); |
@@ -251,20 +251,17 @@ acpi_remove_notify_handler(acpi_handle device, | |||
251 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 251 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
252 | } | 252 | } |
253 | 253 | ||
254 | /* Make sure all deferred notify tasks are completed */ | ||
255 | |||
256 | acpi_os_wait_events_complete(); | ||
257 | |||
258 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
259 | if (ACPI_FAILURE(status)) { | ||
260 | return_ACPI_STATUS(status); | ||
261 | } | ||
262 | |||
263 | /* Root Object. Global handlers are removed here */ | 254 | /* Root Object. Global handlers are removed here */ |
264 | 255 | ||
265 | if (device == ACPI_ROOT_OBJECT) { | 256 | if (device == ACPI_ROOT_OBJECT) { |
266 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { | 257 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { |
267 | if (handler_type & (i + 1)) { | 258 | if (handler_type & (i + 1)) { |
259 | status = | ||
260 | acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
261 | if (ACPI_FAILURE(status)) { | ||
262 | return_ACPI_STATUS(status); | ||
263 | } | ||
264 | |||
268 | if (!acpi_gbl_global_notify[i].handler || | 265 | if (!acpi_gbl_global_notify[i].handler || |
269 | (acpi_gbl_global_notify[i].handler != | 266 | (acpi_gbl_global_notify[i].handler != |
270 | handler)) { | 267 | handler)) { |
@@ -277,31 +274,40 @@ acpi_remove_notify_handler(acpi_handle device, | |||
277 | 274 | ||
278 | acpi_gbl_global_notify[i].handler = NULL; | 275 | acpi_gbl_global_notify[i].handler = NULL; |
279 | acpi_gbl_global_notify[i].context = NULL; | 276 | acpi_gbl_global_notify[i].context = NULL; |
277 | |||
278 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
279 | |||
280 | /* Make sure all deferred notify tasks are completed */ | ||
281 | |||
282 | acpi_os_wait_events_complete(); | ||
280 | } | 283 | } |
281 | } | 284 | } |
282 | 285 | ||
283 | goto unlock_and_exit; | 286 | return_ACPI_STATUS(AE_OK); |
284 | } | 287 | } |
285 | 288 | ||
286 | /* All other objects: Are Notifies allowed on this object? */ | 289 | /* All other objects: Are Notifies allowed on this object? */ |
287 | 290 | ||
288 | if (!acpi_ev_is_notify_object(node)) { | 291 | if (!acpi_ev_is_notify_object(node)) { |
289 | status = AE_TYPE; | 292 | return_ACPI_STATUS(AE_TYPE); |
290 | goto unlock_and_exit; | ||
291 | } | 293 | } |
292 | 294 | ||
293 | /* Must have an existing internal object */ | 295 | /* Must have an existing internal object */ |
294 | 296 | ||
295 | obj_desc = acpi_ns_get_attached_object(node); | 297 | obj_desc = acpi_ns_get_attached_object(node); |
296 | if (!obj_desc) { | 298 | if (!obj_desc) { |
297 | status = AE_NOT_EXIST; | 299 | return_ACPI_STATUS(AE_NOT_EXIST); |
298 | goto unlock_and_exit; | ||
299 | } | 300 | } |
300 | 301 | ||
301 | /* Internal object exists. Find the handler and remove it */ | 302 | /* Internal object exists. Find the handler and remove it */ |
302 | 303 | ||
303 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { | 304 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { |
304 | if (handler_type & (i + 1)) { | 305 | if (handler_type & (i + 1)) { |
306 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
307 | if (ACPI_FAILURE(status)) { | ||
308 | return_ACPI_STATUS(status); | ||
309 | } | ||
310 | |||
305 | handler_obj = obj_desc->common_notify.notify_list[i]; | 311 | handler_obj = obj_desc->common_notify.notify_list[i]; |
306 | previous_handler_obj = NULL; | 312 | previous_handler_obj = NULL; |
307 | 313 | ||
@@ -329,10 +335,17 @@ acpi_remove_notify_handler(acpi_handle device, | |||
329 | handler_obj->notify.next[i]; | 335 | handler_obj->notify.next[i]; |
330 | } | 336 | } |
331 | 337 | ||
338 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
339 | |||
340 | /* Make sure all deferred notify tasks are completed */ | ||
341 | |||
342 | acpi_os_wait_events_complete(); | ||
332 | acpi_ut_remove_reference(handler_obj); | 343 | acpi_ut_remove_reference(handler_obj); |
333 | } | 344 | } |
334 | } | 345 | } |
335 | 346 | ||
347 | return_ACPI_STATUS(status); | ||
348 | |||
336 | unlock_and_exit: | 349 | unlock_and_exit: |
337 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 350 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
338 | return_ACPI_STATUS(status); | 351 | return_ACPI_STATUS(status); |
@@ -457,6 +470,8 @@ exit: | |||
457 | return_ACPI_STATUS(status); | 470 | return_ACPI_STATUS(status); |
458 | } | 471 | } |
459 | 472 | ||
473 | ACPI_EXPORT_SYMBOL(acpi_install_sci_handler) | ||
474 | |||
460 | /******************************************************************************* | 475 | /******************************************************************************* |
461 | * | 476 | * |
462 | * FUNCTION: acpi_remove_sci_handler | 477 | * FUNCTION: acpi_remove_sci_handler |
@@ -468,7 +483,6 @@ exit: | |||
468 | * DESCRIPTION: Remove a handler for a System Control Interrupt. | 483 | * DESCRIPTION: Remove a handler for a System Control Interrupt. |
469 | * | 484 | * |
470 | ******************************************************************************/ | 485 | ******************************************************************************/ |
471 | |||
472 | acpi_status acpi_remove_sci_handler(acpi_sci_handler address) | 486 | acpi_status acpi_remove_sci_handler(acpi_sci_handler address) |
473 | { | 487 | { |
474 | struct acpi_sci_handler_info *prev_sci_handler; | 488 | struct acpi_sci_handler_info *prev_sci_handler; |
@@ -522,6 +536,8 @@ unlock_and_exit: | |||
522 | return_ACPI_STATUS(status); | 536 | return_ACPI_STATUS(status); |
523 | } | 537 | } |
524 | 538 | ||
539 | ACPI_EXPORT_SYMBOL(acpi_remove_sci_handler) | ||
540 | |||
525 | /******************************************************************************* | 541 | /******************************************************************************* |
526 | * | 542 | * |
527 | * FUNCTION: acpi_install_global_event_handler | 543 | * FUNCTION: acpi_install_global_event_handler |
@@ -537,7 +553,6 @@ unlock_and_exit: | |||
537 | * Can be used to update event counters, etc. | 553 | * Can be used to update event counters, etc. |
538 | * | 554 | * |
539 | ******************************************************************************/ | 555 | ******************************************************************************/ |
540 | |||
541 | acpi_status | 556 | acpi_status |
542 | acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) | 557 | acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) |
543 | { | 558 | { |
@@ -840,10 +855,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
840 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 855 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
841 | } | 856 | } |
842 | 857 | ||
843 | /* Make sure all deferred GPE tasks are completed */ | ||
844 | |||
845 | acpi_os_wait_events_complete(); | ||
846 | |||
847 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | 858 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
848 | if (ACPI_FAILURE(status)) { | 859 | if (ACPI_FAILURE(status)) { |
849 | return_ACPI_STATUS(status); | 860 | return_ACPI_STATUS(status); |
@@ -895,9 +906,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
895 | (void)acpi_ev_add_gpe_reference(gpe_event_info); | 906 | (void)acpi_ev_add_gpe_reference(gpe_event_info); |
896 | } | 907 | } |
897 | 908 | ||
909 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
910 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
911 | |||
912 | /* Make sure all deferred GPE tasks are completed */ | ||
913 | |||
914 | acpi_os_wait_events_complete(); | ||
915 | |||
898 | /* Now we can free the handler object */ | 916 | /* Now we can free the handler object */ |
899 | 917 | ||
900 | ACPI_FREE(handler); | 918 | ACPI_FREE(handler); |
919 | return_ACPI_STATUS(status); | ||
901 | 920 | ||
902 | unlock_and_exit: | 921 | unlock_and_exit: |
903 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 922 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 8ba1464efd11..7d2949420db7 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -343,16 +343,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
343 | struct acpi_walk_state *walk_state) | 343 | struct acpi_walk_state *walk_state) |
344 | { | 344 | { |
345 | union acpi_operand_object *ddb_handle; | 345 | union acpi_operand_object *ddb_handle; |
346 | struct acpi_table_header *table_header; | ||
346 | struct acpi_table_header *table; | 347 | struct acpi_table_header *table; |
347 | struct acpi_table_desc table_desc; | ||
348 | u32 table_index; | 348 | u32 table_index; |
349 | acpi_status status; | 349 | acpi_status status; |
350 | u32 length; | 350 | u32 length; |
351 | 351 | ||
352 | ACPI_FUNCTION_TRACE(ex_load_op); | 352 | ACPI_FUNCTION_TRACE(ex_load_op); |
353 | 353 | ||
354 | ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); | ||
355 | |||
356 | /* Source Object can be either an op_region or a Buffer/Field */ | 354 | /* Source Object can be either an op_region or a Buffer/Field */ |
357 | 355 | ||
358 | switch (obj_desc->common.type) { | 356 | switch (obj_desc->common.type) { |
@@ -380,17 +378,17 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
380 | 378 | ||
381 | /* Get the table header first so we can get the table length */ | 379 | /* Get the table header first so we can get the table length */ |
382 | 380 | ||
383 | table = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); | 381 | table_header = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); |
384 | if (!table) { | 382 | if (!table_header) { |
385 | return_ACPI_STATUS(AE_NO_MEMORY); | 383 | return_ACPI_STATUS(AE_NO_MEMORY); |
386 | } | 384 | } |
387 | 385 | ||
388 | status = | 386 | status = |
389 | acpi_ex_region_read(obj_desc, | 387 | acpi_ex_region_read(obj_desc, |
390 | sizeof(struct acpi_table_header), | 388 | sizeof(struct acpi_table_header), |
391 | ACPI_CAST_PTR(u8, table)); | 389 | ACPI_CAST_PTR(u8, table_header)); |
392 | length = table->length; | 390 | length = table_header->length; |
393 | ACPI_FREE(table); | 391 | ACPI_FREE(table_header); |
394 | 392 | ||
395 | if (ACPI_FAILURE(status)) { | 393 | if (ACPI_FAILURE(status)) { |
396 | return_ACPI_STATUS(status); | 394 | return_ACPI_STATUS(status); |
@@ -420,22 +418,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
420 | 418 | ||
421 | /* Allocate a buffer for the table */ | 419 | /* Allocate a buffer for the table */ |
422 | 420 | ||
423 | table_desc.pointer = ACPI_ALLOCATE(length); | 421 | table = ACPI_ALLOCATE(length); |
424 | if (!table_desc.pointer) { | 422 | if (!table) { |
425 | return_ACPI_STATUS(AE_NO_MEMORY); | 423 | return_ACPI_STATUS(AE_NO_MEMORY); |
426 | } | 424 | } |
427 | 425 | ||
428 | /* Read the entire table */ | 426 | /* Read the entire table */ |
429 | 427 | ||
430 | status = acpi_ex_region_read(obj_desc, length, | 428 | status = acpi_ex_region_read(obj_desc, length, |
431 | ACPI_CAST_PTR(u8, | 429 | ACPI_CAST_PTR(u8, table)); |
432 | table_desc.pointer)); | ||
433 | if (ACPI_FAILURE(status)) { | 430 | if (ACPI_FAILURE(status)) { |
434 | ACPI_FREE(table_desc.pointer); | 431 | ACPI_FREE(table); |
435 | return_ACPI_STATUS(status); | 432 | return_ACPI_STATUS(status); |
436 | } | 433 | } |
437 | |||
438 | table_desc.address = obj_desc->region.address; | ||
439 | break; | 434 | break; |
440 | 435 | ||
441 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ | 436 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ |
@@ -452,10 +447,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
452 | 447 | ||
453 | /* Get the actual table length from the table header */ | 448 | /* Get the actual table length from the table header */ |
454 | 449 | ||
455 | table = | 450 | table_header = |
456 | ACPI_CAST_PTR(struct acpi_table_header, | 451 | ACPI_CAST_PTR(struct acpi_table_header, |
457 | obj_desc->buffer.pointer); | 452 | obj_desc->buffer.pointer); |
458 | length = table->length; | 453 | length = table_header->length; |
459 | 454 | ||
460 | /* Table cannot extend beyond the buffer */ | 455 | /* Table cannot extend beyond the buffer */ |
461 | 456 | ||
@@ -470,13 +465,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
470 | * Copy the table from the buffer because the buffer could be modified | 465 | * Copy the table from the buffer because the buffer could be modified |
471 | * or even deleted in the future | 466 | * or even deleted in the future |
472 | */ | 467 | */ |
473 | table_desc.pointer = ACPI_ALLOCATE(length); | 468 | table = ACPI_ALLOCATE(length); |
474 | if (!table_desc.pointer) { | 469 | if (!table) { |
475 | return_ACPI_STATUS(AE_NO_MEMORY); | 470 | return_ACPI_STATUS(AE_NO_MEMORY); |
476 | } | 471 | } |
477 | 472 | ||
478 | ACPI_MEMCPY(table_desc.pointer, table, length); | 473 | ACPI_MEMCPY(table, table_header, length); |
479 | table_desc.address = ACPI_TO_INTEGER(table_desc.pointer); | ||
480 | break; | 474 | break; |
481 | 475 | ||
482 | default: | 476 | default: |
@@ -484,27 +478,32 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
484 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 478 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
485 | } | 479 | } |
486 | 480 | ||
487 | /* Validate table checksum (will not get validated in tb_add_table) */ | 481 | /* Install the new table into the local data structures */ |
488 | |||
489 | status = acpi_tb_verify_checksum(table_desc.pointer, length); | ||
490 | if (ACPI_FAILURE(status)) { | ||
491 | ACPI_FREE(table_desc.pointer); | ||
492 | return_ACPI_STATUS(status); | ||
493 | } | ||
494 | |||
495 | /* Complete the table descriptor */ | ||
496 | 482 | ||
497 | table_desc.length = length; | 483 | ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:")); |
498 | table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; | 484 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
499 | 485 | ||
500 | /* Install the new table into the local data structures */ | 486 | status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), |
487 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, | ||
488 | TRUE, TRUE, &table_index); | ||
501 | 489 | ||
502 | status = acpi_tb_add_table(&table_desc, &table_index); | 490 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
503 | if (ACPI_FAILURE(status)) { | 491 | if (ACPI_FAILURE(status)) { |
504 | 492 | ||
505 | /* Delete allocated table buffer */ | 493 | /* Delete allocated table buffer */ |
506 | 494 | ||
507 | acpi_tb_delete_table(&table_desc); | 495 | ACPI_FREE(table); |
496 | return_ACPI_STATUS(status); | ||
497 | } | ||
498 | |||
499 | /* | ||
500 | * Note: Now table is "INSTALLED", it must be validated before | ||
501 | * loading. | ||
502 | */ | ||
503 | status = | ||
504 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | ||
505 | tables[table_index]); | ||
506 | if (ACPI_FAILURE(status)) { | ||
508 | return_ACPI_STATUS(status); | 507 | return_ACPI_STATUS(status); |
509 | } | 508 | } |
510 | 509 | ||
@@ -536,9 +535,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
536 | return_ACPI_STATUS(status); | 535 | return_ACPI_STATUS(status); |
537 | } | 536 | } |
538 | 537 | ||
539 | ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:")); | ||
540 | acpi_tb_print_table_header(0, table_desc.pointer); | ||
541 | |||
542 | /* Remove the reference by added by acpi_ex_store above */ | 538 | /* Remove the reference by added by acpi_ex_store above */ |
543 | 539 | ||
544 | acpi_ut_remove_reference(ddb_handle); | 540 | acpi_ut_remove_reference(ddb_handle); |
@@ -546,8 +542,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
546 | /* Invoke table handler if present */ | 542 | /* Invoke table handler if present */ |
547 | 543 | ||
548 | if (acpi_gbl_table_handler) { | 544 | if (acpi_gbl_table_handler) { |
549 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, | 545 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, |
550 | table_desc.pointer, | ||
551 | acpi_gbl_table_handler_context); | 546 | acpi_gbl_table_handler_context); |
552 | } | 547 | } |
553 | 548 | ||
@@ -576,6 +571,13 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
576 | ACPI_FUNCTION_TRACE(ex_unload_table); | 571 | ACPI_FUNCTION_TRACE(ex_unload_table); |
577 | 572 | ||
578 | /* | 573 | /* |
574 | * Temporarily emit a warning so that the ASL for the machine can be | ||
575 | * hopefully obtained. This is to say that the Unload() operator is | ||
576 | * extremely rare if not completely unused. | ||
577 | */ | ||
578 | ACPI_WARNING((AE_INFO, "Received request to unload an ACPI table")); | ||
579 | |||
580 | /* | ||
579 | * Validate the handle | 581 | * Validate the handle |
580 | * Although the handle is partially validated in acpi_ex_reconfiguration() | 582 | * Although the handle is partially validated in acpi_ex_reconfiguration() |
581 | * when it calls acpi_ex_resolve_operands(), the handle is more completely | 583 | * when it calls acpi_ex_resolve_operands(), the handle is more completely |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 973fdae00f94..925202acc3e4 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -134,9 +134,11 @@ static struct acpi_exdump_info acpi_ex_dump_method[9] = { | |||
134 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} | 134 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} |
135 | }; | 135 | }; |
136 | 136 | ||
137 | static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { | 137 | static struct acpi_exdump_info acpi_ex_dump_mutex[6] = { |
138 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, | 138 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, |
139 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, | 139 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, |
140 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.original_sync_level), | ||
141 | "Original Sync Level"}, | ||
140 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, | 142 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, |
141 | {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), | 143 | {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), |
142 | "Acquire Depth"}, | 144 | "Acquire Depth"}, |
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c new file mode 100644 index 000000000000..cbe29944dc97 --- /dev/null +++ b/drivers/acpi/acpica/tbdata.c | |||
@@ -0,0 +1,723 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbdata - Table manager data structure functions | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acnamesp.h" | ||
47 | #include "actables.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_TABLES | ||
50 | ACPI_MODULE_NAME("tbdata") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_tb_init_table_descriptor | ||
55 | * | ||
56 | * PARAMETERS: table_desc - Table descriptor | ||
57 | * address - Physical address of the table | ||
58 | * flags - Allocation flags of the table | ||
59 | * table - Pointer to the table | ||
60 | * | ||
61 | * RETURN: None | ||
62 | * | ||
63 | * DESCRIPTION: Initialize a new table descriptor | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | void | ||
67 | acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc, | ||
68 | acpi_physical_address address, | ||
69 | u8 flags, struct acpi_table_header *table) | ||
70 | { | ||
71 | |||
72 | /* | ||
73 | * Initialize the table descriptor. Set the pointer to NULL, since the | ||
74 | * table is not fully mapped at this time. | ||
75 | */ | ||
76 | ACPI_MEMSET(table_desc, 0, sizeof(struct acpi_table_desc)); | ||
77 | table_desc->address = address; | ||
78 | table_desc->length = table->length; | ||
79 | table_desc->flags = flags; | ||
80 | ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); | ||
81 | } | ||
82 | |||
83 | /******************************************************************************* | ||
84 | * | ||
85 | * FUNCTION: acpi_tb_acquire_table | ||
86 | * | ||
87 | * PARAMETERS: table_desc - Table descriptor | ||
88 | * table_ptr - Where table is returned | ||
89 | * table_length - Where table length is returned | ||
90 | * table_flags - Where table allocation flags are returned | ||
91 | * | ||
92 | * RETURN: Status | ||
93 | * | ||
94 | * DESCRIPTION: Acquire an ACPI table. It can be used for tables not | ||
95 | * maintained in the acpi_gbl_root_table_list. | ||
96 | * | ||
97 | ******************************************************************************/ | ||
98 | |||
99 | acpi_status | ||
100 | acpi_tb_acquire_table(struct acpi_table_desc *table_desc, | ||
101 | struct acpi_table_header **table_ptr, | ||
102 | u32 *table_length, u8 *table_flags) | ||
103 | { | ||
104 | struct acpi_table_header *table = NULL; | ||
105 | |||
106 | switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { | ||
107 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | ||
108 | |||
109 | table = | ||
110 | acpi_os_map_memory(table_desc->address, table_desc->length); | ||
111 | break; | ||
112 | |||
113 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | ||
114 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | ||
115 | |||
116 | table = | ||
117 | ACPI_CAST_PTR(struct acpi_table_header, | ||
118 | table_desc->address); | ||
119 | break; | ||
120 | |||
121 | default: | ||
122 | |||
123 | break; | ||
124 | } | ||
125 | |||
126 | /* Table is not valid yet */ | ||
127 | |||
128 | if (!table) { | ||
129 | return (AE_NO_MEMORY); | ||
130 | } | ||
131 | |||
132 | /* Fill the return values */ | ||
133 | |||
134 | *table_ptr = table; | ||
135 | *table_length = table_desc->length; | ||
136 | *table_flags = table_desc->flags; | ||
137 | return (AE_OK); | ||
138 | } | ||
139 | |||
140 | /******************************************************************************* | ||
141 | * | ||
142 | * FUNCTION: acpi_tb_release_table | ||
143 | * | ||
144 | * PARAMETERS: table - Pointer for the table | ||
145 | * table_length - Length for the table | ||
146 | * table_flags - Allocation flags for the table | ||
147 | * | ||
148 | * RETURN: None | ||
149 | * | ||
150 | * DESCRIPTION: Release a table. The inverse of acpi_tb_acquire_table(). | ||
151 | * | ||
152 | ******************************************************************************/ | ||
153 | |||
154 | void | ||
155 | acpi_tb_release_table(struct acpi_table_header *table, | ||
156 | u32 table_length, u8 table_flags) | ||
157 | { | ||
158 | |||
159 | switch (table_flags & ACPI_TABLE_ORIGIN_MASK) { | ||
160 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | ||
161 | |||
162 | acpi_os_unmap_memory(table, table_length); | ||
163 | break; | ||
164 | |||
165 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | ||
166 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | ||
167 | default: | ||
168 | |||
169 | break; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | /******************************************************************************* | ||
174 | * | ||
175 | * FUNCTION: acpi_tb_acquire_temp_table | ||
176 | * | ||
177 | * PARAMETERS: table_desc - Table descriptor to be acquired | ||
178 | * address - Address of the table | ||
179 | * flags - Allocation flags of the table | ||
180 | * | ||
181 | * RETURN: Status | ||
182 | * | ||
183 | * DESCRIPTION: This function validates the table header to obtain the length | ||
184 | * of a table and fills the table descriptor to make its state as | ||
185 | * "INSTALLED". Such a table descriptor is only used for verified | ||
186 | * installation. | ||
187 | * | ||
188 | ******************************************************************************/ | ||
189 | |||
190 | acpi_status | ||
191 | acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, | ||
192 | acpi_physical_address address, u8 flags) | ||
193 | { | ||
194 | struct acpi_table_header *table_header; | ||
195 | |||
196 | switch (flags & ACPI_TABLE_ORIGIN_MASK) { | ||
197 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | ||
198 | |||
199 | /* Get the length of the full table from the header */ | ||
200 | |||
201 | table_header = | ||
202 | acpi_os_map_memory(address, | ||
203 | sizeof(struct acpi_table_header)); | ||
204 | if (!table_header) { | ||
205 | return (AE_NO_MEMORY); | ||
206 | } | ||
207 | |||
208 | acpi_tb_init_table_descriptor(table_desc, address, flags, | ||
209 | table_header); | ||
210 | acpi_os_unmap_memory(table_header, | ||
211 | sizeof(struct acpi_table_header)); | ||
212 | return (AE_OK); | ||
213 | |||
214 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | ||
215 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | ||
216 | |||
217 | table_header = ACPI_CAST_PTR(struct acpi_table_header, address); | ||
218 | if (!table_header) { | ||
219 | return (AE_NO_MEMORY); | ||
220 | } | ||
221 | |||
222 | acpi_tb_init_table_descriptor(table_desc, address, flags, | ||
223 | table_header); | ||
224 | return (AE_OK); | ||
225 | |||
226 | default: | ||
227 | |||
228 | break; | ||
229 | } | ||
230 | |||
231 | /* Table is not valid yet */ | ||
232 | |||
233 | return (AE_NO_MEMORY); | ||
234 | } | ||
235 | |||
236 | /******************************************************************************* | ||
237 | * | ||
238 | * FUNCTION: acpi_tb_release_temp_table | ||
239 | * | ||
240 | * PARAMETERS: table_desc - Table descriptor to be released | ||
241 | * | ||
242 | * RETURN: Status | ||
243 | * | ||
244 | * DESCRIPTION: The inverse of acpi_tb_acquire_temp_table(). | ||
245 | * | ||
246 | *****************************************************************************/ | ||
247 | |||
248 | void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc) | ||
249 | { | ||
250 | |||
251 | /* | ||
252 | * Note that the .Address is maintained by the callers of | ||
253 | * acpi_tb_acquire_temp_table(), thus do not invoke acpi_tb_uninstall_table() | ||
254 | * where .Address will be freed. | ||
255 | */ | ||
256 | acpi_tb_invalidate_table(table_desc); | ||
257 | } | ||
258 | |||
259 | /****************************************************************************** | ||
260 | * | ||
261 | * FUNCTION: acpi_tb_validate_table | ||
262 | * | ||
263 | * PARAMETERS: table_desc - Table descriptor | ||
264 | * | ||
265 | * RETURN: Status | ||
266 | * | ||
267 | * DESCRIPTION: This function is called to validate the table, the returned | ||
268 | * table descriptor is in "VALIDATED" state. | ||
269 | * | ||
270 | *****************************************************************************/ | ||
271 | |||
272 | acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc) | ||
273 | { | ||
274 | acpi_status status = AE_OK; | ||
275 | |||
276 | ACPI_FUNCTION_TRACE(tb_validate_table); | ||
277 | |||
278 | /* Validate the table if necessary */ | ||
279 | |||
280 | if (!table_desc->pointer) { | ||
281 | status = acpi_tb_acquire_table(table_desc, &table_desc->pointer, | ||
282 | &table_desc->length, | ||
283 | &table_desc->flags); | ||
284 | if (!table_desc->pointer) { | ||
285 | status = AE_NO_MEMORY; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | return_ACPI_STATUS(status); | ||
290 | } | ||
291 | |||
292 | /******************************************************************************* | ||
293 | * | ||
294 | * FUNCTION: acpi_tb_invalidate_table | ||
295 | * | ||
296 | * PARAMETERS: table_desc - Table descriptor | ||
297 | * | ||
298 | * RETURN: None | ||
299 | * | ||
300 | * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of | ||
301 | * acpi_tb_validate_table(). | ||
302 | * | ||
303 | ******************************************************************************/ | ||
304 | |||
305 | void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc) | ||
306 | { | ||
307 | |||
308 | ACPI_FUNCTION_TRACE(tb_invalidate_table); | ||
309 | |||
310 | /* Table must be validated */ | ||
311 | |||
312 | if (!table_desc->pointer) { | ||
313 | return_VOID; | ||
314 | } | ||
315 | |||
316 | acpi_tb_release_table(table_desc->pointer, table_desc->length, | ||
317 | table_desc->flags); | ||
318 | table_desc->pointer = NULL; | ||
319 | |||
320 | return_VOID; | ||
321 | } | ||
322 | |||
323 | /****************************************************************************** | ||
324 | * | ||
325 | * FUNCTION: acpi_tb_verify_table | ||
326 | * | ||
327 | * PARAMETERS: table_desc - Table descriptor | ||
328 | * signature - Table signature to verify | ||
329 | * | ||
330 | * RETURN: Status | ||
331 | * | ||
332 | * DESCRIPTION: This function is called to validate and verify the table, the | ||
333 | * returned table descriptor is in "VALIDATED" state. | ||
334 | * | ||
335 | *****************************************************************************/ | ||
336 | |||
337 | acpi_status | ||
338 | acpi_tb_verify_table(struct acpi_table_desc *table_desc, char *signature) | ||
339 | { | ||
340 | acpi_status status = AE_OK; | ||
341 | |||
342 | ACPI_FUNCTION_TRACE(tb_verify_table); | ||
343 | |||
344 | /* Validate the table */ | ||
345 | |||
346 | status = acpi_tb_validate_table(table_desc); | ||
347 | if (ACPI_FAILURE(status)) { | ||
348 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
349 | } | ||
350 | |||
351 | /* If a particular signature is expected (DSDT/FACS), it must match */ | ||
352 | |||
353 | if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) { | ||
354 | ACPI_BIOS_ERROR((AE_INFO, | ||
355 | "Invalid signature 0x%X for ACPI table, expected [%s]", | ||
356 | table_desc->signature.integer, signature)); | ||
357 | status = AE_BAD_SIGNATURE; | ||
358 | goto invalidate_and_exit; | ||
359 | } | ||
360 | |||
361 | /* Verify the checksum */ | ||
362 | |||
363 | status = | ||
364 | acpi_tb_verify_checksum(table_desc->pointer, table_desc->length); | ||
365 | if (ACPI_FAILURE(status)) { | ||
366 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, | ||
367 | "%4.4s " ACPI_PRINTF_UINT | ||
368 | " Attempted table install failed", | ||
369 | acpi_ut_valid_acpi_name(table_desc->signature. | ||
370 | ascii) ? table_desc-> | ||
371 | signature.ascii : "????", | ||
372 | ACPI_FORMAT_TO_UINT(table_desc->address))); | ||
373 | goto invalidate_and_exit; | ||
374 | } | ||
375 | |||
376 | return_ACPI_STATUS(AE_OK); | ||
377 | |||
378 | invalidate_and_exit: | ||
379 | acpi_tb_invalidate_table(table_desc); | ||
380 | return_ACPI_STATUS(status); | ||
381 | } | ||
382 | |||
383 | /******************************************************************************* | ||
384 | * | ||
385 | * FUNCTION: acpi_tb_resize_root_table_list | ||
386 | * | ||
387 | * PARAMETERS: None | ||
388 | * | ||
389 | * RETURN: Status | ||
390 | * | ||
391 | * DESCRIPTION: Expand the size of global table array | ||
392 | * | ||
393 | ******************************************************************************/ | ||
394 | |||
395 | acpi_status acpi_tb_resize_root_table_list(void) | ||
396 | { | ||
397 | struct acpi_table_desc *tables; | ||
398 | u32 table_count; | ||
399 | |||
400 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); | ||
401 | |||
402 | /* allow_resize flag is a parameter to acpi_initialize_tables */ | ||
403 | |||
404 | if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { | ||
405 | ACPI_ERROR((AE_INFO, | ||
406 | "Resize of Root Table Array is not allowed")); | ||
407 | return_ACPI_STATUS(AE_SUPPORT); | ||
408 | } | ||
409 | |||
410 | /* Increase the Table Array size */ | ||
411 | |||
412 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
413 | table_count = acpi_gbl_root_table_list.max_table_count; | ||
414 | } else { | ||
415 | table_count = acpi_gbl_root_table_list.current_table_count; | ||
416 | } | ||
417 | |||
418 | tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + | ||
419 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * | ||
420 | sizeof(struct acpi_table_desc)); | ||
421 | if (!tables) { | ||
422 | ACPI_ERROR((AE_INFO, | ||
423 | "Could not allocate new root table array")); | ||
424 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
425 | } | ||
426 | |||
427 | /* Copy and free the previous table array */ | ||
428 | |||
429 | if (acpi_gbl_root_table_list.tables) { | ||
430 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, | ||
431 | (acpi_size) table_count * | ||
432 | sizeof(struct acpi_table_desc)); | ||
433 | |||
434 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
435 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
436 | } | ||
437 | } | ||
438 | |||
439 | acpi_gbl_root_table_list.tables = tables; | ||
440 | acpi_gbl_root_table_list.max_table_count = | ||
441 | table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; | ||
442 | acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; | ||
443 | |||
444 | return_ACPI_STATUS(AE_OK); | ||
445 | } | ||
446 | |||
447 | /******************************************************************************* | ||
448 | * | ||
449 | * FUNCTION: acpi_tb_get_next_root_index | ||
450 | * | ||
451 | * PARAMETERS: table_index - Where table index is returned | ||
452 | * | ||
453 | * RETURN: Status and table index. | ||
454 | * | ||
455 | * DESCRIPTION: Allocate a new ACPI table entry to the global table list | ||
456 | * | ||
457 | ******************************************************************************/ | ||
458 | |||
459 | acpi_status acpi_tb_get_next_root_index(u32 *table_index) | ||
460 | { | ||
461 | acpi_status status; | ||
462 | |||
463 | /* Ensure that there is room for the table in the Root Table List */ | ||
464 | |||
465 | if (acpi_gbl_root_table_list.current_table_count >= | ||
466 | acpi_gbl_root_table_list.max_table_count) { | ||
467 | status = acpi_tb_resize_root_table_list(); | ||
468 | if (ACPI_FAILURE(status)) { | ||
469 | return (status); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | *table_index = acpi_gbl_root_table_list.current_table_count; | ||
474 | acpi_gbl_root_table_list.current_table_count++; | ||
475 | return (AE_OK); | ||
476 | } | ||
477 | |||
478 | /******************************************************************************* | ||
479 | * | ||
480 | * FUNCTION: acpi_tb_terminate | ||
481 | * | ||
482 | * PARAMETERS: None | ||
483 | * | ||
484 | * RETURN: None | ||
485 | * | ||
486 | * DESCRIPTION: Delete all internal ACPI tables | ||
487 | * | ||
488 | ******************************************************************************/ | ||
489 | |||
490 | void acpi_tb_terminate(void) | ||
491 | { | ||
492 | u32 i; | ||
493 | |||
494 | ACPI_FUNCTION_TRACE(tb_terminate); | ||
495 | |||
496 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
497 | |||
498 | /* Delete the individual tables */ | ||
499 | |||
500 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { | ||
501 | acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]); | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * Delete the root table array if allocated locally. Array cannot be | ||
506 | * mapped, so we don't need to check for that flag. | ||
507 | */ | ||
508 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
509 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
510 | } | ||
511 | |||
512 | acpi_gbl_root_table_list.tables = NULL; | ||
513 | acpi_gbl_root_table_list.flags = 0; | ||
514 | acpi_gbl_root_table_list.current_table_count = 0; | ||
515 | |||
516 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | ||
517 | |||
518 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
519 | return_VOID; | ||
520 | } | ||
521 | |||
522 | /******************************************************************************* | ||
523 | * | ||
524 | * FUNCTION: acpi_tb_delete_namespace_by_owner | ||
525 | * | ||
526 | * PARAMETERS: table_index - Table index | ||
527 | * | ||
528 | * RETURN: Status | ||
529 | * | ||
530 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. | ||
531 | * | ||
532 | ******************************************************************************/ | ||
533 | |||
534 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) | ||
535 | { | ||
536 | acpi_owner_id owner_id; | ||
537 | acpi_status status; | ||
538 | |||
539 | ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); | ||
540 | |||
541 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
542 | if (ACPI_FAILURE(status)) { | ||
543 | return_ACPI_STATUS(status); | ||
544 | } | ||
545 | |||
546 | if (table_index >= acpi_gbl_root_table_list.current_table_count) { | ||
547 | |||
548 | /* The table index does not exist */ | ||
549 | |||
550 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
551 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
552 | } | ||
553 | |||
554 | /* Get the owner ID for this table, used to delete namespace nodes */ | ||
555 | |||
556 | owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
557 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
558 | |||
559 | /* | ||
560 | * Need to acquire the namespace writer lock to prevent interference | ||
561 | * with any concurrent namespace walks. The interpreter must be | ||
562 | * released during the deletion since the acquisition of the deletion | ||
563 | * lock may block, and also since the execution of a namespace walk | ||
564 | * must be allowed to use the interpreter. | ||
565 | */ | ||
566 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | ||
567 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | ||
568 | |||
569 | acpi_ns_delete_namespace_by_owner(owner_id); | ||
570 | if (ACPI_FAILURE(status)) { | ||
571 | return_ACPI_STATUS(status); | ||
572 | } | ||
573 | |||
574 | acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); | ||
575 | |||
576 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | ||
577 | return_ACPI_STATUS(status); | ||
578 | } | ||
579 | |||
580 | /******************************************************************************* | ||
581 | * | ||
582 | * FUNCTION: acpi_tb_allocate_owner_id | ||
583 | * | ||
584 | * PARAMETERS: table_index - Table index | ||
585 | * | ||
586 | * RETURN: Status | ||
587 | * | ||
588 | * DESCRIPTION: Allocates owner_id in table_desc | ||
589 | * | ||
590 | ******************************************************************************/ | ||
591 | |||
592 | acpi_status acpi_tb_allocate_owner_id(u32 table_index) | ||
593 | { | ||
594 | acpi_status status = AE_BAD_PARAMETER; | ||
595 | |||
596 | ACPI_FUNCTION_TRACE(tb_allocate_owner_id); | ||
597 | |||
598 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
599 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
600 | status = | ||
601 | acpi_ut_allocate_owner_id(& | ||
602 | (acpi_gbl_root_table_list. | ||
603 | tables[table_index].owner_id)); | ||
604 | } | ||
605 | |||
606 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
607 | return_ACPI_STATUS(status); | ||
608 | } | ||
609 | |||
610 | /******************************************************************************* | ||
611 | * | ||
612 | * FUNCTION: acpi_tb_release_owner_id | ||
613 | * | ||
614 | * PARAMETERS: table_index - Table index | ||
615 | * | ||
616 | * RETURN: Status | ||
617 | * | ||
618 | * DESCRIPTION: Releases owner_id in table_desc | ||
619 | * | ||
620 | ******************************************************************************/ | ||
621 | |||
622 | acpi_status acpi_tb_release_owner_id(u32 table_index) | ||
623 | { | ||
624 | acpi_status status = AE_BAD_PARAMETER; | ||
625 | |||
626 | ACPI_FUNCTION_TRACE(tb_release_owner_id); | ||
627 | |||
628 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
629 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
630 | acpi_ut_release_owner_id(& | ||
631 | (acpi_gbl_root_table_list. | ||
632 | tables[table_index].owner_id)); | ||
633 | status = AE_OK; | ||
634 | } | ||
635 | |||
636 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
637 | return_ACPI_STATUS(status); | ||
638 | } | ||
639 | |||
640 | /******************************************************************************* | ||
641 | * | ||
642 | * FUNCTION: acpi_tb_get_owner_id | ||
643 | * | ||
644 | * PARAMETERS: table_index - Table index | ||
645 | * owner_id - Where the table owner_id is returned | ||
646 | * | ||
647 | * RETURN: Status | ||
648 | * | ||
649 | * DESCRIPTION: returns owner_id for the ACPI table | ||
650 | * | ||
651 | ******************************************************************************/ | ||
652 | |||
653 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id) | ||
654 | { | ||
655 | acpi_status status = AE_BAD_PARAMETER; | ||
656 | |||
657 | ACPI_FUNCTION_TRACE(tb_get_owner_id); | ||
658 | |||
659 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
660 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
661 | *owner_id = | ||
662 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
663 | status = AE_OK; | ||
664 | } | ||
665 | |||
666 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
667 | return_ACPI_STATUS(status); | ||
668 | } | ||
669 | |||
670 | /******************************************************************************* | ||
671 | * | ||
672 | * FUNCTION: acpi_tb_is_table_loaded | ||
673 | * | ||
674 | * PARAMETERS: table_index - Index into the root table | ||
675 | * | ||
676 | * RETURN: Table Loaded Flag | ||
677 | * | ||
678 | ******************************************************************************/ | ||
679 | |||
680 | u8 acpi_tb_is_table_loaded(u32 table_index) | ||
681 | { | ||
682 | u8 is_loaded = FALSE; | ||
683 | |||
684 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
685 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
686 | is_loaded = (u8) | ||
687 | (acpi_gbl_root_table_list.tables[table_index].flags & | ||
688 | ACPI_TABLE_IS_LOADED); | ||
689 | } | ||
690 | |||
691 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
692 | return (is_loaded); | ||
693 | } | ||
694 | |||
695 | /******************************************************************************* | ||
696 | * | ||
697 | * FUNCTION: acpi_tb_set_table_loaded_flag | ||
698 | * | ||
699 | * PARAMETERS: table_index - Table index | ||
700 | * is_loaded - TRUE if table is loaded, FALSE otherwise | ||
701 | * | ||
702 | * RETURN: None | ||
703 | * | ||
704 | * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. | ||
705 | * | ||
706 | ******************************************************************************/ | ||
707 | |||
708 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) | ||
709 | { | ||
710 | |||
711 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
712 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
713 | if (is_loaded) { | ||
714 | acpi_gbl_root_table_list.tables[table_index].flags |= | ||
715 | ACPI_TABLE_IS_LOADED; | ||
716 | } else { | ||
717 | acpi_gbl_root_table_list.tables[table_index].flags &= | ||
718 | ~ACPI_TABLE_IS_LOADED; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
723 | } | ||
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index ec14588254d4..a37af164b8c8 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -332,15 +332,15 @@ void acpi_tb_parse_fadt(u32 table_index) | |||
332 | 332 | ||
333 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ | 333 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ |
334 | 334 | ||
335 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, | 335 | acpi_tb_install_fixed_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, |
336 | ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); | 336 | ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); |
337 | 337 | ||
338 | /* If Hardware Reduced flag is set, there is no FACS */ | 338 | /* If Hardware Reduced flag is set, there is no FACS */ |
339 | 339 | ||
340 | if (!acpi_gbl_reduced_hardware) { | 340 | if (!acpi_gbl_reduced_hardware) { |
341 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT. | 341 | acpi_tb_install_fixed_table((acpi_physical_address) |
342 | Xfacs, ACPI_SIG_FACS, | 342 | acpi_gbl_FADT.Xfacs, ACPI_SIG_FACS, |
343 | ACPI_TABLE_INDEX_FACS); | 343 | ACPI_TABLE_INDEX_FACS); |
344 | } | 344 | } |
345 | } | 345 | } |
346 | 346 | ||
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index c12003947bd5..cb947700206c 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c | |||
@@ -99,8 +99,8 @@ acpi_tb_find_table(char *signature, | |||
99 | /* Table is not currently mapped, map it */ | 99 | /* Table is not currently mapped, map it */ |
100 | 100 | ||
101 | status = | 101 | status = |
102 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | 102 | acpi_tb_validate_table(&acpi_gbl_root_table_list. |
103 | tables[i]); | 103 | tables[i]); |
104 | if (ACPI_FAILURE(status)) { | 104 | if (ACPI_FAILURE(status)) { |
105 | return_ACPI_STATUS(status); | 105 | return_ACPI_STATUS(status); |
106 | } | 106 | } |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index e3040947e9a0..d4d6029fef44 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -43,688 +43,483 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | ||
47 | #include "actables.h" | 46 | #include "actables.h" |
48 | 47 | ||
49 | #define _COMPONENT ACPI_TABLES | 48 | #define _COMPONENT ACPI_TABLES |
50 | ACPI_MODULE_NAME("tbinstal") | 49 | ACPI_MODULE_NAME("tbinstal") |
51 | 50 | ||
52 | /****************************************************************************** | 51 | /* Local prototypes */ |
52 | static u8 | ||
53 | acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index); | ||
54 | |||
55 | /******************************************************************************* | ||
53 | * | 56 | * |
54 | * FUNCTION: acpi_tb_verify_table | 57 | * FUNCTION: acpi_tb_compare_tables |
55 | * | 58 | * |
56 | * PARAMETERS: table_desc - table | 59 | * PARAMETERS: table_desc - Table 1 descriptor to be compared |
60 | * table_index - Index of table 2 to be compared | ||
57 | * | 61 | * |
58 | * RETURN: Status | 62 | * RETURN: TRUE if both tables are identical. |
59 | * | 63 | * |
60 | * DESCRIPTION: this function is called to verify and map table | 64 | * DESCRIPTION: This function compares a table with another table that has |
65 | * already been installed in the root table list. | ||
61 | * | 66 | * |
62 | *****************************************************************************/ | 67 | ******************************************************************************/ |
63 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | 68 | |
69 | static u8 | ||
70 | acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index) | ||
64 | { | 71 | { |
65 | acpi_status status = AE_OK; | 72 | acpi_status status = AE_OK; |
73 | u8 is_identical; | ||
74 | struct acpi_table_header *table; | ||
75 | u32 table_length; | ||
76 | u8 table_flags; | ||
66 | 77 | ||
67 | ACPI_FUNCTION_TRACE(tb_verify_table); | 78 | status = |
68 | 79 | acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index], | |
69 | /* Map the table if necessary */ | 80 | &table, &table_length, &table_flags); |
70 | 81 | if (ACPI_FAILURE(status)) { | |
71 | if (!table_desc->pointer) { | 82 | return (FALSE); |
72 | if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == | ||
73 | ACPI_TABLE_ORIGIN_MAPPED) { | ||
74 | table_desc->pointer = | ||
75 | acpi_os_map_memory(table_desc->address, | ||
76 | table_desc->length); | ||
77 | } | ||
78 | if (!table_desc->pointer) { | ||
79 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
80 | } | ||
81 | } | 83 | } |
82 | 84 | ||
83 | /* Always calculate checksum, ignore bad checksum if requested */ | 85 | /* |
86 | * Check for a table match on the entire table length, | ||
87 | * not just the header. | ||
88 | */ | ||
89 | is_identical = (u8)((table_desc->length != table_length || | ||
90 | ACPI_MEMCMP(table_desc->pointer, table, | ||
91 | table_length)) ? FALSE : TRUE); | ||
84 | 92 | ||
85 | status = | 93 | /* Release the acquired table */ |
86 | acpi_tb_verify_checksum(table_desc->pointer, table_desc->length); | ||
87 | 94 | ||
88 | return_ACPI_STATUS(status); | 95 | acpi_tb_release_table(table, table_length, table_flags); |
96 | return (is_identical); | ||
89 | } | 97 | } |
90 | 98 | ||
91 | /******************************************************************************* | 99 | /******************************************************************************* |
92 | * | 100 | * |
93 | * FUNCTION: acpi_tb_add_table | 101 | * FUNCTION: acpi_tb_install_table_with_override |
94 | * | 102 | * |
95 | * PARAMETERS: table_desc - Table descriptor | 103 | * PARAMETERS: table_index - Index into root table array |
96 | * table_index - Where the table index is returned | 104 | * new_table_desc - New table descriptor to install |
105 | * override - Whether override should be performed | ||
97 | * | 106 | * |
98 | * RETURN: Status | 107 | * RETURN: None |
99 | * | 108 | * |
100 | * DESCRIPTION: This function is called to add an ACPI table. It is used to | 109 | * DESCRIPTION: Install an ACPI table into the global data structure. The |
101 | * dynamically load tables via the Load and load_table AML | 110 | * table override mechanism is called to allow the host |
102 | * operators. | 111 | * OS to replace any table before it is installed in the root |
112 | * table array. | ||
103 | * | 113 | * |
104 | ******************************************************************************/ | 114 | ******************************************************************************/ |
105 | 115 | ||
106 | acpi_status | 116 | void |
107 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | 117 | acpi_tb_install_table_with_override(u32 table_index, |
118 | struct acpi_table_desc *new_table_desc, | ||
119 | u8 override) | ||
108 | { | 120 | { |
109 | u32 i; | ||
110 | acpi_status status = AE_OK; | ||
111 | 121 | ||
112 | ACPI_FUNCTION_TRACE(tb_add_table); | 122 | if (table_index >= acpi_gbl_root_table_list.current_table_count) { |
113 | 123 | return; | |
114 | if (!table_desc->pointer) { | ||
115 | status = acpi_tb_verify_table(table_desc); | ||
116 | if (ACPI_FAILURE(status) || !table_desc->pointer) { | ||
117 | return_ACPI_STATUS(status); | ||
118 | } | ||
119 | } | 124 | } |
120 | 125 | ||
121 | /* | 126 | /* |
122 | * Validate the incoming table signature. | 127 | * ACPI Table Override: |
123 | * | 128 | * |
124 | * 1) Originally, we checked the table signature for "SSDT" or "PSDT". | 129 | * Before we install the table, let the host OS override it with a new |
125 | * 2) We added support for OEMx tables, signature "OEM". | 130 | * one if desired. Any table within the RSDT/XSDT can be replaced, |
126 | * 3) Valid tables were encountered with a null signature, so we just | 131 | * including the DSDT which is pointed to by the FADT. |
127 | * gave up on validating the signature, (05/2008). | ||
128 | * 4) We encountered non-AML tables such as the MADT, which caused | ||
129 | * interpreter errors and kernel faults. So now, we once again allow | ||
130 | * only "SSDT", "OEMx", and now, also a null signature. (05/2011). | ||
131 | */ | 132 | */ |
132 | if ((table_desc->pointer->signature[0] != 0x00) && | 133 | if (override) { |
133 | (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)) | 134 | acpi_tb_override_table(new_table_desc); |
134 | && (ACPI_STRNCMP(table_desc->pointer->signature, "OEM", 3))) { | ||
135 | ACPI_BIOS_ERROR((AE_INFO, | ||
136 | "Table has invalid signature [%4.4s] (0x%8.8X), " | ||
137 | "must be SSDT or OEMx", | ||
138 | acpi_ut_valid_acpi_name(table_desc->pointer-> | ||
139 | signature) ? | ||
140 | table_desc->pointer->signature : "????", | ||
141 | *(u32 *)table_desc->pointer->signature)); | ||
142 | |||
143 | return_ACPI_STATUS(AE_BAD_SIGNATURE); | ||
144 | } | 135 | } |
145 | 136 | ||
146 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 137 | acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list. |
138 | tables[table_index], | ||
139 | new_table_desc->address, | ||
140 | new_table_desc->flags, | ||
141 | new_table_desc->pointer); | ||
147 | 142 | ||
148 | /* Check if table is already registered */ | 143 | acpi_tb_print_table_header(new_table_desc->address, |
144 | new_table_desc->pointer); | ||
149 | 145 | ||
150 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { | 146 | /* Set the global integer width (based upon revision of the DSDT) */ |
151 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | ||
152 | status = | ||
153 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
154 | tables[i]); | ||
155 | if (ACPI_FAILURE(status) | ||
156 | || !acpi_gbl_root_table_list.tables[i].pointer) { | ||
157 | continue; | ||
158 | } | ||
159 | } | ||
160 | 147 | ||
161 | /* | 148 | if (table_index == ACPI_TABLE_INDEX_DSDT) { |
162 | * Check for a table match on the entire table length, | 149 | acpi_ut_set_integer_width(new_table_desc->pointer->revision); |
163 | * not just the header. | ||
164 | */ | ||
165 | if (table_desc->length != | ||
166 | acpi_gbl_root_table_list.tables[i].length) { | ||
167 | continue; | ||
168 | } | ||
169 | |||
170 | if (ACPI_MEMCMP(table_desc->pointer, | ||
171 | acpi_gbl_root_table_list.tables[i].pointer, | ||
172 | acpi_gbl_root_table_list.tables[i].length)) { | ||
173 | continue; | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * Note: the current mechanism does not unregister a table if it is | ||
178 | * dynamically unloaded. The related namespace entries are deleted, | ||
179 | * but the table remains in the root table list. | ||
180 | * | ||
181 | * The assumption here is that the number of different tables that | ||
182 | * will be loaded is actually small, and there is minimal overhead | ||
183 | * in just keeping the table in case it is needed again. | ||
184 | * | ||
185 | * If this assumption changes in the future (perhaps on large | ||
186 | * machines with many table load/unload operations), tables will | ||
187 | * need to be unregistered when they are unloaded, and slots in the | ||
188 | * root table list should be reused when empty. | ||
189 | */ | ||
190 | |||
191 | /* | ||
192 | * Table is already registered. | ||
193 | * We can delete the table that was passed as a parameter. | ||
194 | */ | ||
195 | acpi_tb_delete_table(table_desc); | ||
196 | *table_index = i; | ||
197 | |||
198 | if (acpi_gbl_root_table_list.tables[i]. | ||
199 | flags & ACPI_TABLE_IS_LOADED) { | ||
200 | |||
201 | /* Table is still loaded, this is an error */ | ||
202 | |||
203 | status = AE_ALREADY_EXISTS; | ||
204 | goto release; | ||
205 | } else { | ||
206 | /* Table was unloaded, allow it to be reloaded */ | ||
207 | |||
208 | table_desc->pointer = | ||
209 | acpi_gbl_root_table_list.tables[i].pointer; | ||
210 | table_desc->address = | ||
211 | acpi_gbl_root_table_list.tables[i].address; | ||
212 | status = AE_OK; | ||
213 | goto print_header; | ||
214 | } | ||
215 | } | 150 | } |
216 | |||
217 | /* | ||
218 | * ACPI Table Override: | ||
219 | * Allow the host to override dynamically loaded tables. | ||
220 | * NOTE: the table is fully mapped at this point, and the mapping will | ||
221 | * be deleted by tb_table_override if the table is actually overridden. | ||
222 | */ | ||
223 | (void)acpi_tb_table_override(table_desc->pointer, table_desc); | ||
224 | |||
225 | /* Add the table to the global root table list */ | ||
226 | |||
227 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, | ||
228 | table_desc->length, table_desc->flags, | ||
229 | table_index); | ||
230 | if (ACPI_FAILURE(status)) { | ||
231 | goto release; | ||
232 | } | ||
233 | |||
234 | print_header: | ||
235 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); | ||
236 | |||
237 | release: | ||
238 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
239 | return_ACPI_STATUS(status); | ||
240 | } | 151 | } |
241 | 152 | ||
242 | /******************************************************************************* | 153 | /******************************************************************************* |
243 | * | 154 | * |
244 | * FUNCTION: acpi_tb_table_override | 155 | * FUNCTION: acpi_tb_install_fixed_table |
245 | * | 156 | * |
246 | * PARAMETERS: table_header - Header for the original table | 157 | * PARAMETERS: address - Physical address of DSDT or FACS |
247 | * table_desc - Table descriptor initialized for the | 158 | * signature - Table signature, NULL if no need to |
248 | * original table. May or may not be mapped. | 159 | * match |
160 | * table_index - Index into root table array | ||
249 | * | 161 | * |
250 | * RETURN: Pointer to the entire new table. NULL if table not overridden. | 162 | * RETURN: Status |
251 | * If overridden, installs the new table within the input table | ||
252 | * descriptor. | ||
253 | * | 163 | * |
254 | * DESCRIPTION: Attempt table override by calling the OSL override functions. | 164 | * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data |
255 | * Note: If the table is overridden, then the entire new table | 165 | * structure. |
256 | * is mapped and returned by this function. | ||
257 | * | 166 | * |
258 | ******************************************************************************/ | 167 | ******************************************************************************/ |
259 | 168 | ||
260 | struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header | 169 | acpi_status |
261 | *table_header, | 170 | acpi_tb_install_fixed_table(acpi_physical_address address, |
262 | struct acpi_table_desc | 171 | char *signature, u32 table_index) |
263 | *table_desc) | ||
264 | { | 172 | { |
173 | struct acpi_table_desc new_table_desc; | ||
265 | acpi_status status; | 174 | acpi_status status; |
266 | struct acpi_table_header *new_table = NULL; | ||
267 | acpi_physical_address new_address = 0; | ||
268 | u32 new_table_length = 0; | ||
269 | u8 new_flags; | ||
270 | char *override_type; | ||
271 | 175 | ||
272 | /* (1) Attempt logical override (returns a logical address) */ | 176 | ACPI_FUNCTION_TRACE(tb_install_fixed_table); |
273 | 177 | ||
274 | status = acpi_os_table_override(table_header, &new_table); | 178 | if (!address) { |
275 | if (ACPI_SUCCESS(status) && new_table) { | 179 | ACPI_ERROR((AE_INFO, |
276 | new_address = ACPI_PTR_TO_PHYSADDR(new_table); | 180 | "Null physical address for ACPI table [%s]", |
277 | new_table_length = new_table->length; | 181 | signature)); |
278 | new_flags = ACPI_TABLE_ORIGIN_OVERRIDE; | 182 | return (AE_NO_MEMORY); |
279 | override_type = "Logical"; | ||
280 | goto finish_override; | ||
281 | } | 183 | } |
282 | 184 | ||
283 | /* (2) Attempt physical override (returns a physical address) */ | 185 | /* Fill a table descriptor for validation */ |
284 | 186 | ||
285 | status = acpi_os_physical_table_override(table_header, | 187 | status = acpi_tb_acquire_temp_table(&new_table_desc, address, |
286 | &new_address, | 188 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); |
287 | &new_table_length); | 189 | if (ACPI_FAILURE(status)) { |
288 | if (ACPI_SUCCESS(status) && new_address && new_table_length) { | 190 | ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", |
289 | 191 | ACPI_CAST_PTR(void, address))); | |
290 | /* Map the entire new table */ | 192 | return_ACPI_STATUS(status); |
291 | |||
292 | new_table = acpi_os_map_memory(new_address, new_table_length); | ||
293 | if (!new_table) { | ||
294 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, | ||
295 | "%4.4s " ACPI_PRINTF_UINT | ||
296 | " Attempted physical table override failed", | ||
297 | table_header->signature, | ||
298 | ACPI_FORMAT_TO_UINT(table_desc-> | ||
299 | address))); | ||
300 | return (NULL); | ||
301 | } | ||
302 | |||
303 | override_type = "Physical"; | ||
304 | new_flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
305 | goto finish_override; | ||
306 | } | 193 | } |
307 | 194 | ||
308 | return (NULL); /* There was no override */ | 195 | /* Validate and verify a table before installation */ |
309 | |||
310 | finish_override: | ||
311 | |||
312 | ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT | ||
313 | " %s table override, new table: " ACPI_PRINTF_UINT, | ||
314 | table_header->signature, | ||
315 | ACPI_FORMAT_TO_UINT(table_desc->address), | ||
316 | override_type, ACPI_FORMAT_TO_UINT(new_table))); | ||
317 | 196 | ||
318 | /* We can now unmap/delete the original table (if fully mapped) */ | 197 | status = acpi_tb_verify_table(&new_table_desc, signature); |
198 | if (ACPI_FAILURE(status)) { | ||
199 | goto release_and_exit; | ||
200 | } | ||
319 | 201 | ||
320 | acpi_tb_delete_table(table_desc); | 202 | acpi_tb_install_table_with_override(table_index, &new_table_desc, TRUE); |
321 | 203 | ||
322 | /* Setup descriptor for the new table */ | 204 | release_and_exit: |
323 | 205 | ||
324 | table_desc->address = new_address; | 206 | /* Release the temporary table descriptor */ |
325 | table_desc->pointer = new_table; | ||
326 | table_desc->length = new_table_length; | ||
327 | table_desc->flags = new_flags; | ||
328 | 207 | ||
329 | return (new_table); | 208 | acpi_tb_release_temp_table(&new_table_desc); |
209 | return_ACPI_STATUS(status); | ||
330 | } | 210 | } |
331 | 211 | ||
332 | /******************************************************************************* | 212 | /******************************************************************************* |
333 | * | 213 | * |
334 | * FUNCTION: acpi_tb_resize_root_table_list | 214 | * FUNCTION: acpi_tb_install_standard_table |
335 | * | 215 | * |
336 | * PARAMETERS: None | 216 | * PARAMETERS: address - Address of the table (might be a virtual |
217 | * address depending on the table_flags) | ||
218 | * flags - Flags for the table | ||
219 | * reload - Whether reload should be performed | ||
220 | * override - Whether override should be performed | ||
221 | * table_index - Where the table index is returned | ||
337 | * | 222 | * |
338 | * RETURN: Status | 223 | * RETURN: Status |
339 | * | 224 | * |
340 | * DESCRIPTION: Expand the size of global table array | 225 | * DESCRIPTION: This function is called to install an ACPI table that is |
226 | * neither DSDT nor FACS (a "standard" table.) | ||
227 | * When this function is called by "Load" or "LoadTable" opcodes, | ||
228 | * or by acpi_load_table() API, the "Reload" parameter is set. | ||
229 | * After sucessfully returning from this function, table is | ||
230 | * "INSTALLED" but not "VALIDATED". | ||
341 | * | 231 | * |
342 | ******************************************************************************/ | 232 | ******************************************************************************/ |
343 | 233 | ||
344 | acpi_status acpi_tb_resize_root_table_list(void) | 234 | acpi_status |
235 | acpi_tb_install_standard_table(acpi_physical_address address, | ||
236 | u8 flags, | ||
237 | u8 reload, u8 override, u32 *table_index) | ||
345 | { | 238 | { |
346 | struct acpi_table_desc *tables; | 239 | u32 i; |
347 | u32 table_count; | 240 | acpi_status status = AE_OK; |
348 | 241 | struct acpi_table_desc new_table_desc; | |
349 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); | ||
350 | |||
351 | /* allow_resize flag is a parameter to acpi_initialize_tables */ | ||
352 | 242 | ||
353 | if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { | 243 | ACPI_FUNCTION_TRACE(tb_install_standard_table); |
354 | ACPI_ERROR((AE_INFO, | ||
355 | "Resize of Root Table Array is not allowed")); | ||
356 | return_ACPI_STATUS(AE_SUPPORT); | ||
357 | } | ||
358 | 244 | ||
359 | /* Increase the Table Array size */ | 245 | /* Acquire a temporary table descriptor for validation */ |
360 | 246 | ||
361 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 247 | status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags); |
362 | table_count = acpi_gbl_root_table_list.max_table_count; | 248 | if (ACPI_FAILURE(status)) { |
363 | } else { | 249 | ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", |
364 | table_count = acpi_gbl_root_table_list.current_table_count; | 250 | ACPI_CAST_PTR(void, address))); |
251 | return_ACPI_STATUS(status); | ||
365 | } | 252 | } |
366 | 253 | ||
367 | tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + | 254 | /* |
368 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * | 255 | * Optionally do not load any SSDTs from the RSDT/XSDT. This can |
369 | sizeof(struct acpi_table_desc)); | 256 | * be useful for debugging ACPI problems on some machines. |
370 | if (!tables) { | 257 | */ |
371 | ACPI_ERROR((AE_INFO, | 258 | if (!reload && |
372 | "Could not allocate new root table array")); | 259 | acpi_gbl_disable_ssdt_table_install && |
373 | return_ACPI_STATUS(AE_NO_MEMORY); | 260 | ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) { |
261 | ACPI_INFO((AE_INFO, "Ignoring installation of %4.4s at %p", | ||
262 | new_table_desc.signature.ascii, ACPI_CAST_PTR(void, | ||
263 | address))); | ||
264 | goto release_and_exit; | ||
374 | } | 265 | } |
375 | 266 | ||
376 | /* Copy and free the previous table array */ | 267 | /* Validate and verify a table before installation */ |
377 | |||
378 | if (acpi_gbl_root_table_list.tables) { | ||
379 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, | ||
380 | (acpi_size) table_count * | ||
381 | sizeof(struct acpi_table_desc)); | ||
382 | 268 | ||
383 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 269 | status = acpi_tb_verify_table(&new_table_desc, NULL); |
384 | ACPI_FREE(acpi_gbl_root_table_list.tables); | 270 | if (ACPI_FAILURE(status)) { |
385 | } | 271 | goto release_and_exit; |
386 | } | 272 | } |
387 | 273 | ||
388 | acpi_gbl_root_table_list.tables = tables; | 274 | if (reload) { |
389 | acpi_gbl_root_table_list.max_table_count = | 275 | /* |
390 | table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; | 276 | * Validate the incoming table signature. |
391 | acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; | 277 | * |
392 | 278 | * 1) Originally, we checked the table signature for "SSDT" or "PSDT". | |
393 | return_ACPI_STATUS(AE_OK); | 279 | * 2) We added support for OEMx tables, signature "OEM". |
394 | } | 280 | * 3) Valid tables were encountered with a null signature, so we just |
395 | 281 | * gave up on validating the signature, (05/2008). | |
396 | /******************************************************************************* | 282 | * 4) We encountered non-AML tables such as the MADT, which caused |
397 | * | 283 | * interpreter errors and kernel faults. So now, we once again allow |
398 | * FUNCTION: acpi_tb_store_table | 284 | * only "SSDT", "OEMx", and now, also a null signature. (05/2011). |
399 | * | 285 | */ |
400 | * PARAMETERS: address - Table address | 286 | if ((new_table_desc.signature.ascii[0] != 0x00) && |
401 | * table - Table header | 287 | (!ACPI_COMPARE_NAME |
402 | * length - Table length | 288 | (&new_table_desc.signature, ACPI_SIG_SSDT)) |
403 | * flags - flags | 289 | && (ACPI_STRNCMP(new_table_desc.signature.ascii, "OEM", 3))) |
404 | * | 290 | { |
405 | * RETURN: Status and table index. | 291 | ACPI_BIOS_ERROR((AE_INFO, |
406 | * | 292 | "Table has invalid signature [%4.4s] (0x%8.8X), " |
407 | * DESCRIPTION: Add an ACPI table to the global table list | 293 | "must be SSDT or OEMx", |
408 | * | 294 | acpi_ut_valid_acpi_name(new_table_desc. |
409 | ******************************************************************************/ | 295 | signature. |
296 | ascii) ? | ||
297 | new_table_desc.signature. | ||
298 | ascii : "????", | ||
299 | new_table_desc.signature.integer)); | ||
300 | |||
301 | status = AE_BAD_SIGNATURE; | ||
302 | goto release_and_exit; | ||
303 | } | ||
410 | 304 | ||
411 | acpi_status | 305 | /* Check if table is already registered */ |
412 | acpi_tb_store_table(acpi_physical_address address, | ||
413 | struct acpi_table_header *table, | ||
414 | u32 length, u8 flags, u32 *table_index) | ||
415 | { | ||
416 | acpi_status status; | ||
417 | struct acpi_table_desc *new_table; | ||
418 | 306 | ||
419 | /* Ensure that there is room for the table in the Root Table List */ | 307 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; |
308 | ++i) { | ||
309 | /* | ||
310 | * Check for a table match on the entire table length, | ||
311 | * not just the header. | ||
312 | */ | ||
313 | if (!acpi_tb_compare_tables(&new_table_desc, i)) { | ||
314 | continue; | ||
315 | } | ||
420 | 316 | ||
421 | if (acpi_gbl_root_table_list.current_table_count >= | 317 | /* |
422 | acpi_gbl_root_table_list.max_table_count) { | 318 | * Note: the current mechanism does not unregister a table if it is |
423 | status = acpi_tb_resize_root_table_list(); | 319 | * dynamically unloaded. The related namespace entries are deleted, |
424 | if (ACPI_FAILURE(status)) { | 320 | * but the table remains in the root table list. |
425 | return (status); | 321 | * |
322 | * The assumption here is that the number of different tables that | ||
323 | * will be loaded is actually small, and there is minimal overhead | ||
324 | * in just keeping the table in case it is needed again. | ||
325 | * | ||
326 | * If this assumption changes in the future (perhaps on large | ||
327 | * machines with many table load/unload operations), tables will | ||
328 | * need to be unregistered when they are unloaded, and slots in the | ||
329 | * root table list should be reused when empty. | ||
330 | */ | ||
331 | if (acpi_gbl_root_table_list.tables[i]. | ||
332 | flags & ACPI_TABLE_IS_LOADED) { | ||
333 | |||
334 | /* Table is still loaded, this is an error */ | ||
335 | |||
336 | status = AE_ALREADY_EXISTS; | ||
337 | goto release_and_exit; | ||
338 | } else { | ||
339 | /* | ||
340 | * Table was unloaded, allow it to be reloaded. | ||
341 | * As we are going to return AE_OK to the caller, we should | ||
342 | * take the responsibility of freeing the input descriptor. | ||
343 | * Refill the input descriptor to ensure | ||
344 | * acpi_tb_install_table_with_override() can be called again to | ||
345 | * indicate the re-installation. | ||
346 | */ | ||
347 | acpi_tb_uninstall_table(&new_table_desc); | ||
348 | *table_index = i; | ||
349 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
350 | return_ACPI_STATUS(AE_OK); | ||
351 | } | ||
426 | } | 352 | } |
427 | } | 353 | } |
428 | 354 | ||
429 | new_table = | 355 | /* Add the table to the global root table list */ |
430 | &acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. | ||
431 | current_table_count]; | ||
432 | |||
433 | /* Initialize added table */ | ||
434 | |||
435 | new_table->address = address; | ||
436 | new_table->pointer = table; | ||
437 | new_table->length = length; | ||
438 | new_table->owner_id = 0; | ||
439 | new_table->flags = flags; | ||
440 | |||
441 | ACPI_MOVE_32_TO_32(&new_table->signature, table->signature); | ||
442 | |||
443 | *table_index = acpi_gbl_root_table_list.current_table_count; | ||
444 | acpi_gbl_root_table_list.current_table_count++; | ||
445 | return (AE_OK); | ||
446 | } | ||
447 | |||
448 | /******************************************************************************* | ||
449 | * | ||
450 | * FUNCTION: acpi_tb_delete_table | ||
451 | * | ||
452 | * PARAMETERS: table_index - Table index | ||
453 | * | ||
454 | * RETURN: None | ||
455 | * | ||
456 | * DESCRIPTION: Delete one internal ACPI table | ||
457 | * | ||
458 | ******************************************************************************/ | ||
459 | 356 | ||
460 | void acpi_tb_delete_table(struct acpi_table_desc *table_desc) | 357 | status = acpi_tb_get_next_root_index(&i); |
461 | { | 358 | if (ACPI_FAILURE(status)) { |
462 | /* Table must be mapped or allocated */ | 359 | goto release_and_exit; |
463 | if (!table_desc->pointer) { | ||
464 | return; | ||
465 | } | 360 | } |
466 | switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { | ||
467 | case ACPI_TABLE_ORIGIN_MAPPED: | ||
468 | |||
469 | acpi_os_unmap_memory(table_desc->pointer, table_desc->length); | ||
470 | break; | ||
471 | |||
472 | case ACPI_TABLE_ORIGIN_ALLOCATED: | ||
473 | 361 | ||
474 | ACPI_FREE(table_desc->pointer); | 362 | *table_index = i; |
475 | break; | 363 | acpi_tb_install_table_with_override(i, &new_table_desc, override); |
476 | 364 | ||
477 | /* Not mapped or allocated, there is nothing we can do */ | 365 | release_and_exit: |
478 | 366 | ||
479 | default: | 367 | /* Release the temporary table descriptor */ |
480 | 368 | ||
481 | return; | 369 | acpi_tb_release_temp_table(&new_table_desc); |
482 | } | 370 | return_ACPI_STATUS(status); |
483 | |||
484 | table_desc->pointer = NULL; | ||
485 | } | 371 | } |
486 | 372 | ||
487 | /******************************************************************************* | 373 | /******************************************************************************* |
488 | * | 374 | * |
489 | * FUNCTION: acpi_tb_terminate | 375 | * FUNCTION: acpi_tb_override_table |
490 | * | 376 | * |
491 | * PARAMETERS: None | 377 | * PARAMETERS: old_table_desc - Validated table descriptor to be |
378 | * overridden | ||
492 | * | 379 | * |
493 | * RETURN: None | 380 | * RETURN: None |
494 | * | 381 | * |
495 | * DESCRIPTION: Delete all internal ACPI tables | 382 | * DESCRIPTION: Attempt table override by calling the OSL override functions. |
383 | * Note: If the table is overridden, then the entire new table | ||
384 | * is acquired and returned by this function. | ||
385 | * Before/after invocation, the table descriptor is in a state | ||
386 | * that is "VALIDATED". | ||
496 | * | 387 | * |
497 | ******************************************************************************/ | 388 | ******************************************************************************/ |
498 | 389 | ||
499 | void acpi_tb_terminate(void) | 390 | void acpi_tb_override_table(struct acpi_table_desc *old_table_desc) |
500 | { | 391 | { |
501 | u32 i; | 392 | acpi_status status; |
502 | 393 | char *override_type; | |
503 | ACPI_FUNCTION_TRACE(tb_terminate); | 394 | struct acpi_table_desc new_table_desc; |
504 | 395 | struct acpi_table_header *table; | |
505 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 396 | acpi_physical_address address; |
506 | 397 | u32 length; | |
507 | /* Delete the individual tables */ | ||
508 | 398 | ||
509 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { | 399 | /* (1) Attempt logical override (returns a logical address) */ |
510 | acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); | ||
511 | } | ||
512 | 400 | ||
513 | /* | 401 | status = acpi_os_table_override(old_table_desc->pointer, &table); |
514 | * Delete the root table array if allocated locally. Array cannot be | 402 | if (ACPI_SUCCESS(status) && table) { |
515 | * mapped, so we don't need to check for that flag. | 403 | acpi_tb_acquire_temp_table(&new_table_desc, |
516 | */ | 404 | ACPI_PTR_TO_PHYSADDR(table), |
517 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 405 | ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL); |
518 | ACPI_FREE(acpi_gbl_root_table_list.tables); | 406 | override_type = "Logical"; |
407 | goto finish_override; | ||
519 | } | 408 | } |
520 | 409 | ||
521 | acpi_gbl_root_table_list.tables = NULL; | 410 | /* (2) Attempt physical override (returns a physical address) */ |
522 | acpi_gbl_root_table_list.flags = 0; | ||
523 | acpi_gbl_root_table_list.current_table_count = 0; | ||
524 | 411 | ||
525 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | 412 | status = acpi_os_physical_table_override(old_table_desc->pointer, |
526 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 413 | &address, &length); |
414 | if (ACPI_SUCCESS(status) && address && length) { | ||
415 | acpi_tb_acquire_temp_table(&new_table_desc, address, | ||
416 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); | ||
417 | override_type = "Physical"; | ||
418 | goto finish_override; | ||
419 | } | ||
527 | 420 | ||
528 | return_VOID; | 421 | return; /* There was no override */ |
529 | } | ||
530 | 422 | ||
531 | /******************************************************************************* | 423 | finish_override: |
532 | * | ||
533 | * FUNCTION: acpi_tb_delete_namespace_by_owner | ||
534 | * | ||
535 | * PARAMETERS: table_index - Table index | ||
536 | * | ||
537 | * RETURN: Status | ||
538 | * | ||
539 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. | ||
540 | * | ||
541 | ******************************************************************************/ | ||
542 | |||
543 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) | ||
544 | { | ||
545 | acpi_owner_id owner_id; | ||
546 | acpi_status status; | ||
547 | 424 | ||
548 | ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); | 425 | /* Validate and verify a table before overriding */ |
549 | 426 | ||
550 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 427 | status = acpi_tb_verify_table(&new_table_desc, NULL); |
551 | if (ACPI_FAILURE(status)) { | 428 | if (ACPI_FAILURE(status)) { |
552 | return_ACPI_STATUS(status); | 429 | return; |
553 | } | 430 | } |
554 | 431 | ||
555 | if (table_index >= acpi_gbl_root_table_list.current_table_count) { | 432 | ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT |
556 | 433 | " %s table override, new table: " ACPI_PRINTF_UINT, | |
557 | /* The table index does not exist */ | 434 | old_table_desc->signature.ascii, |
558 | 435 | ACPI_FORMAT_TO_UINT(old_table_desc->address), | |
559 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 436 | override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address))); |
560 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
561 | } | ||
562 | 437 | ||
563 | /* Get the owner ID for this table, used to delete namespace nodes */ | 438 | /* We can now uninstall the original table */ |
564 | 439 | ||
565 | owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; | 440 | acpi_tb_uninstall_table(old_table_desc); |
566 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
567 | 441 | ||
568 | /* | 442 | /* |
569 | * Need to acquire the namespace writer lock to prevent interference | 443 | * Replace the original table descriptor and keep its state as |
570 | * with any concurrent namespace walks. The interpreter must be | 444 | * "VALIDATED". |
571 | * released during the deletion since the acquisition of the deletion | ||
572 | * lock may block, and also since the execution of a namespace walk | ||
573 | * must be allowed to use the interpreter. | ||
574 | */ | 445 | */ |
575 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 446 | acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address, |
576 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | 447 | new_table_desc.flags, |
448 | new_table_desc.pointer); | ||
449 | acpi_tb_validate_table(old_table_desc); | ||
577 | 450 | ||
578 | acpi_ns_delete_namespace_by_owner(owner_id); | 451 | /* Release the temporary table descriptor */ |
579 | if (ACPI_FAILURE(status)) { | ||
580 | return_ACPI_STATUS(status); | ||
581 | } | ||
582 | 452 | ||
583 | acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); | 453 | acpi_tb_release_temp_table(&new_table_desc); |
584 | |||
585 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | ||
586 | return_ACPI_STATUS(status); | ||
587 | } | 454 | } |
588 | 455 | ||
589 | /******************************************************************************* | 456 | /******************************************************************************* |
590 | * | 457 | * |
591 | * FUNCTION: acpi_tb_allocate_owner_id | 458 | * FUNCTION: acpi_tb_store_table |
592 | * | 459 | * |
593 | * PARAMETERS: table_index - Table index | 460 | * PARAMETERS: address - Table address |
461 | * table - Table header | ||
462 | * length - Table length | ||
463 | * flags - Install flags | ||
464 | * table_index - Where the table index is returned | ||
594 | * | 465 | * |
595 | * RETURN: Status | 466 | * RETURN: Status and table index. |
596 | * | 467 | * |
597 | * DESCRIPTION: Allocates owner_id in table_desc | 468 | * DESCRIPTION: Add an ACPI table to the global table list |
598 | * | 469 | * |
599 | ******************************************************************************/ | 470 | ******************************************************************************/ |
600 | 471 | ||
601 | acpi_status acpi_tb_allocate_owner_id(u32 table_index) | 472 | acpi_status |
473 | acpi_tb_store_table(acpi_physical_address address, | ||
474 | struct acpi_table_header * table, | ||
475 | u32 length, u8 flags, u32 *table_index) | ||
602 | { | 476 | { |
603 | acpi_status status = AE_BAD_PARAMETER; | 477 | acpi_status status; |
604 | 478 | struct acpi_table_desc *table_desc; | |
605 | ACPI_FUNCTION_TRACE(tb_allocate_owner_id); | ||
606 | 479 | ||
607 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 480 | status = acpi_tb_get_next_root_index(table_index); |
608 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | 481 | if (ACPI_FAILURE(status)) { |
609 | status = acpi_ut_allocate_owner_id | 482 | return (status); |
610 | (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); | ||
611 | } | 483 | } |
612 | 484 | ||
613 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 485 | /* Initialize added table */ |
614 | return_ACPI_STATUS(status); | ||
615 | } | ||
616 | |||
617 | /******************************************************************************* | ||
618 | * | ||
619 | * FUNCTION: acpi_tb_release_owner_id | ||
620 | * | ||
621 | * PARAMETERS: table_index - Table index | ||
622 | * | ||
623 | * RETURN: Status | ||
624 | * | ||
625 | * DESCRIPTION: Releases owner_id in table_desc | ||
626 | * | ||
627 | ******************************************************************************/ | ||
628 | |||
629 | acpi_status acpi_tb_release_owner_id(u32 table_index) | ||
630 | { | ||
631 | acpi_status status = AE_BAD_PARAMETER; | ||
632 | |||
633 | ACPI_FUNCTION_TRACE(tb_release_owner_id); | ||
634 | |||
635 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
636 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
637 | acpi_ut_release_owner_id(& | ||
638 | (acpi_gbl_root_table_list. | ||
639 | tables[table_index].owner_id)); | ||
640 | status = AE_OK; | ||
641 | } | ||
642 | 486 | ||
643 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 487 | table_desc = &acpi_gbl_root_table_list.tables[*table_index]; |
644 | return_ACPI_STATUS(status); | 488 | acpi_tb_init_table_descriptor(table_desc, address, flags, table); |
489 | table_desc->pointer = table; | ||
490 | return (AE_OK); | ||
645 | } | 491 | } |
646 | 492 | ||
647 | /******************************************************************************* | 493 | /******************************************************************************* |
648 | * | 494 | * |
649 | * FUNCTION: acpi_tb_get_owner_id | 495 | * FUNCTION: acpi_tb_uninstall_table |
650 | * | 496 | * |
651 | * PARAMETERS: table_index - Table index | 497 | * PARAMETERS: table_desc - Table descriptor |
652 | * owner_id - Where the table owner_id is returned | ||
653 | * | 498 | * |
654 | * RETURN: Status | 499 | * RETURN: None |
655 | * | 500 | * |
656 | * DESCRIPTION: returns owner_id for the ACPI table | 501 | * DESCRIPTION: Delete one internal ACPI table |
657 | * | 502 | * |
658 | ******************************************************************************/ | 503 | ******************************************************************************/ |
659 | 504 | ||
660 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id) | 505 | void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc) |
661 | { | 506 | { |
662 | acpi_status status = AE_BAD_PARAMETER; | ||
663 | |||
664 | ACPI_FUNCTION_TRACE(tb_get_owner_id); | ||
665 | 507 | ||
666 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 508 | ACPI_FUNCTION_TRACE(tb_uninstall_table); |
667 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
668 | *owner_id = | ||
669 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
670 | status = AE_OK; | ||
671 | } | ||
672 | 509 | ||
673 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 510 | /* Table must be installed */ |
674 | return_ACPI_STATUS(status); | ||
675 | } | ||
676 | |||
677 | /******************************************************************************* | ||
678 | * | ||
679 | * FUNCTION: acpi_tb_is_table_loaded | ||
680 | * | ||
681 | * PARAMETERS: table_index - Table index | ||
682 | * | ||
683 | * RETURN: Table Loaded Flag | ||
684 | * | ||
685 | ******************************************************************************/ | ||
686 | 511 | ||
687 | u8 acpi_tb_is_table_loaded(u32 table_index) | 512 | if (!table_desc->address) { |
688 | { | 513 | return_VOID; |
689 | u8 is_loaded = FALSE; | ||
690 | |||
691 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
692 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
693 | is_loaded = (u8) | ||
694 | (acpi_gbl_root_table_list.tables[table_index].flags & | ||
695 | ACPI_TABLE_IS_LOADED); | ||
696 | } | 514 | } |
697 | 515 | ||
698 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 516 | acpi_tb_invalidate_table(table_desc); |
699 | return (is_loaded); | ||
700 | } | ||
701 | |||
702 | /******************************************************************************* | ||
703 | * | ||
704 | * FUNCTION: acpi_tb_set_table_loaded_flag | ||
705 | * | ||
706 | * PARAMETERS: table_index - Table index | ||
707 | * is_loaded - TRUE if table is loaded, FALSE otherwise | ||
708 | * | ||
709 | * RETURN: None | ||
710 | * | ||
711 | * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. | ||
712 | * | ||
713 | ******************************************************************************/ | ||
714 | |||
715 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) | ||
716 | { | ||
717 | 517 | ||
718 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 518 | if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == |
719 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | 519 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) { |
720 | if (is_loaded) { | 520 | ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address)); |
721 | acpi_gbl_root_table_list.tables[table_index].flags |= | ||
722 | ACPI_TABLE_IS_LOADED; | ||
723 | } else { | ||
724 | acpi_gbl_root_table_list.tables[table_index].flags &= | ||
725 | ~ACPI_TABLE_IS_LOADED; | ||
726 | } | ||
727 | } | 521 | } |
728 | 522 | ||
729 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 523 | table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL); |
524 | return_VOID; | ||
730 | } | 525 | } |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 9fb85f38de90..e1638ad5db4c 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -178,9 +178,13 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) | |||
178 | } | 178 | } |
179 | 179 | ||
180 | ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); | 180 | ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); |
181 | acpi_tb_delete_table(table_desc); | 181 | acpi_tb_uninstall_table(table_desc); |
182 | table_desc->pointer = new_table; | 182 | |
183 | table_desc->flags = ACPI_TABLE_ORIGIN_ALLOCATED; | 183 | acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list. |
184 | tables[ACPI_TABLE_INDEX_DSDT], | ||
185 | ACPI_PTR_TO_PHYSADDR(new_table), | ||
186 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, | ||
187 | new_table); | ||
184 | 188 | ||
185 | ACPI_INFO((AE_INFO, | 189 | ACPI_INFO((AE_INFO, |
186 | "Forced DSDT copy: length 0x%05X copied locally, original unmapped", | 190 | "Forced DSDT copy: length 0x%05X copied locally, original unmapped", |
@@ -191,116 +195,6 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) | |||
191 | 195 | ||
192 | /******************************************************************************* | 196 | /******************************************************************************* |
193 | * | 197 | * |
194 | * FUNCTION: acpi_tb_install_table | ||
195 | * | ||
196 | * PARAMETERS: address - Physical address of DSDT or FACS | ||
197 | * signature - Table signature, NULL if no need to | ||
198 | * match | ||
199 | * table_index - Index into root table array | ||
200 | * | ||
201 | * RETURN: None | ||
202 | * | ||
203 | * DESCRIPTION: Install an ACPI table into the global data structure. The | ||
204 | * table override mechanism is called to allow the host | ||
205 | * OS to replace any table before it is installed in the root | ||
206 | * table array. | ||
207 | * | ||
208 | ******************************************************************************/ | ||
209 | |||
210 | void | ||
211 | acpi_tb_install_table(acpi_physical_address address, | ||
212 | char *signature, u32 table_index) | ||
213 | { | ||
214 | struct acpi_table_header *table; | ||
215 | struct acpi_table_header *final_table; | ||
216 | struct acpi_table_desc *table_desc; | ||
217 | |||
218 | if (!address) { | ||
219 | ACPI_ERROR((AE_INFO, | ||
220 | "Null physical address for ACPI table [%s]", | ||
221 | signature)); | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | /* Map just the table header */ | ||
226 | |||
227 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | ||
228 | if (!table) { | ||
229 | ACPI_ERROR((AE_INFO, | ||
230 | "Could not map memory for table [%s] at %p", | ||
231 | signature, ACPI_CAST_PTR(void, address))); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | /* If a particular signature is expected (DSDT/FACS), it must match */ | ||
236 | |||
237 | if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { | ||
238 | ACPI_BIOS_ERROR((AE_INFO, | ||
239 | "Invalid signature 0x%X for ACPI table, expected [%s]", | ||
240 | *ACPI_CAST_PTR(u32, table->signature), | ||
241 | signature)); | ||
242 | goto unmap_and_exit; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Initialize the table entry. Set the pointer to NULL, since the | ||
247 | * table is not fully mapped at this time. | ||
248 | */ | ||
249 | table_desc = &acpi_gbl_root_table_list.tables[table_index]; | ||
250 | |||
251 | table_desc->address = address; | ||
252 | table_desc->pointer = NULL; | ||
253 | table_desc->length = table->length; | ||
254 | table_desc->flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
255 | ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); | ||
256 | |||
257 | /* | ||
258 | * ACPI Table Override: | ||
259 | * | ||
260 | * Before we install the table, let the host OS override it with a new | ||
261 | * one if desired. Any table within the RSDT/XSDT can be replaced, | ||
262 | * including the DSDT which is pointed to by the FADT. | ||
263 | * | ||
264 | * NOTE: If the table is overridden, then final_table will contain a | ||
265 | * mapped pointer to the full new table. If the table is not overridden, | ||
266 | * or if there has been a physical override, then the table will be | ||
267 | * fully mapped later (in verify table). In any case, we must | ||
268 | * unmap the header that was mapped above. | ||
269 | */ | ||
270 | final_table = acpi_tb_table_override(table, table_desc); | ||
271 | if (!final_table) { | ||
272 | final_table = table; /* There was no override */ | ||
273 | } | ||
274 | |||
275 | acpi_tb_print_table_header(table_desc->address, final_table); | ||
276 | |||
277 | /* Set the global integer width (based upon revision of the DSDT) */ | ||
278 | |||
279 | if (table_index == ACPI_TABLE_INDEX_DSDT) { | ||
280 | acpi_ut_set_integer_width(final_table->revision); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * If we have a physical override during this early loading of the ACPI | ||
285 | * tables, unmap the table for now. It will be mapped again later when | ||
286 | * it is actually used. This supports very early loading of ACPI tables, | ||
287 | * before virtual memory is fully initialized and running within the | ||
288 | * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE | ||
289 | * flag set and will not be deleted below. | ||
290 | */ | ||
291 | if (final_table != table) { | ||
292 | acpi_tb_delete_table(table_desc); | ||
293 | } | ||
294 | |||
295 | unmap_and_exit: | ||
296 | |||
297 | /* Always unmap the table header that we mapped above */ | ||
298 | |||
299 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
300 | } | ||
301 | |||
302 | /******************************************************************************* | ||
303 | * | ||
304 | * FUNCTION: acpi_tb_get_root_table_entry | 198 | * FUNCTION: acpi_tb_get_root_table_entry |
305 | * | 199 | * |
306 | * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry | 200 | * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry |
@@ -465,6 +359,7 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
465 | u32 length; | 359 | u32 length; |
466 | u8 *table_entry; | 360 | u8 *table_entry; |
467 | acpi_status status; | 361 | acpi_status status; |
362 | u32 table_index; | ||
468 | 363 | ||
469 | ACPI_FUNCTION_TRACE(tb_parse_root_table); | 364 | ACPI_FUNCTION_TRACE(tb_parse_root_table); |
470 | 365 | ||
@@ -576,31 +471,24 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
576 | /* Initialize the root table array from the RSDT/XSDT */ | 471 | /* Initialize the root table array from the RSDT/XSDT */ |
577 | 472 | ||
578 | for (i = 0; i < table_count; i++) { | 473 | for (i = 0; i < table_count; i++) { |
579 | if (acpi_gbl_root_table_list.current_table_count >= | ||
580 | acpi_gbl_root_table_list.max_table_count) { | ||
581 | |||
582 | /* There is no more room in the root table array, attempt resize */ | ||
583 | |||
584 | status = acpi_tb_resize_root_table_list(); | ||
585 | if (ACPI_FAILURE(status)) { | ||
586 | ACPI_WARNING((AE_INFO, | ||
587 | "Truncating %u table entries!", | ||
588 | (unsigned) (table_count - | ||
589 | (acpi_gbl_root_table_list. | ||
590 | current_table_count - | ||
591 | 2)))); | ||
592 | break; | ||
593 | } | ||
594 | } | ||
595 | 474 | ||
596 | /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ | 475 | /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ |
597 | 476 | ||
598 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. | 477 | status = |
599 | current_table_count].address = | 478 | acpi_tb_install_standard_table(acpi_tb_get_root_table_entry |
600 | acpi_tb_get_root_table_entry(table_entry, table_entry_size); | 479 | (table_entry, |
480 | table_entry_size), | ||
481 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, | ||
482 | FALSE, TRUE, &table_index); | ||
483 | |||
484 | if (ACPI_SUCCESS(status) && | ||
485 | ACPI_COMPARE_NAME(&acpi_gbl_root_table_list. | ||
486 | tables[table_index].signature, | ||
487 | ACPI_SIG_FADT)) { | ||
488 | acpi_tb_parse_fadt(table_index); | ||
489 | } | ||
601 | 490 | ||
602 | table_entry += table_entry_size; | 491 | table_entry += table_entry_size; |
603 | acpi_gbl_root_table_list.current_table_count++; | ||
604 | } | 492 | } |
605 | 493 | ||
606 | /* | 494 | /* |
@@ -609,22 +497,5 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
609 | */ | 497 | */ |
610 | acpi_os_unmap_memory(table, length); | 498 | acpi_os_unmap_memory(table, length); |
611 | 499 | ||
612 | /* | ||
613 | * Complete the initialization of the root table array by examining | ||
614 | * the header of each table | ||
615 | */ | ||
616 | for (i = 2; i < acpi_gbl_root_table_list.current_table_count; i++) { | ||
617 | acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. | ||
618 | address, NULL, i); | ||
619 | |||
620 | /* Special case for FADT - validate it then get the DSDT and FACS */ | ||
621 | |||
622 | if (ACPI_COMPARE_NAME | ||
623 | (&acpi_gbl_root_table_list.tables[i].signature, | ||
624 | ACPI_SIG_FADT)) { | ||
625 | acpi_tb_parse_fadt(i); | ||
626 | } | ||
627 | } | ||
628 | |||
629 | return_ACPI_STATUS(AE_OK); | 500 | return_ACPI_STATUS(AE_OK); |
630 | } | 501 | } |
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index a1593159d9ea..6482b0ded652 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -206,8 +206,8 @@ acpi_status | |||
206 | acpi_get_table_header(char *signature, | 206 | acpi_get_table_header(char *signature, |
207 | u32 instance, struct acpi_table_header *out_table_header) | 207 | u32 instance, struct acpi_table_header *out_table_header) |
208 | { | 208 | { |
209 | u32 i; | 209 | u32 i; |
210 | u32 j; | 210 | u32 j; |
211 | struct acpi_table_header *header; | 211 | struct acpi_table_header *header; |
212 | 212 | ||
213 | /* Parameter validation */ | 213 | /* Parameter validation */ |
@@ -233,7 +233,7 @@ acpi_get_table_header(char *signature, | |||
233 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | 233 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
234 | if ((acpi_gbl_root_table_list.tables[i].flags & | 234 | if ((acpi_gbl_root_table_list.tables[i].flags & |
235 | ACPI_TABLE_ORIGIN_MASK) == | 235 | ACPI_TABLE_ORIGIN_MASK) == |
236 | ACPI_TABLE_ORIGIN_MAPPED) { | 236 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) { |
237 | header = | 237 | header = |
238 | acpi_os_map_memory(acpi_gbl_root_table_list. | 238 | acpi_os_map_memory(acpi_gbl_root_table_list. |
239 | tables[i].address, | 239 | tables[i].address, |
@@ -321,8 +321,8 @@ acpi_get_table_with_size(char *signature, | |||
321 | u32 instance, struct acpi_table_header **out_table, | 321 | u32 instance, struct acpi_table_header **out_table, |
322 | acpi_size *tbl_size) | 322 | acpi_size *tbl_size) |
323 | { | 323 | { |
324 | u32 i; | 324 | u32 i; |
325 | u32 j; | 325 | u32 j; |
326 | acpi_status status; | 326 | acpi_status status; |
327 | 327 | ||
328 | /* Parameter validation */ | 328 | /* Parameter validation */ |
@@ -346,7 +346,7 @@ acpi_get_table_with_size(char *signature, | |||
346 | } | 346 | } |
347 | 347 | ||
348 | status = | 348 | status = |
349 | acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); | 349 | acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]); |
350 | if (ACPI_SUCCESS(status)) { | 350 | if (ACPI_SUCCESS(status)) { |
351 | *out_table = acpi_gbl_root_table_list.tables[i].pointer; | 351 | *out_table = acpi_gbl_root_table_list.tables[i].pointer; |
352 | *tbl_size = acpi_gbl_root_table_list.tables[i].length; | 352 | *tbl_size = acpi_gbl_root_table_list.tables[i].length; |
@@ -390,7 +390,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table) | |||
390 | * | 390 | * |
391 | ******************************************************************************/ | 391 | ******************************************************************************/ |
392 | acpi_status | 392 | acpi_status |
393 | acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) | 393 | acpi_get_table_by_index(u32 table_index, struct acpi_table_header ** table) |
394 | { | 394 | { |
395 | acpi_status status; | 395 | acpi_status status; |
396 | 396 | ||
@@ -416,8 +416,8 @@ acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) | |||
416 | /* Table is not mapped, map it */ | 416 | /* Table is not mapped, map it */ |
417 | 417 | ||
418 | status = | 418 | status = |
419 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | 419 | acpi_tb_validate_table(&acpi_gbl_root_table_list. |
420 | tables[table_index]); | 420 | tables[table_index]); |
421 | if (ACPI_FAILURE(status)) { | 421 | if (ACPI_FAILURE(status)) { |
422 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 422 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
423 | return_ACPI_STATUS(status); | 423 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 0909420fc776..ab5308b81aa8 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c | |||
@@ -117,7 +117,7 @@ static acpi_status acpi_tb_load_namespace(void) | |||
117 | tables[ACPI_TABLE_INDEX_DSDT].signature), | 117 | tables[ACPI_TABLE_INDEX_DSDT].signature), |
118 | ACPI_SIG_DSDT) | 118 | ACPI_SIG_DSDT) |
119 | || | 119 | || |
120 | ACPI_FAILURE(acpi_tb_verify_table | 120 | ACPI_FAILURE(acpi_tb_validate_table |
121 | (&acpi_gbl_root_table_list. | 121 | (&acpi_gbl_root_table_list. |
122 | tables[ACPI_TABLE_INDEX_DSDT]))) { | 122 | tables[ACPI_TABLE_INDEX_DSDT]))) { |
123 | status = AE_NO_ACPI_TABLES; | 123 | status = AE_NO_ACPI_TABLES; |
@@ -128,7 +128,7 @@ static acpi_status acpi_tb_load_namespace(void) | |||
128 | * Save the DSDT pointer for simple access. This is the mapped memory | 128 | * Save the DSDT pointer for simple access. This is the mapped memory |
129 | * address. We must take care here because the address of the .Tables | 129 | * address. We must take care here because the address of the .Tables |
130 | * array can change dynamically as tables are loaded at run-time. Note: | 130 | * array can change dynamically as tables are loaded at run-time. Note: |
131 | * .Pointer field is not validated until after call to acpi_tb_verify_table. | 131 | * .Pointer field is not validated until after call to acpi_tb_validate_table. |
132 | */ | 132 | */ |
133 | acpi_gbl_DSDT = | 133 | acpi_gbl_DSDT = |
134 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; | 134 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; |
@@ -174,24 +174,11 @@ static acpi_status acpi_tb_load_namespace(void) | |||
174 | (acpi_gbl_root_table_list.tables[i]. | 174 | (acpi_gbl_root_table_list.tables[i]. |
175 | signature), ACPI_SIG_PSDT)) | 175 | signature), ACPI_SIG_PSDT)) |
176 | || | 176 | || |
177 | ACPI_FAILURE(acpi_tb_verify_table | 177 | ACPI_FAILURE(acpi_tb_validate_table |
178 | (&acpi_gbl_root_table_list.tables[i]))) { | 178 | (&acpi_gbl_root_table_list.tables[i]))) { |
179 | continue; | 179 | continue; |
180 | } | 180 | } |
181 | 181 | ||
182 | /* | ||
183 | * Optionally do not load any SSDTs from the RSDT/XSDT. This can | ||
184 | * be useful for debugging ACPI problems on some machines. | ||
185 | */ | ||
186 | if (acpi_gbl_disable_ssdt_table_load) { | ||
187 | ACPI_INFO((AE_INFO, "Ignoring %4.4s at %p", | ||
188 | acpi_gbl_root_table_list.tables[i].signature. | ||
189 | ascii, ACPI_CAST_PTR(void, | ||
190 | acpi_gbl_root_table_list. | ||
191 | tables[i].address))); | ||
192 | continue; | ||
193 | } | ||
194 | |||
195 | /* Ignore errors while loading tables, get as many as possible */ | 182 | /* Ignore errors while loading tables, get as many as possible */ |
196 | 183 | ||
197 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 184 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
@@ -208,6 +195,45 @@ unlock_and_exit: | |||
208 | 195 | ||
209 | /******************************************************************************* | 196 | /******************************************************************************* |
210 | * | 197 | * |
198 | * FUNCTION: acpi_install_table | ||
199 | * | ||
200 | * PARAMETERS: address - Address of the ACPI table to be installed. | ||
201 | * physical - Whether the address is a physical table | ||
202 | * address or not | ||
203 | * | ||
204 | * RETURN: Status | ||
205 | * | ||
206 | * DESCRIPTION: Dynamically install an ACPI table. | ||
207 | * Note: This function should only be invoked after | ||
208 | * acpi_initialize_tables() and before acpi_load_tables(). | ||
209 | * | ||
210 | ******************************************************************************/ | ||
211 | |||
212 | acpi_status __init | ||
213 | acpi_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 | |||
233 | ACPI_EXPORT_SYMBOL_INIT(acpi_install_table) | ||
234 | |||
235 | /******************************************************************************* | ||
236 | * | ||
211 | * FUNCTION: acpi_load_table | 237 | * FUNCTION: acpi_load_table |
212 | * | 238 | * |
213 | * PARAMETERS: table - Pointer to a buffer containing the ACPI | 239 | * PARAMETERS: table - Pointer to a buffer containing the ACPI |
@@ -222,11 +248,9 @@ unlock_and_exit: | |||
222 | * to ensure that the table is not deleted or unmapped. | 248 | * to ensure that the table is not deleted or unmapped. |
223 | * | 249 | * |
224 | ******************************************************************************/ | 250 | ******************************************************************************/ |
225 | |||
226 | acpi_status acpi_load_table(struct acpi_table_header *table) | 251 | acpi_status acpi_load_table(struct acpi_table_header *table) |
227 | { | 252 | { |
228 | acpi_status status; | 253 | acpi_status status; |
229 | struct acpi_table_desc table_desc; | ||
230 | u32 table_index; | 254 | u32 table_index; |
231 | 255 | ||
232 | ACPI_FUNCTION_TRACE(acpi_load_table); | 256 | ACPI_FUNCTION_TRACE(acpi_load_table); |
@@ -237,14 +261,6 @@ acpi_status acpi_load_table(struct acpi_table_header *table) | |||
237 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 261 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
238 | } | 262 | } |
239 | 263 | ||
240 | /* Init local table descriptor */ | ||
241 | |||
242 | ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); | ||
243 | table_desc.address = ACPI_PTR_TO_PHYSADDR(table); | ||
244 | table_desc.pointer = table; | ||
245 | table_desc.length = table->length; | ||
246 | table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; | ||
247 | |||
248 | /* Must acquire the interpreter lock during this operation */ | 264 | /* Must acquire the interpreter lock during this operation */ |
249 | 265 | ||
250 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | 266 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); |
@@ -255,7 +271,24 @@ acpi_status acpi_load_table(struct acpi_table_header *table) | |||
255 | /* Install the table and load it into the namespace */ | 271 | /* Install the table and load it into the namespace */ |
256 | 272 | ||
257 | ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); | 273 | ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); |
258 | status = acpi_tb_add_table(&table_desc, &table_index); | 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 | * Note: Now table is "INSTALLED", it must be validated before | ||
287 | * using. | ||
288 | */ | ||
289 | status = | ||
290 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | ||
291 | tables[table_index]); | ||
259 | if (ACPI_FAILURE(status)) { | 292 | if (ACPI_FAILURE(status)) { |
260 | goto unlock_and_exit; | 293 | goto unlock_and_exit; |
261 | } | 294 | } |
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index fbfa9eca011f..90ec37c473c6 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -462,7 +462,7 @@ char *acpi_ut_get_mutex_name(u32 mutex_id) | |||
462 | 462 | ||
463 | /* Names for Notify() values, used for debug output */ | 463 | /* Names for Notify() values, used for debug output */ |
464 | 464 | ||
465 | static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { | 465 | static const char *acpi_gbl_generic_notify[ACPI_NOTIFY_MAX + 1] = { |
466 | /* 00 */ "Bus Check", | 466 | /* 00 */ "Bus Check", |
467 | /* 01 */ "Device Check", | 467 | /* 01 */ "Device Check", |
468 | /* 02 */ "Device Wake", | 468 | /* 02 */ "Device Wake", |
@@ -473,23 +473,75 @@ static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { | |||
473 | /* 07 */ "Power Fault", | 473 | /* 07 */ "Power Fault", |
474 | /* 08 */ "Capabilities Check", | 474 | /* 08 */ "Capabilities Check", |
475 | /* 09 */ "Device PLD Check", | 475 | /* 09 */ "Device PLD Check", |
476 | /* 10 */ "Reserved", | 476 | /* 0A */ "Reserved", |
477 | /* 11 */ "System Locality Update", | 477 | /* 0B */ "System Locality Update", |
478 | /* 12 */ "Shutdown Request" | 478 | /* 0C */ "Shutdown Request" |
479 | }; | 479 | }; |
480 | 480 | ||
481 | const char *acpi_ut_get_notify_name(u32 notify_value) | 481 | static const char *acpi_gbl_device_notify[4] = { |
482 | /* 80 */ "Status Change", | ||
483 | /* 81 */ "Information Change", | ||
484 | /* 82 */ "Device-Specific Change", | ||
485 | /* 83 */ "Device-Specific Change" | ||
486 | }; | ||
487 | |||
488 | static const char *acpi_gbl_processor_notify[4] = { | ||
489 | /* 80 */ "Performance Capability Change", | ||
490 | /* 81 */ "C-State Change", | ||
491 | /* 82 */ "Throttling Capability Change", | ||
492 | /* 83 */ "Device-Specific Change" | ||
493 | }; | ||
494 | |||
495 | static const char *acpi_gbl_thermal_notify[4] = { | ||
496 | /* 80 */ "Thermal Status Change", | ||
497 | /* 81 */ "Thermal Trip Point Change", | ||
498 | /* 82 */ "Thermal Device List Change", | ||
499 | /* 83 */ "Thermal Relationship Change" | ||
500 | }; | ||
501 | |||
502 | const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type) | ||
482 | { | 503 | { |
483 | 504 | ||
505 | /* 00 - 0C are common to all object types */ | ||
506 | |||
484 | if (notify_value <= ACPI_NOTIFY_MAX) { | 507 | if (notify_value <= ACPI_NOTIFY_MAX) { |
485 | return (acpi_gbl_notify_value_names[notify_value]); | 508 | return (acpi_gbl_generic_notify[notify_value]); |
486 | } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | 509 | } |
510 | |||
511 | /* 0D - 7F are reserved */ | ||
512 | |||
513 | if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | ||
487 | return ("Reserved"); | 514 | return ("Reserved"); |
488 | } else if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) { | ||
489 | return ("Device Specific"); | ||
490 | } else { | ||
491 | return ("Hardware Specific"); | ||
492 | } | 515 | } |
516 | |||
517 | /* 80 - 83 are per-object-type */ | ||
518 | |||
519 | if (notify_value <= 0x83) { | ||
520 | switch (type) { | ||
521 | case ACPI_TYPE_ANY: | ||
522 | case ACPI_TYPE_DEVICE: | ||
523 | return (acpi_gbl_device_notify[notify_value - 0x80]); | ||
524 | |||
525 | case ACPI_TYPE_PROCESSOR: | ||
526 | return (acpi_gbl_processor_notify[notify_value - 0x80]); | ||
527 | |||
528 | case ACPI_TYPE_THERMAL: | ||
529 | return (acpi_gbl_thermal_notify[notify_value - 0x80]); | ||
530 | |||
531 | default: | ||
532 | return ("Target object type does not support notifies"); | ||
533 | } | ||
534 | } | ||
535 | |||
536 | /* 84 - BF are device-specific */ | ||
537 | |||
538 | if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) { | ||
539 | return ("Device-Specific"); | ||
540 | } | ||
541 | |||
542 | /* C0 and above are hardware-specific */ | ||
543 | |||
544 | return ("Hardware-Specific"); | ||
493 | } | 545 | } |
494 | #endif | 546 | #endif |
495 | 547 | ||
diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index 77219336c7e0..6dc54b3c28b0 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c | |||
@@ -353,7 +353,7 @@ void acpi_ut_print_string(char *string, u16 max_length) | |||
353 | } | 353 | } |
354 | 354 | ||
355 | acpi_os_printf("\""); | 355 | acpi_os_printf("\""); |
356 | for (i = 0; string[i] && (i < max_length); i++) { | 356 | for (i = 0; (i < max_length) && string[i]; i++) { |
357 | 357 | ||
358 | /* Escape sequences */ | 358 | /* Escape sequences */ |
359 | 359 | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6776c599816f..9aeae41e22fb 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -1770,16 +1770,15 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) | |||
1770 | } | 1770 | } |
1771 | #endif | 1771 | #endif |
1772 | 1772 | ||
1773 | static int __init acpi_no_auto_ssdt_setup(char *s) | 1773 | static int __init acpi_no_static_ssdt_setup(char *s) |
1774 | { | 1774 | { |
1775 | printk(KERN_NOTICE PREFIX "SSDT auto-load disabled\n"); | 1775 | acpi_gbl_disable_ssdt_table_install = TRUE; |
1776 | pr_info("ACPI: static SSDT installation disabled\n"); | ||
1776 | 1777 | ||
1777 | acpi_gbl_disable_ssdt_table_load = TRUE; | 1778 | return 0; |
1778 | |||
1779 | return 1; | ||
1780 | } | 1779 | } |
1781 | 1780 | ||
1782 | __setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup); | 1781 | early_param("acpi_no_static_ssdt", acpi_no_static_ssdt_setup); |
1783 | 1782 | ||
1784 | static int __init acpi_disable_return_repair(char *s) | 1783 | static int __init acpi_disable_return_repair(char *s) |
1785 | { | 1784 | { |