• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/acpi/acpica/
1/******************************************************************************
2 *
3 * Module Name: tbinstal - ACPI table installation and removal
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2010, 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
50ACPI_MODULE_NAME("tbinstal")
51
52/******************************************************************************
53 *
54 * FUNCTION:    acpi_tb_verify_table
55 *
56 * PARAMETERS:  table_desc          - table
57 *
58 * RETURN:      Status
59 *
60 * DESCRIPTION: this function is called to verify and map table
61 *
62 *****************************************************************************/
63acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
64{
65	acpi_status status = AE_OK;
66
67	ACPI_FUNCTION_TRACE(tb_verify_table);
68
69	/* Map the table if necessary */
70
71	if (!table_desc->pointer) {
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	}
82
83	/* FACS is the odd table, has no standard ACPI header and no checksum */
84
85	if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) {
86
87		/* Always calculate checksum, ignore bad checksum if requested */
88
89		status =
90		    acpi_tb_verify_checksum(table_desc->pointer,
91					    table_desc->length);
92	}
93
94	return_ACPI_STATUS(status);
95}
96
97/*******************************************************************************
98 *
99 * FUNCTION:    acpi_tb_add_table
100 *
101 * PARAMETERS:  table_desc          - Table descriptor
102 *              table_index         - Where the table index is returned
103 *
104 * RETURN:      Status
105 *
106 * DESCRIPTION: This function is called to add an ACPI table. It is used to
107 *              dynamically load tables via the Load and load_table AML
108 *              operators.
109 *
110 ******************************************************************************/
111
112acpi_status
113acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
114{
115	u32 i;
116	acpi_status status = AE_OK;
117	struct acpi_table_header *override_table = NULL;
118
119	ACPI_FUNCTION_TRACE(tb_add_table);
120
121	if (!table_desc->pointer) {
122		status = acpi_tb_verify_table(table_desc);
123		if (ACPI_FAILURE(status) || !table_desc->pointer) {
124			return_ACPI_STATUS(status);
125		}
126	}
127
128	/*
129	 * Originally, we checked the table signature for "SSDT" or "PSDT" here.
130	 * Next, we added support for OEMx tables, signature "OEM".
131	 * Valid tables were encountered with a null signature, so we've just
132	 * given up on validating the signature, since it seems to be a waste
133	 * of code. The original code was removed (05/2008).
134	 */
135
136	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
137
138	/* Check if table is already registered */
139
140	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
141		if (!acpi_gbl_root_table_list.tables[i].pointer) {
142			status =
143			    acpi_tb_verify_table(&acpi_gbl_root_table_list.
144						 tables[i]);
145			if (ACPI_FAILURE(status)
146			    || !acpi_gbl_root_table_list.tables[i].pointer) {
147				continue;
148			}
149		}
150
151		/*
152		 * Check for a table match on the entire table length,
153		 * not just the header.
154		 */
155		if (table_desc->length !=
156		    acpi_gbl_root_table_list.tables[i].length) {
157			continue;
158		}
159
160		if (ACPI_MEMCMP(table_desc->pointer,
161				acpi_gbl_root_table_list.tables[i].pointer,
162				acpi_gbl_root_table_list.tables[i].length)) {
163			continue;
164		}
165
166		/*
167		 * Note: the current mechanism does not unregister a table if it is
168		 * dynamically unloaded. The related namespace entries are deleted,
169		 * but the table remains in the root table list.
170		 *
171		 * The assumption here is that the number of different tables that
172		 * will be loaded is actually small, and there is minimal overhead
173		 * in just keeping the table in case it is needed again.
174		 *
175		 * If this assumption changes in the future (perhaps on large
176		 * machines with many table load/unload operations), tables will
177		 * need to be unregistered when they are unloaded, and slots in the
178		 * root table list should be reused when empty.
179		 */
180
181		/*
182		 * Table is already registered.
183		 * We can delete the table that was passed as a parameter.
184		 */
185		acpi_tb_delete_table(table_desc);
186		*table_index = i;
187
188		if (acpi_gbl_root_table_list.tables[i].
189		    flags & ACPI_TABLE_IS_LOADED) {
190
191			/* Table is still loaded, this is an error */
192
193			status = AE_ALREADY_EXISTS;
194			goto release;
195		} else {
196			/* Table was unloaded, allow it to be reloaded */
197
198			table_desc->pointer =
199			    acpi_gbl_root_table_list.tables[i].pointer;
200			table_desc->address =
201			    acpi_gbl_root_table_list.tables[i].address;
202			status = AE_OK;
203			goto print_header;
204		}
205	}
206
207	/*
208	 * ACPI Table Override:
209	 * Allow the host to override dynamically loaded tables.
210	 */
211	status = acpi_os_table_override(table_desc->pointer, &override_table);
212	if (ACPI_SUCCESS(status) && override_table) {
213		ACPI_INFO((AE_INFO,
214			   "%4.4s @ 0x%p Table override, replaced with:",
215			   table_desc->pointer->signature,
216			   ACPI_CAST_PTR(void, table_desc->address)));
217
218		/* We can delete the table that was passed as a parameter */
219
220		acpi_tb_delete_table(table_desc);
221
222		/* Setup descriptor for the new table */
223
224		table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
225		table_desc->pointer = override_table;
226		table_desc->length = override_table->length;
227		table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
228	}
229
230	/* Add the table to the global root table list */
231
232	status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
233				     table_desc->length, table_desc->flags,
234				     table_index);
235	if (ACPI_FAILURE(status)) {
236		goto release;
237	}
238
239      print_header:
240	acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
241
242      release:
243	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
244	return_ACPI_STATUS(status);
245}
246
247/*******************************************************************************
248 *
249 * FUNCTION:    acpi_tb_resize_root_table_list
250 *
251 * PARAMETERS:  None
252 *
253 * RETURN:      Status
254 *
255 * DESCRIPTION: Expand the size of global table array
256 *
257 ******************************************************************************/
258
259acpi_status acpi_tb_resize_root_table_list(void)
260{
261	struct acpi_table_desc *tables;
262
263	ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
264
265	/* allow_resize flag is a parameter to acpi_initialize_tables */
266
267	if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
268		ACPI_ERROR((AE_INFO,
269			    "Resize of Root Table Array is not allowed"));
270		return_ACPI_STATUS(AE_SUPPORT);
271	}
272
273	/* Increase the Table Array size */
274
275	tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
276				       max_table_count +
277				       ACPI_ROOT_TABLE_SIZE_INCREMENT) *
278				      sizeof(struct acpi_table_desc));
279	if (!tables) {
280		ACPI_ERROR((AE_INFO,
281			    "Could not allocate new root table array"));
282		return_ACPI_STATUS(AE_NO_MEMORY);
283	}
284
285	/* Copy and free the previous table array */
286
287	if (acpi_gbl_root_table_list.tables) {
288		ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
289			    (acpi_size) acpi_gbl_root_table_list.
290			    max_table_count * sizeof(struct acpi_table_desc));
291
292		if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
293			ACPI_FREE(acpi_gbl_root_table_list.tables);
294		}
295	}
296
297	acpi_gbl_root_table_list.tables = tables;
298	acpi_gbl_root_table_list.max_table_count +=
299	    ACPI_ROOT_TABLE_SIZE_INCREMENT;
300	acpi_gbl_root_table_list.flags |= (u8)ACPI_ROOT_ORIGIN_ALLOCATED;
301
302	return_ACPI_STATUS(AE_OK);
303}
304
305/*******************************************************************************
306 *
307 * FUNCTION:    acpi_tb_store_table
308 *
309 * PARAMETERS:  Address             - Table address
310 *              Table               - Table header
311 *              Length              - Table length
312 *              Flags               - flags
313 *
314 * RETURN:      Status and table index.
315 *
316 * DESCRIPTION: Add an ACPI table to the global table list
317 *
318 ******************************************************************************/
319
320acpi_status
321acpi_tb_store_table(acpi_physical_address address,
322		    struct acpi_table_header *table,
323		    u32 length, u8 flags, u32 *table_index)
324{
325	acpi_status status;
326	struct acpi_table_desc *new_table;
327
328	/* Ensure that there is room for the table in the Root Table List */
329
330	if (acpi_gbl_root_table_list.current_table_count >=
331	    acpi_gbl_root_table_list.max_table_count) {
332		status = acpi_tb_resize_root_table_list();
333		if (ACPI_FAILURE(status)) {
334			return (status);
335		}
336	}
337
338	new_table =
339	    &acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.
340					     current_table_count];
341
342	/* Initialize added table */
343
344	new_table->address = address;
345	new_table->pointer = table;
346	new_table->length = length;
347	new_table->owner_id = 0;
348	new_table->flags = flags;
349
350	ACPI_MOVE_32_TO_32(&new_table->signature, table->signature);
351
352	*table_index = acpi_gbl_root_table_list.current_table_count;
353	acpi_gbl_root_table_list.current_table_count++;
354	return (AE_OK);
355}
356
357/*******************************************************************************
358 *
359 * FUNCTION:    acpi_tb_delete_table
360 *
361 * PARAMETERS:  table_index         - Table index
362 *
363 * RETURN:      None
364 *
365 * DESCRIPTION: Delete one internal ACPI table
366 *
367 ******************************************************************************/
368
369void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
370{
371	/* Table must be mapped or allocated */
372	if (!table_desc->pointer) {
373		return;
374	}
375	switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
376	case ACPI_TABLE_ORIGIN_MAPPED:
377		acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
378		break;
379	case ACPI_TABLE_ORIGIN_ALLOCATED:
380		ACPI_FREE(table_desc->pointer);
381		break;
382	default:;
383	}
384
385	table_desc->pointer = NULL;
386}
387
388/*******************************************************************************
389 *
390 * FUNCTION:    acpi_tb_terminate
391 *
392 * PARAMETERS:  None
393 *
394 * RETURN:      None
395 *
396 * DESCRIPTION: Delete all internal ACPI tables
397 *
398 ******************************************************************************/
399
400void acpi_tb_terminate(void)
401{
402	u32 i;
403
404	ACPI_FUNCTION_TRACE(tb_terminate);
405
406	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
407
408	/* Delete the individual tables */
409
410	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
411		acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]);
412	}
413
414	/*
415	 * Delete the root table array if allocated locally. Array cannot be
416	 * mapped, so we don't need to check for that flag.
417	 */
418	if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
419		ACPI_FREE(acpi_gbl_root_table_list.tables);
420	}
421
422	acpi_gbl_root_table_list.tables = NULL;
423	acpi_gbl_root_table_list.flags = 0;
424	acpi_gbl_root_table_list.current_table_count = 0;
425
426	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
427	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
428}
429
430/*******************************************************************************
431 *
432 * FUNCTION:    acpi_tb_delete_namespace_by_owner
433 *
434 * PARAMETERS:  table_index         - Table index
435 *
436 * RETURN:      Status
437 *
438 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
439 *
440 ******************************************************************************/
441
442acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
443{
444	acpi_owner_id owner_id;
445	acpi_status status;
446
447	ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
448
449	status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
450	if (ACPI_FAILURE(status)) {
451		return_ACPI_STATUS(status);
452	}
453
454	if (table_index >= acpi_gbl_root_table_list.current_table_count) {
455
456		/* The table index does not exist */
457
458		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
459		return_ACPI_STATUS(AE_NOT_EXIST);
460	}
461
462	/* Get the owner ID for this table, used to delete namespace nodes */
463
464	owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
465	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
466
467	/*
468	 * Need to acquire the namespace writer lock to prevent interference
469	 * with any concurrent namespace walks. The interpreter must be
470	 * released during the deletion since the acquisition of the deletion
471	 * lock may block, and also since the execution of a namespace walk
472	 * must be allowed to use the interpreter.
473	 */
474	(void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
475	status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
476
477	acpi_ns_delete_namespace_by_owner(owner_id);
478	if (ACPI_FAILURE(status)) {
479		return_ACPI_STATUS(status);
480	}
481
482	acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
483
484	status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
485	return_ACPI_STATUS(status);
486}
487
488/*******************************************************************************
489 *
490 * FUNCTION:    acpi_tb_allocate_owner_id
491 *
492 * PARAMETERS:  table_index         - Table index
493 *
494 * RETURN:      Status
495 *
496 * DESCRIPTION: Allocates owner_id in table_desc
497 *
498 ******************************************************************************/
499
500acpi_status acpi_tb_allocate_owner_id(u32 table_index)
501{
502	acpi_status status = AE_BAD_PARAMETER;
503
504	ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
505
506	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
507	if (table_index < acpi_gbl_root_table_list.current_table_count) {
508		status = acpi_ut_allocate_owner_id
509		    (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
510	}
511
512	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
513	return_ACPI_STATUS(status);
514}
515
516/*******************************************************************************
517 *
518 * FUNCTION:    acpi_tb_release_owner_id
519 *
520 * PARAMETERS:  table_index         - Table index
521 *
522 * RETURN:      Status
523 *
524 * DESCRIPTION: Releases owner_id in table_desc
525 *
526 ******************************************************************************/
527
528acpi_status acpi_tb_release_owner_id(u32 table_index)
529{
530	acpi_status status = AE_BAD_PARAMETER;
531
532	ACPI_FUNCTION_TRACE(tb_release_owner_id);
533
534	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
535	if (table_index < acpi_gbl_root_table_list.current_table_count) {
536		acpi_ut_release_owner_id(&
537					 (acpi_gbl_root_table_list.
538					  tables[table_index].owner_id));
539		status = AE_OK;
540	}
541
542	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
543	return_ACPI_STATUS(status);
544}
545
546/*******************************************************************************
547 *
548 * FUNCTION:    acpi_tb_get_owner_id
549 *
550 * PARAMETERS:  table_index         - Table index
551 *              owner_id            - Where the table owner_id is returned
552 *
553 * RETURN:      Status
554 *
555 * DESCRIPTION: returns owner_id for the ACPI table
556 *
557 ******************************************************************************/
558
559acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
560{
561	acpi_status status = AE_BAD_PARAMETER;
562
563	ACPI_FUNCTION_TRACE(tb_get_owner_id);
564
565	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
566	if (table_index < acpi_gbl_root_table_list.current_table_count) {
567		*owner_id =
568		    acpi_gbl_root_table_list.tables[table_index].owner_id;
569		status = AE_OK;
570	}
571
572	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
573	return_ACPI_STATUS(status);
574}
575
576/*******************************************************************************
577 *
578 * FUNCTION:    acpi_tb_is_table_loaded
579 *
580 * PARAMETERS:  table_index         - Table index
581 *
582 * RETURN:      Table Loaded Flag
583 *
584 ******************************************************************************/
585
586u8 acpi_tb_is_table_loaded(u32 table_index)
587{
588	u8 is_loaded = FALSE;
589
590	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
591	if (table_index < acpi_gbl_root_table_list.current_table_count) {
592		is_loaded = (u8)
593		    (acpi_gbl_root_table_list.tables[table_index].flags &
594		     ACPI_TABLE_IS_LOADED);
595	}
596
597	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
598	return (is_loaded);
599}
600
601/*******************************************************************************
602 *
603 * FUNCTION:    acpi_tb_set_table_loaded_flag
604 *
605 * PARAMETERS:  table_index         - Table index
606 *              is_loaded           - TRUE if table is loaded, FALSE otherwise
607 *
608 * RETURN:      None
609 *
610 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
611 *
612 ******************************************************************************/
613
614void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
615{
616
617	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
618	if (table_index < acpi_gbl_root_table_list.current_table_count) {
619		if (is_loaded) {
620			acpi_gbl_root_table_list.tables[table_index].flags |=
621			    ACPI_TABLE_IS_LOADED;
622		} else {
623			acpi_gbl_root_table_list.tables[table_index].flags &=
624			    ~ACPI_TABLE_IS_LOADED;
625		}
626	}
627
628	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
629}
630