167754Smsmith/******************************************************************************
267754Smsmith *
3249112Sjkim * Module Name: tbxface - ACPI table-oriented external interfaces
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2567754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2967754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4367754Smsmith
44281075Sdim#define EXPORT_ACPI_INTERFACES
4567754Smsmith
46193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
47193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
48193341Sjkim#include <contrib/dev/acpica/include/actables.h>
4967754Smsmith
5077424Smsmith#define _COMPONENT          ACPI_TABLES
5191116Smsmith        ACPI_MODULE_NAME    ("tbxface")
5267754Smsmith
5367754Smsmith
5467754Smsmith/*******************************************************************************
5567754Smsmith *
56167802Sjkim * FUNCTION:    AcpiAllocateRootTable
5767754Smsmith *
58167802Sjkim * PARAMETERS:  InitialTableCount   - Size of InitialTableArray, in number of
59167802Sjkim *                                    ACPI_TABLE_DESC structures
6067754Smsmith *
6167754Smsmith * RETURN:      Status
6267754Smsmith *
63167802Sjkim * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
64167802Sjkim *              AcpiInitializeTables.
6567754Smsmith *
6667754Smsmith ******************************************************************************/
6767754Smsmith
6867754SmsmithACPI_STATUS
69167802SjkimAcpiAllocateRootTable (
70167802Sjkim    UINT32                  InitialTableCount)
7167754Smsmith{
7267754Smsmith
73207344Sjkim    AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
74167802Sjkim    AcpiGbl_RootTableList.Flags = ACPI_ROOT_ALLOW_RESIZE;
7567754Smsmith
76167802Sjkim    return (AcpiTbResizeRootTableList ());
77167802Sjkim}
7867754Smsmith
7967754Smsmith
80167802Sjkim/*******************************************************************************
81167802Sjkim *
82167802Sjkim * FUNCTION:    AcpiInitializeTables
83167802Sjkim *
84167802Sjkim * PARAMETERS:  InitialTableArray   - Pointer to an array of pre-allocated
85167802Sjkim *                                    ACPI_TABLE_DESC structures. If NULL, the
86167802Sjkim *                                    array is dynamically allocated.
87167802Sjkim *              InitialTableCount   - Size of InitialTableArray, in number of
88167802Sjkim *                                    ACPI_TABLE_DESC structures
89249112Sjkim *              AllowResize         - Flag to tell Table Manager if resize of
90167802Sjkim *                                    pre-allocated array is allowed. Ignored
91167802Sjkim *                                    if InitialTableArray is NULL.
92167802Sjkim *
93167802Sjkim * RETURN:      Status
94167802Sjkim *
95167802Sjkim * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
96167802Sjkim *
97167802Sjkim * NOTE:        Allows static allocation of the initial table array in order
98167802Sjkim *              to avoid the use of dynamic memory in confined environments
99167802Sjkim *              such as the kernel boot sequence where it may not be available.
100167802Sjkim *
101167802Sjkim *              If the host OS memory managers are initialized, use NULL for
102167802Sjkim *              InitialTableArray, and the table will be dynamically allocated.
103167802Sjkim *
104167802Sjkim ******************************************************************************/
10580062Smsmith
106167802SjkimACPI_STATUS
107167802SjkimAcpiInitializeTables (
108167802Sjkim    ACPI_TABLE_DESC         *InitialTableArray,
109167802Sjkim    UINT32                  InitialTableCount,
110167802Sjkim    BOOLEAN                 AllowResize)
111167802Sjkim{
112167802Sjkim    ACPI_PHYSICAL_ADDRESS   RsdpAddress;
113167802Sjkim    ACPI_STATUS             Status;
11480062Smsmith
11567754Smsmith
116167802Sjkim    ACPI_FUNCTION_TRACE (AcpiInitializeTables);
11799146Siwasaki
118167802Sjkim
119167802Sjkim    /*
120249112Sjkim     * Setup the Root Table Array and allocate the table array
121249112Sjkim     * if requested
122167802Sjkim     */
123167802Sjkim    if (!InitialTableArray)
12467754Smsmith    {
125167802Sjkim        Status = AcpiAllocateRootTable (InitialTableCount);
126167802Sjkim        if (ACPI_FAILURE (Status))
127167802Sjkim        {
128167802Sjkim            return_ACPI_STATUS (Status);
129167802Sjkim        }
13067754Smsmith    }
131167802Sjkim    else
13267754Smsmith    {
133167802Sjkim        /* Root Table Array has been statically allocated by the host */
13467754Smsmith
135306536Sjkim        memset (InitialTableArray, 0,
136193267Sjkim            (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC));
13767754Smsmith
138167802Sjkim        AcpiGbl_RootTableList.Tables = InitialTableArray;
139207344Sjkim        AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
140167802Sjkim        AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN;
141167802Sjkim        if (AllowResize)
142167802Sjkim        {
143167802Sjkim            AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
144167802Sjkim        }
14567754Smsmith    }
14667754Smsmith
147167802Sjkim    /* Get the address of the RSDP */
14867754Smsmith
149167802Sjkim    RsdpAddress = AcpiOsGetRootPointer ();
150167802Sjkim    if (!RsdpAddress)
15167754Smsmith    {
152167802Sjkim        return_ACPI_STATUS (AE_NOT_FOUND);
15367754Smsmith    }
15467754Smsmith
155167802Sjkim    /*
156167802Sjkim     * Get the root table (RSDT or XSDT) and extract all entries to the local
157167802Sjkim     * Root Table Array. This array contains the information of the RSDT/XSDT
158167802Sjkim     * in a common, more useable format.
159167802Sjkim     */
160193267Sjkim    Status = AcpiTbParseRootTable (RsdpAddress);
16167754Smsmith    return_ACPI_STATUS (Status);
16267754Smsmith}
16367754Smsmith
164281075SdimACPI_EXPORT_SYMBOL_INIT (AcpiInitializeTables)
16567754Smsmith
166167802Sjkim
16767754Smsmith/*******************************************************************************
16867754Smsmith *
169167802Sjkim * FUNCTION:    AcpiReallocateRootTable
17067754Smsmith *
171167802Sjkim * PARAMETERS:  None
17267754Smsmith *
17367754Smsmith * RETURN:      Status
17467754Smsmith *
175167802Sjkim * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
176167802Sjkim *              root list from the previously provided scratch area. Should
177167802Sjkim *              be called once dynamic memory allocation is available in the
178240716Sjkim *              kernel.
17967754Smsmith *
18067754Smsmith ******************************************************************************/
18167754Smsmith
18267754SmsmithACPI_STATUS
183167802SjkimAcpiReallocateRootTable (
184167802Sjkim    void)
18567754Smsmith{
186240716Sjkim    ACPI_STATUS             Status;
18767754Smsmith
18867754Smsmith
189167802Sjkim    ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
19067754Smsmith
19177424Smsmith
192167802Sjkim    /*
193167802Sjkim     * Only reallocate the root table if the host provided a static buffer
194167802Sjkim     * for the table array in the call to AcpiInitializeTables.
195167802Sjkim     */
196167802Sjkim    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
19767754Smsmith    {
198167802Sjkim        return_ACPI_STATUS (AE_SUPPORT);
19967754Smsmith    }
20067754Smsmith
201240716Sjkim    AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
20267754Smsmith
203240716Sjkim    Status = AcpiTbResizeRootTableList ();
204240716Sjkim    return_ACPI_STATUS (Status);
205167802Sjkim}
20667754Smsmith
207281075SdimACPI_EXPORT_SYMBOL_INIT (AcpiReallocateRootTable)
208151937Sjkim
209151937Sjkim
210193267Sjkim/*******************************************************************************
211167802Sjkim *
212167802Sjkim * FUNCTION:    AcpiGetTableHeader
213167802Sjkim *
214167802Sjkim * PARAMETERS:  Signature           - ACPI signature of needed table
215167802Sjkim *              Instance            - Which instance (for SSDTs)
216167802Sjkim *              OutTableHeader      - The pointer to the table header to fill
217167802Sjkim *
218167802Sjkim * RETURN:      Status and pointer to mapped table header
219167802Sjkim *
220167802Sjkim * DESCRIPTION: Finds an ACPI table header.
221167802Sjkim *
222167802Sjkim * NOTE:        Caller is responsible in unmapping the header with
223167802Sjkim *              AcpiOsUnmapMemory
224167802Sjkim *
225193267Sjkim ******************************************************************************/
22667754Smsmith
227167802SjkimACPI_STATUS
228167802SjkimAcpiGetTableHeader (
229167802Sjkim    char                    *Signature,
230193267Sjkim    UINT32                  Instance,
231167802Sjkim    ACPI_TABLE_HEADER       *OutTableHeader)
232167802Sjkim{
233193267Sjkim    UINT32                  i;
234193267Sjkim    UINT32                  j;
235167802Sjkim    ACPI_TABLE_HEADER       *Header;
23667754Smsmith
23767754Smsmith
238167802Sjkim    /* Parameter validation */
239167802Sjkim
240167802Sjkim    if (!Signature || !OutTableHeader)
24191116Smsmith    {
242167802Sjkim        return (AE_BAD_PARAMETER);
243167802Sjkim    }
24491116Smsmith
245193267Sjkim    /* Walk the root table list */
246193267Sjkim
247207344Sjkim    for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
248167802Sjkim    {
249306536Sjkim        if (!ACPI_COMPARE_NAME (
250306536Sjkim                &(AcpiGbl_RootTableList.Tables[i].Signature), Signature))
251167802Sjkim        {
252167802Sjkim            continue;
253167802Sjkim        }
25491116Smsmith
255167802Sjkim        if (++j < Instance)
256167802Sjkim        {
257167802Sjkim            continue;
258167802Sjkim        }
25991116Smsmith
260167802Sjkim        if (!AcpiGbl_RootTableList.Tables[i].Pointer)
261167802Sjkim        {
262193267Sjkim            if ((AcpiGbl_RootTableList.Tables[i].Flags &
263193267Sjkim                    ACPI_TABLE_ORIGIN_MASK) ==
264281075Sdim                ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL)
265167802Sjkim            {
266193267Sjkim                Header = AcpiOsMapMemory (
267306536Sjkim                    AcpiGbl_RootTableList.Tables[i].Address,
268306536Sjkim                    sizeof (ACPI_TABLE_HEADER));
269167802Sjkim                if (!Header)
270167802Sjkim                {
271241973Sjkim                    return (AE_NO_MEMORY);
272167802Sjkim                }
27391116Smsmith
274306536Sjkim                memcpy (OutTableHeader, Header, sizeof (ACPI_TABLE_HEADER));
275241973Sjkim                AcpiOsUnmapMemory (Header, sizeof (ACPI_TABLE_HEADER));
276167802Sjkim            }
277167802Sjkim            else
278167802Sjkim            {
279241973Sjkim                return (AE_NOT_FOUND);
280167802Sjkim            }
281167802Sjkim        }
282167802Sjkim        else
283167802Sjkim        {
284306536Sjkim            memcpy (OutTableHeader,
285193267Sjkim                AcpiGbl_RootTableList.Tables[i].Pointer,
286241973Sjkim                sizeof (ACPI_TABLE_HEADER));
287167802Sjkim        }
28867754Smsmith
289167802Sjkim        return (AE_OK);
29067754Smsmith    }
29167754Smsmith
292167802Sjkim    return (AE_NOT_FOUND);
29367754Smsmith}
29467754Smsmith
295167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
29667754Smsmith
297167802Sjkim
298193267Sjkim/*******************************************************************************
29967754Smsmith *
300167802Sjkim * FUNCTION:    AcpiGetTable
30167754Smsmith *
302167802Sjkim * PARAMETERS:  Signature           - ACPI signature of needed table
303167802Sjkim *              Instance            - Which instance (for SSDTs)
304167802Sjkim *              OutTable            - Where the pointer to the table is returned
30567754Smsmith *
306249112Sjkim * RETURN:      Status and pointer to the requested table
30767754Smsmith *
308249112Sjkim * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
309249112Sjkim *              RSDT/XSDT.
31067754Smsmith *
311193267Sjkim ******************************************************************************/
31267754Smsmith
31367754SmsmithACPI_STATUS
314167802SjkimAcpiGetTable (
315167802Sjkim    char                    *Signature,
316193267Sjkim    UINT32                  Instance,
317167802Sjkim    ACPI_TABLE_HEADER       **OutTable)
31867754Smsmith{
319193267Sjkim    UINT32                  i;
320193267Sjkim    UINT32                  j;
321167802Sjkim    ACPI_STATUS             Status;
32267754Smsmith
32367754Smsmith
32467754Smsmith    /* Parameter validation */
32567754Smsmith
326167802Sjkim    if (!Signature || !OutTable)
32767754Smsmith    {
328167802Sjkim        return (AE_BAD_PARAMETER);
32967754Smsmith    }
33067754Smsmith
331193267Sjkim    /* Walk the root table list */
332193267Sjkim
333207344Sjkim    for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
334167802Sjkim    {
335306536Sjkim        if (!ACPI_COMPARE_NAME (
336306536Sjkim                &(AcpiGbl_RootTableList.Tables[i].Signature), Signature))
337167802Sjkim        {
338167802Sjkim            continue;
339167802Sjkim        }
34067754Smsmith
341167802Sjkim        if (++j < Instance)
342167802Sjkim        {
343167802Sjkim            continue;
344167802Sjkim        }
345167802Sjkim
346281075Sdim        Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
347167802Sjkim        if (ACPI_SUCCESS (Status))
348167802Sjkim        {
349167802Sjkim            *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer;
350167802Sjkim        }
351167802Sjkim
352167802Sjkim        return (Status);
353117521Snjl    }
35467754Smsmith
355167802Sjkim    return (AE_NOT_FOUND);
35667754Smsmith}
35767754Smsmith
358167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTable)
35967754Smsmith
360167802Sjkim
36167754Smsmith/*******************************************************************************
36267754Smsmith *
363167802Sjkim * FUNCTION:    AcpiGetTableByIndex
36467754Smsmith *
365167802Sjkim * PARAMETERS:  TableIndex          - Table index
366167802Sjkim *              Table               - Where the pointer to the table is returned
36767754Smsmith *
368249112Sjkim * RETURN:      Status and pointer to the requested table
36967754Smsmith *
370249112Sjkim * DESCRIPTION: Obtain a table by an index into the global table list. Used
371249112Sjkim *              internally also.
37267754Smsmith *
37367754Smsmith ******************************************************************************/
37467754Smsmith
37567754SmsmithACPI_STATUS
376167802SjkimAcpiGetTableByIndex (
377193267Sjkim    UINT32                  TableIndex,
378167802Sjkim    ACPI_TABLE_HEADER       **Table)
37967754Smsmith{
38067754Smsmith    ACPI_STATUS             Status;
38167754Smsmith
38267754Smsmith
383167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);
38467754Smsmith
38577424Smsmith
386167802Sjkim    /* Parameter validation */
387167802Sjkim
388167802Sjkim    if (!Table)
38967754Smsmith    {
39067754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
39167754Smsmith    }
39267754Smsmith
393167802Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
39467754Smsmith
395167802Sjkim    /* Validate index */
396167802Sjkim
397207344Sjkim    if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
39867754Smsmith    {
399167802Sjkim        (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
40067754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
40167754Smsmith    }
40267754Smsmith
403167802Sjkim    if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer)
40467754Smsmith    {
405167802Sjkim        /* Table is not mapped, map it */
40667754Smsmith
407306536Sjkim        Status = AcpiTbValidateTable (
408306536Sjkim            &AcpiGbl_RootTableList.Tables[TableIndex]);
409167802Sjkim        if (ACPI_FAILURE (Status))
410167802Sjkim        {
411167802Sjkim            (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
412167802Sjkim            return_ACPI_STATUS (Status);
413167802Sjkim        }
41467754Smsmith    }
41567754Smsmith
416167802Sjkim    *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
417167802Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
418167802Sjkim    return_ACPI_STATUS (AE_OK);
419167802Sjkim}
420151937Sjkim
421167802SjkimACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
42267754Smsmith
42367754Smsmith
42467754Smsmith/*******************************************************************************
42567754Smsmith *
426193267Sjkim * FUNCTION:    AcpiInstallTableHandler
427193267Sjkim *
428193267Sjkim * PARAMETERS:  Handler         - Table event handler
429193267Sjkim *              Context         - Value passed to the handler on each event
430193267Sjkim *
431193267Sjkim * RETURN:      Status
432193267Sjkim *
433249112Sjkim * DESCRIPTION: Install a global table event handler.
434193267Sjkim *
435193267Sjkim ******************************************************************************/
436193267Sjkim
437193267SjkimACPI_STATUS
438193267SjkimAcpiInstallTableHandler (
439193267Sjkim    ACPI_TABLE_HANDLER      Handler,
440193267Sjkim    void                    *Context)
441193267Sjkim{
442193267Sjkim    ACPI_STATUS             Status;
443193267Sjkim
444193267Sjkim
445193267Sjkim    ACPI_FUNCTION_TRACE (AcpiInstallTableHandler);
446193267Sjkim
447193267Sjkim
448193267Sjkim    if (!Handler)
449193267Sjkim    {
450193267Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
451193267Sjkim    }
452193267Sjkim
453193267Sjkim    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
454193267Sjkim    if (ACPI_FAILURE (Status))
455193267Sjkim    {
456193267Sjkim        return_ACPI_STATUS (Status);
457193267Sjkim    }
458193267Sjkim
459193267Sjkim    /* Don't allow more than one handler */
460193267Sjkim
461193267Sjkim    if (AcpiGbl_TableHandler)
462193267Sjkim    {
463193267Sjkim        Status = AE_ALREADY_EXISTS;
464193267Sjkim        goto Cleanup;
465193267Sjkim    }
466193267Sjkim
467193267Sjkim    /* Install the handler */
468193267Sjkim
469193267Sjkim    AcpiGbl_TableHandler = Handler;
470193267Sjkim    AcpiGbl_TableHandlerContext = Context;
471193267Sjkim
472193267SjkimCleanup:
473193267Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
474193267Sjkim    return_ACPI_STATUS (Status);
475193267Sjkim}
476193267Sjkim
477193267SjkimACPI_EXPORT_SYMBOL (AcpiInstallTableHandler)
478193267Sjkim
479193267Sjkim
480193267Sjkim/*******************************************************************************
481193267Sjkim *
482193267Sjkim * FUNCTION:    AcpiRemoveTableHandler
483193267Sjkim *
484193267Sjkim * PARAMETERS:  Handler         - Table event handler that was installed
485193267Sjkim *                                previously.
486193267Sjkim *
487193267Sjkim * RETURN:      Status
488193267Sjkim *
489249112Sjkim * DESCRIPTION: Remove a table event handler
490193267Sjkim *
491193267Sjkim ******************************************************************************/
492193267Sjkim
493193267SjkimACPI_STATUS
494193267SjkimAcpiRemoveTableHandler (
495193267Sjkim    ACPI_TABLE_HANDLER      Handler)
496193267Sjkim{
497193267Sjkim    ACPI_STATUS             Status;
498193267Sjkim
499193267Sjkim
500193267Sjkim    ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler);
501193267Sjkim
502193267Sjkim
503193267Sjkim    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
504193267Sjkim    if (ACPI_FAILURE (Status))
505193267Sjkim    {
506193267Sjkim        return_ACPI_STATUS (Status);
507193267Sjkim    }
508193267Sjkim
509193267Sjkim    /* Make sure that the installed handler is the same */
510193267Sjkim
511193267Sjkim    if (!Handler ||
512193267Sjkim        Handler != AcpiGbl_TableHandler)
513193267Sjkim    {
514193267Sjkim        Status = AE_BAD_PARAMETER;
515193267Sjkim        goto Cleanup;
516193267Sjkim    }
517193267Sjkim
518193267Sjkim    /* Remove the handler */
519193267Sjkim
520193267Sjkim    AcpiGbl_TableHandler = NULL;
521193267Sjkim
522193267SjkimCleanup:
523193267Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
524193267Sjkim    return_ACPI_STATUS (Status);
525193267Sjkim}
526193267Sjkim
527193267SjkimACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler)
528