xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/tables/tbinstal.c (revision 6c4a44e36ba846c54467103f884d65dfa13e7fcb)
1 /******************************************************************************
2  *
3  * Module Name: tbinstal - ACPI table installation and removal
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights.  You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code.  No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision.  In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change.  Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee.  Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution.  In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government.  In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 
117 #define __TBINSTAL_C__
118 
119 #include "acpi.h"
120 #include "accommon.h"
121 #include "acnamesp.h"
122 #include "actables.h"
123 
124 
125 #define _COMPONENT          ACPI_TABLES
126         ACPI_MODULE_NAME    ("tbinstal")
127 
128 
129 /******************************************************************************
130  *
131  * FUNCTION:    AcpiTbVerifyTable
132  *
133  * PARAMETERS:  TableDesc           - table
134  *
135  * RETURN:      Status
136  *
137  * DESCRIPTION: this function is called to verify and map table
138  *
139  *****************************************************************************/
140 
141 ACPI_STATUS
142 AcpiTbVerifyTable (
143     ACPI_TABLE_DESC         *TableDesc)
144 {
145     ACPI_STATUS             Status = AE_OK;
146 
147 
148     ACPI_FUNCTION_TRACE (TbVerifyTable);
149 
150 
151     /* Map the table if necessary */
152 
153     if (!TableDesc->Pointer)
154     {
155         if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
156             ACPI_TABLE_ORIGIN_MAPPED)
157         {
158             TableDesc->Pointer = AcpiOsMapMemory (
159                 TableDesc->Address, TableDesc->Length);
160         }
161 
162         if (!TableDesc->Pointer)
163         {
164             return_ACPI_STATUS (AE_NO_MEMORY);
165         }
166     }
167 
168     /* FACS is the odd table, has no standard ACPI header and no checksum */
169 
170     if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
171     {
172         /* Always calculate checksum, ignore bad checksum if requested */
173 
174         Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
175     }
176 
177     return_ACPI_STATUS (Status);
178 }
179 
180 
181 /*******************************************************************************
182  *
183  * FUNCTION:    AcpiTbAddTable
184  *
185  * PARAMETERS:  TableDesc           - Table descriptor
186  *              TableIndex          - Where the table index is returned
187  *
188  * RETURN:      Status
189  *
190  * DESCRIPTION: This function is called to add an ACPI table. It is used to
191  *              dynamically load tables via the Load and LoadTable AML
192  *              operators.
193  *
194  ******************************************************************************/
195 
196 ACPI_STATUS
197 AcpiTbAddTable (
198     ACPI_TABLE_DESC         *TableDesc,
199     UINT32                  *TableIndex)
200 {
201     UINT32                  i;
202     ACPI_STATUS             Status = AE_OK;
203 
204 
205     ACPI_FUNCTION_TRACE (TbAddTable);
206 
207 
208     if (!TableDesc->Pointer)
209     {
210         Status = AcpiTbVerifyTable (TableDesc);
211         if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
212         {
213             return_ACPI_STATUS (Status);
214         }
215     }
216 
217     /*
218      * Validate the incoming table signature.
219      *
220      * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
221      * 2) We added support for OEMx tables, signature "OEM".
222      * 3) Valid tables were encountered with a null signature, so we just
223      *    gave up on validating the signature, (05/2008).
224      * 4) We encountered non-AML tables such as the MADT, which caused
225      *    interpreter errors and kernel faults. So now, we once again allow
226      *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
227      */
228     if ((TableDesc->Pointer->Signature[0] != 0x00) &&
229        (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
230        (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
231     {
232         ACPI_BIOS_ERROR ((AE_INFO,
233             "Table has invalid signature [%4.4s] (0x%8.8X), "
234             "must be SSDT or OEMx",
235             AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ?
236                 TableDesc->Pointer->Signature : "????",
237             *(UINT32 *) TableDesc->Pointer->Signature));
238 
239         return_ACPI_STATUS (AE_BAD_SIGNATURE);
240     }
241 
242     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
243 
244     /* Check if table is already registered */
245 
246     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
247     {
248         if (!AcpiGbl_RootTableList.Tables[i].Pointer)
249         {
250             Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
251             if (ACPI_FAILURE (Status) ||
252                 !AcpiGbl_RootTableList.Tables[i].Pointer)
253             {
254                 continue;
255             }
256         }
257 
258         /*
259          * Check for a table match on the entire table length,
260          * not just the header.
261          */
262         if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
263         {
264             continue;
265         }
266 
267         if (ACPI_MEMCMP (TableDesc->Pointer,
268                 AcpiGbl_RootTableList.Tables[i].Pointer,
269                 AcpiGbl_RootTableList.Tables[i].Length))
270         {
271             continue;
272         }
273 
274         /*
275          * Note: the current mechanism does not unregister a table if it is
276          * dynamically unloaded. The related namespace entries are deleted,
277          * but the table remains in the root table list.
278          *
279          * The assumption here is that the number of different tables that
280          * will be loaded is actually small, and there is minimal overhead
281          * in just keeping the table in case it is needed again.
282          *
283          * If this assumption changes in the future (perhaps on large
284          * machines with many table load/unload operations), tables will
285          * need to be unregistered when they are unloaded, and slots in the
286          * root table list should be reused when empty.
287          */
288 
289         /*
290          * Table is already registered.
291          * We can delete the table that was passed as a parameter.
292          */
293         AcpiTbDeleteTable (TableDesc);
294         *TableIndex = i;
295 
296         if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
297         {
298             /* Table is still loaded, this is an error */
299 
300             Status = AE_ALREADY_EXISTS;
301             goto Release;
302         }
303         else
304         {
305             /* Table was unloaded, allow it to be reloaded */
306 
307             TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
308             TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
309             Status = AE_OK;
310             goto PrintHeader;
311         }
312     }
313 
314     /*
315      * ACPI Table Override:
316      * Allow the host to override dynamically loaded tables.
317      * NOTE: the table is fully mapped at this point, and the mapping will
318      * be deleted by TbTableOverride if the table is actually overridden.
319      */
320     (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc);
321 
322     /* Add the table to the global root table list */
323 
324     Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
325                 TableDesc->Length, TableDesc->Flags, TableIndex);
326     if (ACPI_FAILURE (Status))
327     {
328         goto Release;
329     }
330 
331 PrintHeader:
332     AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
333 
334 Release:
335     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
336     return_ACPI_STATUS (Status);
337 }
338 
339 
340 /*******************************************************************************
341  *
342  * FUNCTION:    AcpiTbTableOverride
343  *
344  * PARAMETERS:  TableHeader         - Header for the original table
345  *              TableDesc           - Table descriptor initialized for the
346  *                                    original table. May or may not be mapped.
347  *
348  * RETURN:      Pointer to the entire new table. NULL if table not overridden.
349  *              If overridden, installs the new table within the input table
350  *              descriptor.
351  *
352  * DESCRIPTION: Attempt table override by calling the OSL override functions.
353  *              Note: If the table is overridden, then the entire new table
354  *              is mapped and returned by this function.
355  *
356  ******************************************************************************/
357 
358 ACPI_TABLE_HEADER *
359 AcpiTbTableOverride (
360     ACPI_TABLE_HEADER       *TableHeader,
361     ACPI_TABLE_DESC         *TableDesc)
362 {
363     ACPI_STATUS             Status;
364     ACPI_TABLE_HEADER       *NewTable = NULL;
365     ACPI_PHYSICAL_ADDRESS   NewAddress = 0;
366     UINT32                  NewTableLength = 0;
367     UINT8                   NewFlags;
368     char                    *OverrideType;
369 
370 
371     /* (1) Attempt logical override (returns a logical address) */
372 
373     Status = AcpiOsTableOverride (TableHeader, &NewTable);
374     if (ACPI_SUCCESS (Status) && NewTable)
375     {
376         NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable);
377         NewTableLength = NewTable->Length;
378         NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE;
379         OverrideType = "Logical";
380         goto FinishOverride;
381     }
382 
383     /* (2) Attempt physical override (returns a physical address) */
384 
385     Status = AcpiOsPhysicalTableOverride (TableHeader,
386         &NewAddress, &NewTableLength);
387     if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
388     {
389         /* Map the entire new table */
390 
391         NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
392         if (!NewTable)
393         {
394             ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
395                 "%4.4s %p Attempted physical table override failed",
396                 TableHeader->Signature,
397                 ACPI_CAST_PTR (void, TableDesc->Address)));
398             return (NULL);
399         }
400 
401         OverrideType = "Physical";
402         NewFlags = ACPI_TABLE_ORIGIN_MAPPED;
403         goto FinishOverride;
404     }
405 
406     return (NULL); /* There was no override */
407 
408 
409 FinishOverride:
410 
411     ACPI_INFO ((AE_INFO,
412         "%4.4s %p %s table override, new table: %p",
413         TableHeader->Signature,
414         ACPI_CAST_PTR (void, TableDesc->Address),
415         OverrideType, NewTable));
416 
417     /* We can now unmap/delete the original table (if fully mapped) */
418 
419     AcpiTbDeleteTable (TableDesc);
420 
421     /* Setup descriptor for the new table */
422 
423     TableDesc->Address = NewAddress;
424     TableDesc->Pointer = NewTable;
425     TableDesc->Length = NewTableLength;
426     TableDesc->Flags = NewFlags;
427 
428     return (NewTable);
429 }
430 
431 
432 /*******************************************************************************
433  *
434  * FUNCTION:    AcpiTbResizeRootTableList
435  *
436  * PARAMETERS:  None
437  *
438  * RETURN:      Status
439  *
440  * DESCRIPTION: Expand the size of global table array
441  *
442  ******************************************************************************/
443 
444 ACPI_STATUS
445 AcpiTbResizeRootTableList (
446     void)
447 {
448     ACPI_TABLE_DESC         *Tables;
449 
450 
451     ACPI_FUNCTION_TRACE (TbResizeRootTableList);
452 
453 
454     /* AllowResize flag is a parameter to AcpiInitializeTables */
455 
456     if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
457     {
458         ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
459         return_ACPI_STATUS (AE_SUPPORT);
460     }
461 
462     /* Increase the Table Array size */
463 
464     Tables = ACPI_ALLOCATE_ZEROED (
465         ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount +
466             ACPI_ROOT_TABLE_SIZE_INCREMENT) *
467         sizeof (ACPI_TABLE_DESC));
468     if (!Tables)
469     {
470         ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
471         return_ACPI_STATUS (AE_NO_MEMORY);
472     }
473 
474     /* Copy and free the previous table array */
475 
476     if (AcpiGbl_RootTableList.Tables)
477     {
478         ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
479             (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC));
480 
481         if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
482         {
483             ACPI_FREE (AcpiGbl_RootTableList.Tables);
484         }
485     }
486 
487     AcpiGbl_RootTableList.Tables = Tables;
488     AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT;
489     AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED;
490 
491     return_ACPI_STATUS (AE_OK);
492 }
493 
494 
495 /*******************************************************************************
496  *
497  * FUNCTION:    AcpiTbStoreTable
498  *
499  * PARAMETERS:  Address             - Table address
500  *              Table               - Table header
501  *              Length              - Table length
502  *              Flags               - flags
503  *
504  * RETURN:      Status and table index.
505  *
506  * DESCRIPTION: Add an ACPI table to the global table list
507  *
508  ******************************************************************************/
509 
510 ACPI_STATUS
511 AcpiTbStoreTable (
512     ACPI_PHYSICAL_ADDRESS   Address,
513     ACPI_TABLE_HEADER       *Table,
514     UINT32                  Length,
515     UINT8                   Flags,
516     UINT32                  *TableIndex)
517 {
518     ACPI_STATUS             Status;
519     ACPI_TABLE_DESC         *NewTable;
520 
521 
522     /* Ensure that there is room for the table in the Root Table List */
523 
524     if (AcpiGbl_RootTableList.CurrentTableCount >=
525         AcpiGbl_RootTableList.MaxTableCount)
526     {
527         Status = AcpiTbResizeRootTableList();
528         if (ACPI_FAILURE (Status))
529         {
530             return (Status);
531         }
532     }
533 
534     NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount];
535 
536     /* Initialize added table */
537 
538     NewTable->Address = Address;
539     NewTable->Pointer = Table;
540     NewTable->Length = Length;
541     NewTable->OwnerId = 0;
542     NewTable->Flags = Flags;
543 
544     ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature);
545 
546     *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
547     AcpiGbl_RootTableList.CurrentTableCount++;
548     return (AE_OK);
549 }
550 
551 
552 /*******************************************************************************
553  *
554  * FUNCTION:    AcpiTbDeleteTable
555  *
556  * PARAMETERS:  TableIndex          - Table index
557  *
558  * RETURN:      None
559  *
560  * DESCRIPTION: Delete one internal ACPI table
561  *
562  ******************************************************************************/
563 
564 void
565 AcpiTbDeleteTable (
566     ACPI_TABLE_DESC         *TableDesc)
567 {
568 
569     /* Table must be mapped or allocated */
570 
571     if (!TableDesc->Pointer)
572     {
573         return;
574     }
575 
576     switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
577     {
578     case ACPI_TABLE_ORIGIN_MAPPED:
579         AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
580         break;
581 
582     case ACPI_TABLE_ORIGIN_ALLOCATED:
583         ACPI_FREE (TableDesc->Pointer);
584         break;
585 
586     /* Not mapped or allocated, there is nothing we can do */
587 
588     default:
589         return;
590     }
591 
592     TableDesc->Pointer = NULL;
593 }
594 
595 
596 /*******************************************************************************
597  *
598  * FUNCTION:    AcpiTbTerminate
599  *
600  * PARAMETERS:  None
601  *
602  * RETURN:      None
603  *
604  * DESCRIPTION: Delete all internal ACPI tables
605  *
606  ******************************************************************************/
607 
608 void
609 AcpiTbTerminate (
610     void)
611 {
612     UINT32                  i;
613 
614 
615     ACPI_FUNCTION_TRACE (TbTerminate);
616 
617 
618     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
619 
620     /* Delete the individual tables */
621 
622     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
623     {
624         AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
625     }
626 
627     /*
628      * Delete the root table array if allocated locally. Array cannot be
629      * mapped, so we don't need to check for that flag.
630      */
631     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
632     {
633         ACPI_FREE (AcpiGbl_RootTableList.Tables);
634     }
635 
636     AcpiGbl_RootTableList.Tables = NULL;
637     AcpiGbl_RootTableList.Flags = 0;
638     AcpiGbl_RootTableList.CurrentTableCount = 0;
639 
640     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
641     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
642 }
643 
644 
645 /*******************************************************************************
646  *
647  * FUNCTION:    AcpiTbDeleteNamespaceByOwner
648  *
649  * PARAMETERS:  TableIndex          - Table index
650  *
651  * RETURN:      Status
652  *
653  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
654  *
655  ******************************************************************************/
656 
657 ACPI_STATUS
658 AcpiTbDeleteNamespaceByOwner (
659     UINT32                  TableIndex)
660 {
661     ACPI_OWNER_ID           OwnerId;
662     ACPI_STATUS             Status;
663 
664 
665     ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
666 
667 
668     Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
669     if (ACPI_FAILURE (Status))
670     {
671         return_ACPI_STATUS (Status);
672     }
673 
674     if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
675     {
676         /* The table index does not exist */
677 
678         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
679         return_ACPI_STATUS (AE_NOT_EXIST);
680     }
681 
682     /* Get the owner ID for this table, used to delete namespace nodes */
683 
684     OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
685     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
686 
687     /*
688      * Need to acquire the namespace writer lock to prevent interference
689      * with any concurrent namespace walks. The interpreter must be
690      * released during the deletion since the acquisition of the deletion
691      * lock may block, and also since the execution of a namespace walk
692      * must be allowed to use the interpreter.
693      */
694     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
695     Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
696 
697     AcpiNsDeleteNamespaceByOwner (OwnerId);
698     if (ACPI_FAILURE (Status))
699     {
700         return_ACPI_STATUS (Status);
701     }
702 
703     AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
704 
705     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
706     return_ACPI_STATUS (Status);
707 }
708 
709 
710 /*******************************************************************************
711  *
712  * FUNCTION:    AcpiTbAllocateOwnerId
713  *
714  * PARAMETERS:  TableIndex          - Table index
715  *
716  * RETURN:      Status
717  *
718  * DESCRIPTION: Allocates OwnerId in TableDesc
719  *
720  ******************************************************************************/
721 
722 ACPI_STATUS
723 AcpiTbAllocateOwnerId (
724     UINT32                  TableIndex)
725 {
726     ACPI_STATUS             Status = AE_BAD_PARAMETER;
727 
728 
729     ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
730 
731 
732     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
733     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
734     {
735         Status = AcpiUtAllocateOwnerId
736                     (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
737     }
738 
739     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
740     return_ACPI_STATUS (Status);
741 }
742 
743 
744 /*******************************************************************************
745  *
746  * FUNCTION:    AcpiTbReleaseOwnerId
747  *
748  * PARAMETERS:  TableIndex          - Table index
749  *
750  * RETURN:      Status
751  *
752  * DESCRIPTION: Releases OwnerId in TableDesc
753  *
754  ******************************************************************************/
755 
756 ACPI_STATUS
757 AcpiTbReleaseOwnerId (
758     UINT32                  TableIndex)
759 {
760     ACPI_STATUS             Status = AE_BAD_PARAMETER;
761 
762 
763     ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
764 
765 
766     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
767     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
768     {
769         AcpiUtReleaseOwnerId (
770             &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
771         Status = AE_OK;
772     }
773 
774     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
775     return_ACPI_STATUS (Status);
776 }
777 
778 
779 /*******************************************************************************
780  *
781  * FUNCTION:    AcpiTbGetOwnerId
782  *
783  * PARAMETERS:  TableIndex          - Table index
784  *              OwnerId             - Where the table OwnerId is returned
785  *
786  * RETURN:      Status
787  *
788  * DESCRIPTION: returns OwnerId for the ACPI table
789  *
790  ******************************************************************************/
791 
792 ACPI_STATUS
793 AcpiTbGetOwnerId (
794     UINT32                  TableIndex,
795     ACPI_OWNER_ID           *OwnerId)
796 {
797     ACPI_STATUS             Status = AE_BAD_PARAMETER;
798 
799 
800     ACPI_FUNCTION_TRACE (TbGetOwnerId);
801 
802 
803     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
804     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
805     {
806         *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
807         Status = AE_OK;
808     }
809 
810     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
811     return_ACPI_STATUS (Status);
812 }
813 
814 
815 /*******************************************************************************
816  *
817  * FUNCTION:    AcpiTbIsTableLoaded
818  *
819  * PARAMETERS:  TableIndex          - Table index
820  *
821  * RETURN:      Table Loaded Flag
822  *
823  ******************************************************************************/
824 
825 BOOLEAN
826 AcpiTbIsTableLoaded (
827     UINT32                  TableIndex)
828 {
829     BOOLEAN                 IsLoaded = FALSE;
830 
831 
832     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
833     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
834     {
835         IsLoaded = (BOOLEAN)
836             (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
837             ACPI_TABLE_IS_LOADED);
838     }
839 
840     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
841     return (IsLoaded);
842 }
843 
844 
845 /*******************************************************************************
846  *
847  * FUNCTION:    AcpiTbSetTableLoadedFlag
848  *
849  * PARAMETERS:  TableIndex          - Table index
850  *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
851  *
852  * RETURN:      None
853  *
854  * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
855  *
856  ******************************************************************************/
857 
858 void
859 AcpiTbSetTableLoadedFlag (
860     UINT32                  TableIndex,
861     BOOLEAN                 IsLoaded)
862 {
863 
864     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
865     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
866     {
867         if (IsLoaded)
868         {
869             AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
870                 ACPI_TABLE_IS_LOADED;
871         }
872         else
873         {
874             AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
875                 ~ACPI_TABLE_IS_LOADED;
876         }
877     }
878 
879     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
880 }
881 
882