1167802Sjkim/******************************************************************************
2167802Sjkim *
3167802Sjkim * Module Name: tbfind   - find table
4167802Sjkim *
5167802Sjkim *****************************************************************************/
6167802Sjkim
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9167802Sjkim * All rights reserved.
10167802Sjkim *
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.
25167802Sjkim *
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.
29167802Sjkim *
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 */
43167802Sjkim
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/actables.h>
47167802Sjkim
48167802Sjkim#define _COMPONENT          ACPI_TABLES
49167802Sjkim        ACPI_MODULE_NAME    ("tbfind")
50167802Sjkim
51167802Sjkim
52167802Sjkim/*******************************************************************************
53167802Sjkim *
54167802Sjkim * FUNCTION:    AcpiTbFindTable
55167802Sjkim *
56167802Sjkim * PARAMETERS:  Signature           - String with ACPI table signature
57167802Sjkim *              OemId               - String with the table OEM ID
58167802Sjkim *              OemTableId          - String with the OEM Table ID
59167802Sjkim *              TableIndex          - Where the table index is returned
60167802Sjkim *
61167802Sjkim * RETURN:      Status and table index
62167802Sjkim *
63167802Sjkim * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
64167802Sjkim *              Signature, OEM ID and OEM Table ID. Returns an index that can
65167802Sjkim *              be used to get the table header or entire table.
66167802Sjkim *
67167802Sjkim ******************************************************************************/
68167802Sjkim
69167802SjkimACPI_STATUS
70167802SjkimAcpiTbFindTable (
71167802Sjkim    char                    *Signature,
72167802Sjkim    char                    *OemId,
73167802Sjkim    char                    *OemTableId,
74193267Sjkim    UINT32                  *TableIndex)
75167802Sjkim{
76167802Sjkim    ACPI_STATUS             Status;
77193267Sjkim    ACPI_TABLE_HEADER       Header;
78306536Sjkim    UINT32                  i;
79167802Sjkim
80167802Sjkim
81167802Sjkim    ACPI_FUNCTION_TRACE (TbFindTable);
82167802Sjkim
83167802Sjkim
84306536Sjkim    /* Validate the input table signature */
85306536Sjkim
86306536Sjkim    if (!AcpiUtValidNameseg (Signature))
87306536Sjkim    {
88306536Sjkim        return_ACPI_STATUS (AE_BAD_SIGNATURE);
89306536Sjkim    }
90306536Sjkim
91306536Sjkim    /* Don't allow the OEM strings to be too long */
92306536Sjkim
93306536Sjkim    if ((strlen (OemId) > ACPI_OEM_ID_SIZE) ||
94306536Sjkim        (strlen (OemTableId) > ACPI_OEM_TABLE_ID_SIZE))
95306536Sjkim    {
96306536Sjkim        return_ACPI_STATUS (AE_AML_STRING_LIMIT);
97306536Sjkim    }
98306536Sjkim
99193267Sjkim    /* Normalize the input strings */
100193267Sjkim
101306536Sjkim    memset (&Header, 0, sizeof (ACPI_TABLE_HEADER));
102241973Sjkim    ACPI_MOVE_NAME (Header.Signature, Signature);
103306536Sjkim    strncpy (Header.OemId, OemId, ACPI_OEM_ID_SIZE);
104306536Sjkim    strncpy (Header.OemTableId, OemTableId, ACPI_OEM_TABLE_ID_SIZE);
105193267Sjkim
106193267Sjkim    /* Search for the table */
107193267Sjkim
108207344Sjkim    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
109167802Sjkim    {
110306536Sjkim        if (memcmp (&(AcpiGbl_RootTableList.Tables[i].Signature),
111306536Sjkim            Header.Signature, ACPI_NAME_SIZE))
112167802Sjkim        {
113167802Sjkim            /* Not the requested table */
114167802Sjkim
115167802Sjkim            continue;
116167802Sjkim        }
117167802Sjkim
118167802Sjkim        /* Table with matching signature has been found */
119167802Sjkim
120167802Sjkim        if (!AcpiGbl_RootTableList.Tables[i].Pointer)
121167802Sjkim        {
122167802Sjkim            /* Table is not currently mapped, map it */
123167802Sjkim
124281075Sdim            Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
125167802Sjkim            if (ACPI_FAILURE (Status))
126167802Sjkim            {
127167802Sjkim                return_ACPI_STATUS (Status);
128167802Sjkim            }
129167802Sjkim
130167802Sjkim            if (!AcpiGbl_RootTableList.Tables[i].Pointer)
131167802Sjkim            {
132167802Sjkim                continue;
133167802Sjkim            }
134167802Sjkim        }
135167802Sjkim
136167802Sjkim        /* Check for table match on all IDs */
137167802Sjkim
138306536Sjkim        if (!memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->Signature,
139306536Sjkim                Header.Signature, ACPI_NAME_SIZE) &&
140167802Sjkim            (!OemId[0] ||
141306536Sjkim             !memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->OemId,
142306536Sjkim                 Header.OemId, ACPI_OEM_ID_SIZE)) &&
143167802Sjkim            (!OemTableId[0] ||
144306536Sjkim             !memcmp (AcpiGbl_RootTableList.Tables[i].Pointer->OemTableId,
145306536Sjkim                 Header.OemTableId, ACPI_OEM_TABLE_ID_SIZE)))
146167802Sjkim        {
147167802Sjkim            *TableIndex = i;
148167802Sjkim
149167802Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n",
150193267Sjkim                Header.Signature));
151167802Sjkim            return_ACPI_STATUS (AE_OK);
152167802Sjkim        }
153167802Sjkim    }
154167802Sjkim
155167802Sjkim    return_ACPI_STATUS (AE_NOT_FOUND);
156167802Sjkim}
157