aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables/tbxface.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/tables/tbxface.c')
-rw-r--r--drivers/acpi/tables/tbxface.c620
1 files changed, 351 insertions, 269 deletions
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 5ba9303293ad..77439fc36c32 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -49,80 +49,146 @@
49#define _COMPONENT ACPI_TABLES 49#define _COMPONENT ACPI_TABLES
50ACPI_MODULE_NAME("tbxface") 50ACPI_MODULE_NAME("tbxface")
51 51
52/* Local prototypes */
53static acpi_status acpi_tb_load_namespace(void);
54
52/******************************************************************************* 55/*******************************************************************************
53 * 56 *
54 * FUNCTION: acpi_load_tables 57 * FUNCTION: acpi_initialize_tables
55 * 58 *
56 * PARAMETERS: None 59 * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated
60 * struct acpi_table_desc structures. If NULL, the
61 * array is dynamically allocated.
62 * initial_table_count - Size of initial_table_array, in number of
63 * struct acpi_table_desc structures
64 * allow_realloc - Flag to tell Table Manager if resize of
65 * pre-allocated array is allowed. Ignored
66 * if initial_table_array is NULL.
57 * 67 *
58 * RETURN: Status 68 * RETURN: Status
59 * 69 *
60 * DESCRIPTION: This function is called to load the ACPI tables from the 70 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
61 * provided RSDT 71 *
72 * NOTE: Allows static allocation of the initial table array in order
73 * to avoid the use of dynamic memory in confined environments
74 * such as the kernel boot sequence where it may not be available.
75 *
76 * If the host OS memory managers are initialized, use NULL for
77 * initial_table_array, and the table will be dynamically allocated.
62 * 78 *
63 ******************************************************************************/ 79 ******************************************************************************/
64acpi_status acpi_load_tables(void) 80
81acpi_status
82acpi_initialize_tables(struct acpi_table_desc *initial_table_array,
83 u32 initial_table_count, u8 allow_resize)
65{ 84{
66 struct acpi_pointer rsdp_address; 85 acpi_physical_address address;
67 acpi_status status; 86 acpi_status status;
87 struct acpi_table_rsdp *rsdp;
68 88
69 ACPI_FUNCTION_TRACE(acpi_load_tables); 89 ACPI_FUNCTION_TRACE(acpi_initialize_tables);
70 90
71 /* Get the RSDP */ 91 /*
92 * Set up the Root Table Array
93 * Allocate the table array if requested
94 */
95 if (!initial_table_array) {
96 acpi_gbl_root_table_list.size = initial_table_count;
97 acpi_gbl_root_table_list.flags = ACPI_TABLE_FLAGS_ALLOW_RESIZE;
72 98
73 status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING, 99 status = acpi_tb_resize_root_table_list();
74 &rsdp_address); 100 if (ACPI_FAILURE(status)) {
75 if (ACPI_FAILURE(status)) { 101 return_ACPI_STATUS(status);
76 ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP")); 102 }
77 goto error_exit; 103 } else {
104 /* Root Table Array has been statically allocated by the host */
105
106 acpi_gbl_root_table_list.tables = initial_table_array;
107 acpi_gbl_root_table_list.size = initial_table_count;
108 acpi_gbl_root_table_list.flags = ACPI_TABLE_ORIGIN_UNKNOWN;
109 if (allow_resize) {
110 acpi_gbl_root_table_list.flags =
111 ACPI_TABLE_FLAGS_ALLOW_RESIZE;
112 }
78 } 113 }
79 114
80 /* Map and validate the RSDP */ 115 /* Get the RSDP and map it */
81 116
82 acpi_gbl_table_flags = rsdp_address.pointer_type; 117 address = acpi_os_get_root_pointer();
118 if (!address) {
119 return_ACPI_STATUS(AE_NOT_FOUND);
120 }
83 121
84 status = acpi_tb_verify_rsdp(&rsdp_address); 122 rsdp = acpi_os_map_memory(address, sizeof(struct acpi_table_rsdp));
85 if (ACPI_FAILURE(status)) { 123 if (!rsdp) {
86 ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation")); 124 return_ACPI_STATUS(AE_NO_MEMORY);
87 goto error_exit;
88 } 125 }
89 126
90 /* Get the RSDT via the RSDP */ 127 ACPI_INFO((AE_INFO, "%.8s @ 0x%p",
128 rsdp->signature, ACPI_CAST_PTR(void, address)));
91 129
92 status = acpi_tb_get_table_rsdt(); 130 /*
93 if (ACPI_FAILURE(status)) { 131 * Get the root table (RSDT or XSDT) and extract all entries to the local
94 ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT")); 132 * Root Table Array. This array contains the information of the RSDT/XSDT
95 goto error_exit; 133 * in a common, more useable format.
96 } 134 */
135 status = acpi_tb_parse_root_table(rsdp, ACPI_TABLE_ORIGIN_MAPPED);
136 acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
137 return_ACPI_STATUS(status);
138}
97 139
98 /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */ 140ACPI_EXPORT_SYMBOL(acpi_initialize_tables)
99 141
100 status = acpi_tb_get_required_tables(); 142/*******************************************************************************
101 if (ACPI_FAILURE(status)) { 143 *
102 ACPI_EXCEPTION((AE_INFO, status, 144 * FUNCTION: acpi_reallocate_root_table
103 "Could not get all required tables (DSDT/FADT/FACS)")); 145 *
104 goto error_exit; 146 * PARAMETERS: None
147 *
148 * RETURN: Status
149 *
150 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
151 * root list from the previously provided scratch area. Should
152 * be called once dynamic memory allocation is available in the
153 * kernel
154 *
155 ******************************************************************************/
156acpi_status acpi_reallocate_root_table(void)
157{
158 struct acpi_table_desc *tables;
159 acpi_size new_size;
160
161 ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
162
163 /*
164 * Only reallocate the root table if the host provided a static buffer
165 * for the table array in the call to acpi_initialize_tables.
166 */
167 if ((acpi_gbl_root_table_list.flags & ACPI_TABLE_ORIGIN_MASK) !=
168 ACPI_TABLE_ORIGIN_UNKNOWN) {
169 return_ACPI_STATUS(AE_SUPPORT);
105 } 170 }
106 171
107 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); 172 new_size =
173 (acpi_gbl_root_table_list.count +
174 ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc);
108 175
109 /* Load the namespace from the tables */ 176 /* Create new array and copy the old array */
110 177
111 status = acpi_ns_load_namespace(); 178 tables = ACPI_ALLOCATE_ZEROED(new_size);
112 if (ACPI_FAILURE(status)) { 179 if (!tables) {
113 ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace")); 180 return_ACPI_STATUS(AE_NO_MEMORY);
114 goto error_exit;
115 } 181 }
116 182
117 return_ACPI_STATUS(AE_OK); 183 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size);
118 184
119 error_exit: 185 acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count;
120 ACPI_EXCEPTION((AE_INFO, status, "Could not load tables")); 186 acpi_gbl_root_table_list.tables = tables;
121 return_ACPI_STATUS(status); 187 acpi_gbl_root_table_list.flags =
122} 188 ACPI_TABLE_ORIGIN_ALLOCATED | ACPI_TABLE_FLAGS_ALLOW_RESIZE;
123
124ACPI_EXPORT_SYMBOL(acpi_load_tables)
125 189
190 return_ACPI_STATUS(AE_OK);
191}
126/******************************************************************************* 192/*******************************************************************************
127 * 193 *
128 * FUNCTION: acpi_load_table 194 * FUNCTION: acpi_load_table
@@ -141,342 +207,358 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables)
141acpi_status acpi_load_table(struct acpi_table_header *table_ptr) 207acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
142{ 208{
143 acpi_status status; 209 acpi_status status;
144 struct acpi_table_desc table_info; 210 acpi_native_uint table_index;
145 struct acpi_pointer address;
146
147 ACPI_FUNCTION_TRACE(acpi_load_table);
148
149 if (!table_ptr) {
150 return_ACPI_STATUS(AE_BAD_PARAMETER);
151 }
152 211
153 /* Copy the table to a local buffer */ 212 /*
154 213 * Install the new table into the local data structures
155 address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; 214 */
156 address.pointer.logical = table_ptr; 215 status = acpi_tb_add_table(table_ptr, &table_index);
157
158 status = acpi_tb_get_table_body(&address, table_ptr, &table_info);
159 if (ACPI_FAILURE(status)) {
160 return_ACPI_STATUS(status);
161 }
162
163 /* Check signature for a valid table type */
164
165 status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL);
166 if (ACPI_FAILURE(status)) { 216 if (ACPI_FAILURE(status)) {
167 return_ACPI_STATUS(status); 217 return_ACPI_STATUS(status);
168 } 218 }
219 status = acpi_ns_load_table(table_index, acpi_gbl_root_node);
220 return_ACPI_STATUS(status);
221}
169 222
170 /* Install the new table into the local data structures */ 223ACPI_EXPORT_SYMBOL(acpi_load_table)
171
172 status = acpi_tb_install_table(&table_info);
173 if (ACPI_FAILURE(status)) {
174 if (status == AE_ALREADY_EXISTS) {
175 224
176 /* Table already exists, no error */ 225/******************************************************************************
226 *
227 * FUNCTION: acpi_get_table_header
228 *
229 * PARAMETERS: Signature - ACPI signature of needed table
230 * Instance - Which instance (for SSDTs)
231 * out_table_header - Where the pointer to the table header
232 * is returned
233 *
234 * RETURN: Status and pointer to mapped table header
235 *
236 * DESCRIPTION: Finds an ACPI table header.
237 *
238 * NOTE: Caller is responsible in unmapping the header with
239 * acpi_os_unmap_memory
240 *
241 *****************************************************************************/
242acpi_status
243acpi_get_table_header(char *signature,
244 acpi_native_uint instance,
245 struct acpi_table_header **out_table_header)
246{
247 acpi_native_uint i;
248 acpi_native_uint j;
177 249
178 status = AE_OK; 250 /*
251 * Walk the root table list
252 */
253 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
254 if (!ACPI_COMPARE_NAME
255 (&(acpi_gbl_root_table_list.tables[i].signature),
256 signature)) {
257 continue;
179 } 258 }
180 259
181 /* Free table allocated by acpi_tb_get_table_body */ 260 if (++j < instance) {
182 261 continue;
183 acpi_tb_delete_single_table(&table_info); 262 }
184 return_ACPI_STATUS(status);
185 }
186
187 /* Convert the table to common format if necessary */
188
189 switch (table_info.type) {
190 case ACPI_TABLE_ID_FADT:
191
192 status = acpi_tb_convert_table_fadt();
193 break;
194
195 case ACPI_TABLE_ID_FACS:
196
197 status = acpi_tb_build_common_facs(&table_info);
198 break;
199
200 default:
201 /* Load table into namespace if it contains executable AML */
202
203 status =
204 acpi_ns_load_table(table_info.installed_desc,
205 acpi_gbl_root_node);
206 break;
207 }
208 263
209 if (ACPI_FAILURE(status)) { 264 *out_table_header =
265 acpi_tb_map(acpi_gbl_root_table_list.tables[i].address,
266 (u32) sizeof(struct acpi_table_header),
267 acpi_gbl_root_table_list.tables[i].
268 flags & ACPI_TABLE_ORIGIN_MASK);
210 269
211 /* Uninstall table and free the buffer */ 270 if (!out_table_header) {
271 return (AE_NO_MEMORY);
272 }
212 273
213 (void)acpi_tb_uninstall_table(table_info.installed_desc); 274 return (AE_OK);
214 } 275 }
215 276
216 return_ACPI_STATUS(status); 277 return (AE_NOT_FOUND);
217} 278}
218 279
219ACPI_EXPORT_SYMBOL(acpi_load_table) 280ACPI_EXPORT_SYMBOL(acpi_get_table_header)
220 281
221/******************************************************************************* 282
283/******************************************************************************
222 * 284 *
223 * FUNCTION: acpi_unload_table_id 285 * FUNCTION: acpi_unload_table_id
224 * 286 *
225 * PARAMETERS: table_type - Type of table to be unloaded 287 * PARAMETERS: id - Owner ID of the table to be removed.
226 * id - Owner ID of the table to be removed.
227 * 288 *
228 * RETURN: Status 289 * RETURN: Status
229 * 290 *
230 * DESCRIPTION: This routine is used to force the unload of a table (by id) 291 * DESCRIPTION: This routine is used to force the unload of a table (by id)
231 * 292 *
232 ******************************************************************************/ 293 ******************************************************************************/
233acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id) 294acpi_status acpi_unload_table_id(acpi_owner_id id)
234{ 295{
235 struct acpi_table_desc *table_desc; 296 int i;
236 acpi_status status; 297 acpi_status status = AE_NOT_EXIST;
237 298
238 ACPI_FUNCTION_TRACE(acpi_unload_table); 299 ACPI_FUNCTION_TRACE(acpi_unload_table);
239 300
240 /* Parameter validation */
241 if (table_type > ACPI_TABLE_ID_MAX)
242 return_ACPI_STATUS(AE_BAD_PARAMETER);
243
244 /* Find table from the requested type list */ 301 /* Find table from the requested type list */
245 table_desc = acpi_gbl_table_lists[table_type].next; 302 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
246 while (table_desc && table_desc->owner_id != id) 303 if (id != acpi_gbl_root_table_list.tables[i].owner_id) {
247 table_desc = table_desc->next; 304 continue;
248 305 }
249 if (!table_desc) 306 /*
250 return_ACPI_STATUS(AE_NOT_EXIST); 307 * Delete all namespace objects owned by this table. Note that these
251 308 * objects can appear anywhere in the namespace by virtue of the AML
252 /* 309 * "Scope" operator. Thus, we need to track ownership by an ID, not
253 * Delete all namespace objects owned by this table. Note that these 310 * simply a position within the hierarchy
254 * objects can appear anywhere in the namespace by virtue of the AML 311 */
255 * "Scope" operator. Thus, we need to track ownership by an ID, not 312 acpi_tb_delete_namespace_by_owner(i);
256 * simply a position within the hierarchy 313 acpi_tb_release_owner_id(i);
257 */ 314 acpi_tb_set_table_loaded_flag(i, FALSE);
258 acpi_ns_delete_namespace_by_owner(table_desc->owner_id); 315 }
259 316 return_ACPI_STATUS(status);
260 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
261 if (ACPI_FAILURE(status))
262 return_ACPI_STATUS(status);
263
264 (void)acpi_tb_uninstall_table(table_desc);
265
266 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
267
268 return_ACPI_STATUS(AE_OK);
269} 317}
270 318
271ACPI_EXPORT_SYMBOL(acpi_unload_table_id) 319ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
272 320
273#ifdef ACPI_FUTURE_USAGE
274/******************************************************************************* 321/*******************************************************************************
275 * 322 *
276 * FUNCTION: acpi_unload_table 323 * FUNCTION: acpi_get_table
277 * 324 *
278 * PARAMETERS: table_type - Type of table to be unloaded 325 * PARAMETERS: Signature - ACPI signature of needed table
326 * Instance - Which instance (for SSDTs)
327 * out_table - Where the pointer to the table is returned
279 * 328 *
280 * RETURN: Status 329 * RETURN: Status and pointer to table
281 * 330 *
282 * DESCRIPTION: This routine is used to force the unload of a table 331 * DESCRIPTION: Finds and verifies an ACPI table.
283 * 332 *
284 ******************************************************************************/ 333 *****************************************************************************/
285acpi_status acpi_unload_table(acpi_table_type table_type) 334acpi_status
335acpi_get_table(char *signature,
336 acpi_native_uint instance, struct acpi_table_header ** out_table)
286{ 337{
287 struct acpi_table_desc *table_desc; 338 acpi_native_uint i;
288 339 acpi_native_uint j;
289 ACPI_FUNCTION_TRACE(acpi_unload_table); 340 acpi_status status;
290
291 /* Parameter validation */
292 341
293 if (table_type > ACPI_TABLE_ID_MAX) { 342 /*
294 return_ACPI_STATUS(AE_BAD_PARAMETER); 343 * Walk the root table list
295 } 344 */
345 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
346 if (!ACPI_COMPARE_NAME
347 (&(acpi_gbl_root_table_list.tables[i].signature),
348 signature)) {
349 continue;
350 }
296 351
297 /* Find all tables of the requested type */ 352 if (++j < instance) {
353 continue;
354 }
298 355
299 table_desc = acpi_gbl_table_lists[table_type].next; 356 status =
300 if (!table_desc) { 357 acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]);
301 return_ACPI_STATUS(AE_NOT_EXIST); 358 if (ACPI_SUCCESS(status)) {
302 } 359 *out_table = acpi_gbl_root_table_list.tables[i].pointer;
360 }
303 361
304 while (table_desc) { 362 return (status);
305 /*
306 * Delete all namespace objects owned by this table. Note that these
307 * objects can appear anywhere in the namespace by virtue of the AML
308 * "Scope" operator. Thus, we need to track ownership by an ID, not
309 * simply a position within the hierarchy
310 */
311 acpi_ns_delete_namespace_by_owner(table_desc->owner_id);
312 table_desc = table_desc->next;
313 } 363 }
314 364
315 /* Delete (or unmap) all tables of this type */ 365 return (AE_NOT_FOUND);
316
317 acpi_tb_delete_tables_by_type(table_type);
318 return_ACPI_STATUS(AE_OK);
319} 366}
320 367
321ACPI_EXPORT_SYMBOL(acpi_unload_table) 368ACPI_EXPORT_SYMBOL(acpi_get_table)
322 369
323/******************************************************************************* 370/*******************************************************************************
324 * 371 *
325 * FUNCTION: acpi_get_table_header 372 * FUNCTION: acpi_get_table_by_index
326 * 373 *
327 * PARAMETERS: table_type - one of the defined table types 374 * PARAMETERS: table_index - Table index
328 * Instance - the non zero instance of the table, allows 375 * Table - Where the pointer to the table is returned
329 * support for multiple tables of the same type
330 * see acpi_gbl_acpi_table_flag
331 * out_table_header - pointer to the struct acpi_table_header if successful
332 * 376 *
333 * DESCRIPTION: This function is called to get an ACPI table header. The caller 377 * RETURN: Status and pointer to the table
334 * supplies an pointer to a data area sufficient to contain an ACPI
335 * struct acpi_table_header structure.
336 * 378 *
337 * The header contains a length field that can be used to determine 379 * DESCRIPTION: Obtain a table by an index into the global table list.
338 * the size of the buffer needed to contain the entire table. This
339 * function is not valid for the RSD PTR table since it does not
340 * have a standard header and is fixed length.
341 * 380 *
342 ******************************************************************************/ 381 ******************************************************************************/
343acpi_status 382acpi_status
344acpi_get_table_header(acpi_table_type table_type, 383acpi_get_table_by_index(acpi_native_uint table_index,
345 u32 instance, struct acpi_table_header *out_table_header) 384 struct acpi_table_header ** table)
346{ 385{
347 struct acpi_table_header *tbl_ptr;
348 acpi_status status; 386 acpi_status status;
349 387
350 ACPI_FUNCTION_TRACE(acpi_get_table_header); 388 ACPI_FUNCTION_TRACE(acpi_get_table_by_index);
351 389
352 if ((instance == 0) || 390 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
353 (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) {
354 return_ACPI_STATUS(AE_BAD_PARAMETER);
355 }
356 391
357 /* Check the table type and instance */ 392 /* Validate index */
358 393
359 if ((table_type > ACPI_TABLE_ID_MAX) || 394 if (table_index >= acpi_gbl_root_table_list.count) {
360 (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && 395 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
361 instance > 1)) {
362 return_ACPI_STATUS(AE_BAD_PARAMETER); 396 return_ACPI_STATUS(AE_BAD_PARAMETER);
363 } 397 }
364 398
365 /* Get a pointer to the entire table */ 399 if (!acpi_gbl_root_table_list.tables[table_index].pointer) {
366 400
367 status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); 401 /* Table is not mapped, map it */
368 if (ACPI_FAILURE(status)) {
369 return_ACPI_STATUS(status);
370 }
371 402
372 /* The function will return a NULL pointer if the table is not loaded */ 403 status =
373 404 acpi_tb_verify_table(&acpi_gbl_root_table_list.
374 if (tbl_ptr == NULL) { 405 tables[table_index]);
375 return_ACPI_STATUS(AE_NOT_EXIST); 406 if (ACPI_FAILURE(status)) {
407 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
408 return_ACPI_STATUS(status);
409 }
376 } 410 }
377 411
378 /* Copy the header to the caller's buffer */ 412 *table = acpi_gbl_root_table_list.tables[table_index].pointer;
379 413 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
380 ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header), 414 return_ACPI_STATUS(AE_OK);
381 ACPI_CAST_PTR(void, tbl_ptr),
382 sizeof(struct acpi_table_header));
383
384 return_ACPI_STATUS(status);
385} 415}
386 416
387ACPI_EXPORT_SYMBOL(acpi_get_table_header) 417ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
388#endif /* ACPI_FUTURE_USAGE */
389 418
390/******************************************************************************* 419/*******************************************************************************
391 * 420 *
392 * FUNCTION: acpi_get_table 421 * FUNCTION: acpi_tb_load_namespace
393 * 422 *
394 * PARAMETERS: table_type - one of the defined table types 423 * PARAMETERS: None
395 * Instance - the non zero instance of the table, allows
396 * support for multiple tables of the same type
397 * see acpi_gbl_acpi_table_flag
398 * ret_buffer - pointer to a structure containing a buffer to
399 * receive the table
400 * 424 *
401 * RETURN: Status 425 * RETURN: Status
402 * 426 *
403 * DESCRIPTION: This function is called to get an ACPI table. The caller 427 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
404 * supplies an out_buffer large enough to contain the entire ACPI 428 * the RSDT/XSDT.
405 * table. The caller should call the acpi_get_table_header function
406 * first to determine the buffer size needed. Upon completion
407 * the out_buffer->Length field will indicate the number of bytes
408 * copied into the out_buffer->buf_ptr buffer. This table will be
409 * a complete table including the header.
410 * 429 *
411 ******************************************************************************/ 430 ******************************************************************************/
412acpi_status 431static acpi_status acpi_tb_load_namespace(void)
413acpi_get_table(acpi_table_type table_type,
414 u32 instance, struct acpi_buffer *ret_buffer)
415{ 432{
416 struct acpi_table_header *tbl_ptr;
417 acpi_status status; 433 acpi_status status;
418 acpi_size table_length; 434 struct acpi_table_header *table;
435 acpi_native_uint i;
419 436
420 ACPI_FUNCTION_TRACE(acpi_get_table); 437 ACPI_FUNCTION_TRACE(tb_load_namespace);
421 438
422 /* Parameter validation */ 439 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
423 440
424 if (instance == 0) { 441 /*
425 return_ACPI_STATUS(AE_BAD_PARAMETER); 442 * Load the namespace. The DSDT is required, but any SSDT and PSDT tables
443 * are optional.
444 */
445 if (!acpi_gbl_root_table_list.count ||
446 !ACPI_COMPARE_NAME(&
447 (acpi_gbl_root_table_list.
448 tables[ACPI_TABLE_INDEX_DSDT].signature),
449 ACPI_SIG_DSDT)
450 ||
451 ACPI_FAILURE(acpi_tb_verify_table
452 (&acpi_gbl_root_table_list.
453 tables[ACPI_TABLE_INDEX_DSDT]))) {
454 status = AE_NO_ACPI_TABLES;
455 goto unlock_and_exit;
426 } 456 }
427 457
428 status = acpi_ut_validate_buffer(ret_buffer); 458 /*
429 if (ACPI_FAILURE(status)) { 459 * Find DSDT table
430 return_ACPI_STATUS(status); 460 */
461 status =
462 acpi_os_table_override(acpi_gbl_root_table_list.
463 tables[ACPI_TABLE_INDEX_DSDT].pointer,
464 &table);
465 if (ACPI_SUCCESS(status) && table) {
466 /*
467 * DSDT table has been found
468 */
469 acpi_tb_delete_table(ACPI_TABLE_INDEX_DSDT);
470 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
471 table;
472 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
473 table->length;
474 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
475 ACPI_TABLE_ORIGIN_UNKNOWN;
476
477 ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
478 acpi_tb_print_table_header(0, table);
431 } 479 }
432 480
433 /* Check the table type and instance */ 481 status =
482 acpi_tb_verify_table(&acpi_gbl_root_table_list.
483 tables[ACPI_TABLE_INDEX_DSDT]);
484 if (ACPI_FAILURE(status)) {
485
486 /* A valid DSDT is required */
434 487
435 if ((table_type > ACPI_TABLE_ID_MAX) || 488 status = AE_NO_ACPI_TABLES;
436 (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && 489 goto unlock_and_exit;
437 instance > 1)) {
438 return_ACPI_STATUS(AE_BAD_PARAMETER);
439 } 490 }
440 491
441 /* Get a pointer to the entire table */ 492 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
442 493
443 status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); 494 /*
495 * Load and parse tables.
496 */
497 status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
444 if (ACPI_FAILURE(status)) { 498 if (ACPI_FAILURE(status)) {
445 return_ACPI_STATUS(status); 499 return_ACPI_STATUS(status);
446 } 500 }
447 501
448 /* 502 /*
449 * acpi_tb_get_table_ptr will return a NULL pointer if the 503 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
450 * table is not loaded.
451 */ 504 */
452 if (tbl_ptr == NULL) { 505 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
453 return_ACPI_STATUS(AE_NOT_EXIST); 506 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
507 if ((!ACPI_COMPARE_NAME
508 (&(acpi_gbl_root_table_list.tables[i].signature),
509 ACPI_SIG_SSDT)
510 &&
511 !ACPI_COMPARE_NAME(&
512 (acpi_gbl_root_table_list.tables[i].
513 signature), ACPI_SIG_PSDT))
514 ||
515 ACPI_FAILURE(acpi_tb_verify_table
516 (&acpi_gbl_root_table_list.tables[i]))) {
517 continue;
518 }
519
520 /* Ignore errors while loading tables, get as many as possible */
521
522 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
523 (void)acpi_ns_load_table(i, acpi_gbl_root_node);
524 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
454 } 525 }
455 526
456 /* Get the table length */ 527 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
457 528
458 if (table_type == ACPI_TABLE_ID_RSDP) { 529 unlock_and_exit:
530 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
531 return_ACPI_STATUS(status);
532}
459 533
460 /* RSD PTR is the only "table" without a header */ 534/*******************************************************************************
535 *
536 * FUNCTION: acpi_load_tables
537 *
538 * PARAMETERS: None
539 *
540 * RETURN: Status
541 *
542 * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
543 *
544 ******************************************************************************/
461 545
462 table_length = sizeof(struct rsdp_descriptor); 546acpi_status acpi_load_tables(void)
463 } else { 547{
464 table_length = (acpi_size) tbl_ptr->length; 548 acpi_status status;
465 }
466 549
467 /* Validate/Allocate/Clear caller buffer */ 550 ACPI_FUNCTION_TRACE(acpi_load_tables);
468 551
469 status = acpi_ut_initialize_buffer(ret_buffer, table_length); 552 /*
553 * Load the namespace from the tables
554 */
555 status = acpi_tb_load_namespace();
470 if (ACPI_FAILURE(status)) { 556 if (ACPI_FAILURE(status)) {
471 return_ACPI_STATUS(status); 557 ACPI_EXCEPTION((AE_INFO, status,
558 "While loading namespace from ACPI tables"));
472 } 559 }
473 560
474 /* Copy the table to the buffer */ 561 return_ACPI_STATUS(status);
475
476 ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer),
477 ACPI_CAST_PTR(void, tbl_ptr), table_length);
478
479 return_ACPI_STATUS(AE_OK);
480} 562}
481 563
482ACPI_EXPORT_SYMBOL(acpi_get_table) 564ACPI_EXPORT_SYMBOL(acpi_load_tables)