tbinstal.c revision 241973
177298Sobrien/******************************************************************************
2104834Sobrien *
377298Sobrien * Module Name: tbinstal - ACPI table installation and removal
477298Sobrien *
589857Sobrien *****************************************************************************/
677298Sobrien
789857Sobrien/*
877298Sobrien * Copyright (C) 2000 - 2012, Intel Corp.
977298Sobrien * All rights reserved.
1077298Sobrien *
1177298Sobrien * Redistribution and use in source and binary forms, with or without
1289857Sobrien * modification, are permitted provided that the following conditions
1377298Sobrien * are met:
1477298Sobrien * 1. Redistributions of source code must retain the above copyright
1577298Sobrien *    notice, this list of conditions, and the following disclaimer,
1677298Sobrien *    without modification.
1777298Sobrien * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1889857Sobrien *    substantially similar to the "NO WARRANTY" disclaimer below
19218822Sdim *    ("Disclaimer") and any redistribution must be conditioned upon
20218822Sdim *    including a substantially similar Disclaimer requirement for further
2177298Sobrien *    binary redistribution.
2277298Sobrien * 3. Neither the names of the above-listed copyright holders nor the names
2377298Sobrien *    of any contributors may be used to endorse or promote products derived
2477298Sobrien *    from this software without specific prior written permission.
2577298Sobrien *
2677298Sobrien * Alternatively, this software may be distributed under the terms of the
2777298Sobrien * GNU General Public License ("GPL") version 2 as published by the Free
2877298Sobrien * Software Foundation.
2977298Sobrien *
3077298Sobrien * NO WARRANTY
3177298Sobrien * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3277298Sobrien * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3377298Sobrien * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34104834Sobrien * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3577298Sobrien * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3677298Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3777298Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38218822Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3977298Sobrien * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4077298Sobrien * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4177298Sobrien * POSSIBILITY OF SUCH DAMAGES.
4277298Sobrien */
4377298Sobrien
4477298Sobrien
4577298Sobrien#define __TBINSTAL_C__
4677298Sobrien
4777298Sobrien#include <contrib/dev/acpica/include/acpi.h>
4877298Sobrien#include <contrib/dev/acpica/include/accommon.h>
49#include <contrib/dev/acpica/include/acnamesp.h>
50#include <contrib/dev/acpica/include/actables.h>
51
52
53#define _COMPONENT          ACPI_TABLES
54        ACPI_MODULE_NAME    ("tbinstal")
55
56
57/******************************************************************************
58 *
59 * FUNCTION:    AcpiTbVerifyTable
60 *
61 * PARAMETERS:  TableDesc           - table
62 *
63 * RETURN:      Status
64 *
65 * DESCRIPTION: this function is called to verify and map table
66 *
67 *****************************************************************************/
68
69ACPI_STATUS
70AcpiTbVerifyTable (
71    ACPI_TABLE_DESC         *TableDesc)
72{
73    ACPI_STATUS             Status = AE_OK;
74
75
76    ACPI_FUNCTION_TRACE (TbVerifyTable);
77
78
79    /* Map the table if necessary */
80
81    if (!TableDesc->Pointer)
82    {
83        if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
84            ACPI_TABLE_ORIGIN_MAPPED)
85        {
86            TableDesc->Pointer = AcpiOsMapMemory (
87                TableDesc->Address, TableDesc->Length);
88        }
89
90        if (!TableDesc->Pointer)
91        {
92            return_ACPI_STATUS (AE_NO_MEMORY);
93        }
94    }
95
96    /* FACS is the odd table, has no standard ACPI header and no checksum */
97
98    if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
99    {
100        /* Always calculate checksum, ignore bad checksum if requested */
101
102        Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
103    }
104
105    return_ACPI_STATUS (Status);
106}
107
108
109/*******************************************************************************
110 *
111 * FUNCTION:    AcpiTbAddTable
112 *
113 * PARAMETERS:  TableDesc           - Table descriptor
114 *              TableIndex          - Where the table index is returned
115 *
116 * RETURN:      Status
117 *
118 * DESCRIPTION: This function is called to add an ACPI table. It is used to
119 *              dynamically load tables via the Load and LoadTable AML
120 *              operators.
121 *
122 ******************************************************************************/
123
124ACPI_STATUS
125AcpiTbAddTable (
126    ACPI_TABLE_DESC         *TableDesc,
127    UINT32                  *TableIndex)
128{
129    UINT32                  i;
130    ACPI_STATUS             Status = AE_OK;
131
132
133    ACPI_FUNCTION_TRACE (TbAddTable);
134
135
136    if (!TableDesc->Pointer)
137    {
138        Status = AcpiTbVerifyTable (TableDesc);
139        if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
140        {
141            return_ACPI_STATUS (Status);
142        }
143    }
144
145    /*
146     * Validate the incoming table signature.
147     *
148     * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
149     * 2) We added support for OEMx tables, signature "OEM".
150     * 3) Valid tables were encountered with a null signature, so we just
151     *    gave up on validating the signature, (05/2008).
152     * 4) We encountered non-AML tables such as the MADT, which caused
153     *    interpreter errors and kernel faults. So now, we once again allow
154     *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
155     */
156    if ((TableDesc->Pointer->Signature[0] != 0x00) &&
157       (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
158       (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
159    {
160        ACPI_BIOS_ERROR ((AE_INFO,
161            "Table has invalid signature [%4.4s] (0x%8.8X), "
162            "must be SSDT or OEMx",
163            AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ?
164                TableDesc->Pointer->Signature : "????",
165            *(UINT32 *) TableDesc->Pointer->Signature));
166
167        return_ACPI_STATUS (AE_BAD_SIGNATURE);
168    }
169
170    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
171
172    /* Check if table is already registered */
173
174    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
175    {
176        if (!AcpiGbl_RootTableList.Tables[i].Pointer)
177        {
178            Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
179            if (ACPI_FAILURE (Status) ||
180                !AcpiGbl_RootTableList.Tables[i].Pointer)
181            {
182                continue;
183            }
184        }
185
186        /*
187         * Check for a table match on the entire table length,
188         * not just the header.
189         */
190        if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
191        {
192            continue;
193        }
194
195        if (ACPI_MEMCMP (TableDesc->Pointer,
196                AcpiGbl_RootTableList.Tables[i].Pointer,
197                AcpiGbl_RootTableList.Tables[i].Length))
198        {
199            continue;
200        }
201
202        /*
203         * Note: the current mechanism does not unregister a table if it is
204         * dynamically unloaded. The related namespace entries are deleted,
205         * but the table remains in the root table list.
206         *
207         * The assumption here is that the number of different tables that
208         * will be loaded is actually small, and there is minimal overhead
209         * in just keeping the table in case it is needed again.
210         *
211         * If this assumption changes in the future (perhaps on large
212         * machines with many table load/unload operations), tables will
213         * need to be unregistered when they are unloaded, and slots in the
214         * root table list should be reused when empty.
215         */
216
217        /*
218         * Table is already registered.
219         * We can delete the table that was passed as a parameter.
220         */
221        AcpiTbDeleteTable (TableDesc);
222        *TableIndex = i;
223
224        if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
225        {
226            /* Table is still loaded, this is an error */
227
228            Status = AE_ALREADY_EXISTS;
229            goto Release;
230        }
231        else
232        {
233            /* Table was unloaded, allow it to be reloaded */
234
235            TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
236            TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
237            Status = AE_OK;
238            goto PrintHeader;
239        }
240    }
241
242    /*
243     * ACPI Table Override:
244     * Allow the host to override dynamically loaded tables.
245     * NOTE: the table is fully mapped at this point, and the mapping will
246     * be deleted by TbTableOverride if the table is actually overridden.
247     */
248    (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc);
249
250    /* Add the table to the global root table list */
251
252    Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
253                TableDesc->Length, TableDesc->Flags, TableIndex);
254    if (ACPI_FAILURE (Status))
255    {
256        goto Release;
257    }
258
259PrintHeader:
260    AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
261
262Release:
263    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
264    return_ACPI_STATUS (Status);
265}
266
267
268/*******************************************************************************
269 *
270 * FUNCTION:    AcpiTbTableOverride
271 *
272 * PARAMETERS:  TableHeader         - Header for the original table
273 *              TableDesc           - Table descriptor initialized for the
274 *                                    original table. May or may not be mapped.
275 *
276 * RETURN:      Pointer to the entire new table. NULL if table not overridden.
277 *              If overridden, installs the new table within the input table
278 *              descriptor.
279 *
280 * DESCRIPTION: Attempt table override by calling the OSL override functions.
281 *              Note: If the table is overridden, then the entire new table
282 *              is mapped and returned by this function.
283 *
284 ******************************************************************************/
285
286ACPI_TABLE_HEADER *
287AcpiTbTableOverride (
288    ACPI_TABLE_HEADER       *TableHeader,
289    ACPI_TABLE_DESC         *TableDesc)
290{
291    ACPI_STATUS             Status;
292    ACPI_TABLE_HEADER       *NewTable = NULL;
293    ACPI_PHYSICAL_ADDRESS   NewAddress = 0;
294    UINT32                  NewTableLength = 0;
295    UINT8                   NewFlags;
296    char                    *OverrideType;
297
298
299    /* (1) Attempt logical override (returns a logical address) */
300
301    Status = AcpiOsTableOverride (TableHeader, &NewTable);
302    if (ACPI_SUCCESS (Status) && NewTable)
303    {
304        NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable);
305        NewTableLength = NewTable->Length;
306        NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE;
307        OverrideType = "Logical";
308        goto FinishOverride;
309    }
310
311    /* (2) Attempt physical override (returns a physical address) */
312
313    Status = AcpiOsPhysicalTableOverride (TableHeader,
314        &NewAddress, &NewTableLength);
315    if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
316    {
317        /* Map the entire new table */
318
319        NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
320        if (!NewTable)
321        {
322            ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
323                "%4.4s %p Attempted physical table override failed",
324                TableHeader->Signature,
325                ACPI_CAST_PTR (void, TableDesc->Address)));
326            return (NULL);
327        }
328
329        OverrideType = "Physical";
330        NewFlags = ACPI_TABLE_ORIGIN_MAPPED;
331        goto FinishOverride;
332    }
333
334    return (NULL); /* There was no override */
335
336
337FinishOverride:
338
339    ACPI_INFO ((AE_INFO,
340        "%4.4s %p %s table override, new table: %p",
341        TableHeader->Signature,
342        ACPI_CAST_PTR (void, TableDesc->Address),
343        OverrideType, NewTable));
344
345    /* We can now unmap/delete the original table (if fully mapped) */
346
347    AcpiTbDeleteTable (TableDesc);
348
349    /* Setup descriptor for the new table */
350
351    TableDesc->Address = NewAddress;
352    TableDesc->Pointer = NewTable;
353    TableDesc->Length = NewTableLength;
354    TableDesc->Flags = NewFlags;
355
356    return (NewTable);
357}
358
359
360/*******************************************************************************
361 *
362 * FUNCTION:    AcpiTbResizeRootTableList
363 *
364 * PARAMETERS:  None
365 *
366 * RETURN:      Status
367 *
368 * DESCRIPTION: Expand the size of global table array
369 *
370 ******************************************************************************/
371
372ACPI_STATUS
373AcpiTbResizeRootTableList (
374    void)
375{
376    ACPI_TABLE_DESC         *Tables;
377    UINT32                  TableCount;
378
379
380    ACPI_FUNCTION_TRACE (TbResizeRootTableList);
381
382
383    /* AllowResize flag is a parameter to AcpiInitializeTables */
384
385    if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
386    {
387        ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
388        return_ACPI_STATUS (AE_SUPPORT);
389    }
390
391    /* Increase the Table Array size */
392
393    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
394    {
395        TableCount = AcpiGbl_RootTableList.MaxTableCount;
396    }
397    else
398    {
399        TableCount = AcpiGbl_RootTableList.CurrentTableCount;
400    }
401
402    Tables = ACPI_ALLOCATE_ZEROED (
403        ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
404        sizeof (ACPI_TABLE_DESC));
405    if (!Tables)
406    {
407        ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
408        return_ACPI_STATUS (AE_NO_MEMORY);
409    }
410
411    /* Copy and free the previous table array */
412
413    if (AcpiGbl_RootTableList.Tables)
414    {
415        ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
416            (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
417
418        if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
419        {
420            ACPI_FREE (AcpiGbl_RootTableList.Tables);
421        }
422    }
423
424    AcpiGbl_RootTableList.Tables = Tables;
425    AcpiGbl_RootTableList.MaxTableCount =
426        TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
427    AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
428
429    return_ACPI_STATUS (AE_OK);
430}
431
432
433/*******************************************************************************
434 *
435 * FUNCTION:    AcpiTbStoreTable
436 *
437 * PARAMETERS:  Address             - Table address
438 *              Table               - Table header
439 *              Length              - Table length
440 *              Flags               - flags
441 *
442 * RETURN:      Status and table index.
443 *
444 * DESCRIPTION: Add an ACPI table to the global table list
445 *
446 ******************************************************************************/
447
448ACPI_STATUS
449AcpiTbStoreTable (
450    ACPI_PHYSICAL_ADDRESS   Address,
451    ACPI_TABLE_HEADER       *Table,
452    UINT32                  Length,
453    UINT8                   Flags,
454    UINT32                  *TableIndex)
455{
456    ACPI_STATUS             Status;
457    ACPI_TABLE_DESC         *NewTable;
458
459
460    /* Ensure that there is room for the table in the Root Table List */
461
462    if (AcpiGbl_RootTableList.CurrentTableCount >=
463        AcpiGbl_RootTableList.MaxTableCount)
464    {
465        Status = AcpiTbResizeRootTableList();
466        if (ACPI_FAILURE (Status))
467        {
468            return (Status);
469        }
470    }
471
472    NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount];
473
474    /* Initialize added table */
475
476    NewTable->Address = Address;
477    NewTable->Pointer = Table;
478    NewTable->Length = Length;
479    NewTable->OwnerId = 0;
480    NewTable->Flags = Flags;
481
482    ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature);
483
484    *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
485    AcpiGbl_RootTableList.CurrentTableCount++;
486    return (AE_OK);
487}
488
489
490/*******************************************************************************
491 *
492 * FUNCTION:    AcpiTbDeleteTable
493 *
494 * PARAMETERS:  TableIndex          - Table index
495 *
496 * RETURN:      None
497 *
498 * DESCRIPTION: Delete one internal ACPI table
499 *
500 ******************************************************************************/
501
502void
503AcpiTbDeleteTable (
504    ACPI_TABLE_DESC         *TableDesc)
505{
506
507    /* Table must be mapped or allocated */
508
509    if (!TableDesc->Pointer)
510    {
511        return;
512    }
513
514    switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
515    {
516    case ACPI_TABLE_ORIGIN_MAPPED:
517        AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
518        break;
519
520    case ACPI_TABLE_ORIGIN_ALLOCATED:
521        ACPI_FREE (TableDesc->Pointer);
522        break;
523
524    /* Not mapped or allocated, there is nothing we can do */
525
526    default:
527        return;
528    }
529
530    TableDesc->Pointer = NULL;
531}
532
533
534/*******************************************************************************
535 *
536 * FUNCTION:    AcpiTbTerminate
537 *
538 * PARAMETERS:  None
539 *
540 * RETURN:      None
541 *
542 * DESCRIPTION: Delete all internal ACPI tables
543 *
544 ******************************************************************************/
545
546void
547AcpiTbTerminate (
548    void)
549{
550    UINT32                  i;
551
552
553    ACPI_FUNCTION_TRACE (TbTerminate);
554
555
556    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
557
558    /* Delete the individual tables */
559
560    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
561    {
562        AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
563    }
564
565    /*
566     * Delete the root table array if allocated locally. Array cannot be
567     * mapped, so we don't need to check for that flag.
568     */
569    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
570    {
571        ACPI_FREE (AcpiGbl_RootTableList.Tables);
572    }
573
574    AcpiGbl_RootTableList.Tables = NULL;
575    AcpiGbl_RootTableList.Flags = 0;
576    AcpiGbl_RootTableList.CurrentTableCount = 0;
577
578    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
579    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
580
581    return_VOID;
582}
583
584
585/*******************************************************************************
586 *
587 * FUNCTION:    AcpiTbDeleteNamespaceByOwner
588 *
589 * PARAMETERS:  TableIndex          - Table index
590 *
591 * RETURN:      Status
592 *
593 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
594 *
595 ******************************************************************************/
596
597ACPI_STATUS
598AcpiTbDeleteNamespaceByOwner (
599    UINT32                  TableIndex)
600{
601    ACPI_OWNER_ID           OwnerId;
602    ACPI_STATUS             Status;
603
604
605    ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
606
607
608    Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
609    if (ACPI_FAILURE (Status))
610    {
611        return_ACPI_STATUS (Status);
612    }
613
614    if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
615    {
616        /* The table index does not exist */
617
618        (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
619        return_ACPI_STATUS (AE_NOT_EXIST);
620    }
621
622    /* Get the owner ID for this table, used to delete namespace nodes */
623
624    OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
625    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
626
627    /*
628     * Need to acquire the namespace writer lock to prevent interference
629     * with any concurrent namespace walks. The interpreter must be
630     * released during the deletion since the acquisition of the deletion
631     * lock may block, and also since the execution of a namespace walk
632     * must be allowed to use the interpreter.
633     */
634    (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
635    Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
636
637    AcpiNsDeleteNamespaceByOwner (OwnerId);
638    if (ACPI_FAILURE (Status))
639    {
640        return_ACPI_STATUS (Status);
641    }
642
643    AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
644
645    Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
646    return_ACPI_STATUS (Status);
647}
648
649
650/*******************************************************************************
651 *
652 * FUNCTION:    AcpiTbAllocateOwnerId
653 *
654 * PARAMETERS:  TableIndex          - Table index
655 *
656 * RETURN:      Status
657 *
658 * DESCRIPTION: Allocates OwnerId in TableDesc
659 *
660 ******************************************************************************/
661
662ACPI_STATUS
663AcpiTbAllocateOwnerId (
664    UINT32                  TableIndex)
665{
666    ACPI_STATUS             Status = AE_BAD_PARAMETER;
667
668
669    ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
670
671
672    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
673    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
674    {
675        Status = AcpiUtAllocateOwnerId
676                    (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
677    }
678
679    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
680    return_ACPI_STATUS (Status);
681}
682
683
684/*******************************************************************************
685 *
686 * FUNCTION:    AcpiTbReleaseOwnerId
687 *
688 * PARAMETERS:  TableIndex          - Table index
689 *
690 * RETURN:      Status
691 *
692 * DESCRIPTION: Releases OwnerId in TableDesc
693 *
694 ******************************************************************************/
695
696ACPI_STATUS
697AcpiTbReleaseOwnerId (
698    UINT32                  TableIndex)
699{
700    ACPI_STATUS             Status = AE_BAD_PARAMETER;
701
702
703    ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
704
705
706    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
707    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
708    {
709        AcpiUtReleaseOwnerId (
710            &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
711        Status = AE_OK;
712    }
713
714    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
715    return_ACPI_STATUS (Status);
716}
717
718
719/*******************************************************************************
720 *
721 * FUNCTION:    AcpiTbGetOwnerId
722 *
723 * PARAMETERS:  TableIndex          - Table index
724 *              OwnerId             - Where the table OwnerId is returned
725 *
726 * RETURN:      Status
727 *
728 * DESCRIPTION: returns OwnerId for the ACPI table
729 *
730 ******************************************************************************/
731
732ACPI_STATUS
733AcpiTbGetOwnerId (
734    UINT32                  TableIndex,
735    ACPI_OWNER_ID           *OwnerId)
736{
737    ACPI_STATUS             Status = AE_BAD_PARAMETER;
738
739
740    ACPI_FUNCTION_TRACE (TbGetOwnerId);
741
742
743    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
744    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
745    {
746        *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
747        Status = AE_OK;
748    }
749
750    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
751    return_ACPI_STATUS (Status);
752}
753
754
755/*******************************************************************************
756 *
757 * FUNCTION:    AcpiTbIsTableLoaded
758 *
759 * PARAMETERS:  TableIndex          - Table index
760 *
761 * RETURN:      Table Loaded Flag
762 *
763 ******************************************************************************/
764
765BOOLEAN
766AcpiTbIsTableLoaded (
767    UINT32                  TableIndex)
768{
769    BOOLEAN                 IsLoaded = FALSE;
770
771
772    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
773    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
774    {
775        IsLoaded = (BOOLEAN)
776            (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
777            ACPI_TABLE_IS_LOADED);
778    }
779
780    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
781    return (IsLoaded);
782}
783
784
785/*******************************************************************************
786 *
787 * FUNCTION:    AcpiTbSetTableLoadedFlag
788 *
789 * PARAMETERS:  TableIndex          - Table index
790 *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
791 *
792 * RETURN:      None
793 *
794 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
795 *
796 ******************************************************************************/
797
798void
799AcpiTbSetTableLoadedFlag (
800    UINT32                  TableIndex,
801    BOOLEAN                 IsLoaded)
802{
803
804    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
805    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
806    {
807        if (IsLoaded)
808        {
809            AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
810                ACPI_TABLE_IS_LOADED;
811        }
812        else
813        {
814            AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
815                ~ACPI_TABLE_IS_LOADED;
816        }
817    }
818
819    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
820}
821