1c2c66affSColin Finck /******************************************************************************
2c2c66affSColin Finck  *
3c2c66affSColin Finck  * Module Name: utosi - Support for the _OSI predefined control method
4c2c66affSColin Finck  *
5c2c66affSColin Finck  *****************************************************************************/
6c2c66affSColin Finck 
7c2c66affSColin Finck /*
8*03b24380SThomas Faber  * Copyright (C) 2000 - 2022, Intel Corp.
9c2c66affSColin Finck  * All rights reserved.
10c2c66affSColin Finck  *
11c2c66affSColin Finck  * Redistribution and use in source and binary forms, with or without
12c2c66affSColin Finck  * modification, are permitted provided that the following conditions
13c2c66affSColin Finck  * are met:
14c2c66affSColin Finck  * 1. Redistributions of source code must retain the above copyright
15c2c66affSColin Finck  *    notice, this list of conditions, and the following disclaimer,
16c2c66affSColin Finck  *    without modification.
17c2c66affSColin Finck  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18c2c66affSColin Finck  *    substantially similar to the "NO WARRANTY" disclaimer below
19c2c66affSColin Finck  *    ("Disclaimer") and any redistribution must be conditioned upon
20c2c66affSColin Finck  *    including a substantially similar Disclaimer requirement for further
21c2c66affSColin Finck  *    binary redistribution.
22c2c66affSColin Finck  * 3. Neither the names of the above-listed copyright holders nor the names
23c2c66affSColin Finck  *    of any contributors may be used to endorse or promote products derived
24c2c66affSColin Finck  *    from this software without specific prior written permission.
25c2c66affSColin Finck  *
26c2c66affSColin Finck  * Alternatively, this software may be distributed under the terms of the
27c2c66affSColin Finck  * GNU General Public License ("GPL") version 2 as published by the Free
28c2c66affSColin Finck  * Software Foundation.
29c2c66affSColin Finck  *
30c2c66affSColin Finck  * NO WARRANTY
31c2c66affSColin Finck  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32c2c66affSColin Finck  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
336eb8cc49SThomas Faber  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34c2c66affSColin Finck  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35c2c66affSColin Finck  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36c2c66affSColin Finck  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37c2c66affSColin Finck  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38c2c66affSColin Finck  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39c2c66affSColin Finck  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40c2c66affSColin Finck  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41c2c66affSColin Finck  * POSSIBILITY OF SUCH DAMAGES.
42c2c66affSColin Finck  */
43c2c66affSColin Finck 
44c2c66affSColin Finck #include "acpi.h"
45c2c66affSColin Finck #include "accommon.h"
46c2c66affSColin Finck 
47c2c66affSColin Finck 
48c2c66affSColin Finck #define _COMPONENT          ACPI_UTILITIES
49c2c66affSColin Finck         ACPI_MODULE_NAME    ("utosi")
50c2c66affSColin Finck 
51c2c66affSColin Finck 
52c2c66affSColin Finck /******************************************************************************
53c2c66affSColin Finck  *
54c2c66affSColin Finck  * ACPICA policy for new _OSI strings:
55c2c66affSColin Finck  *
56c2c66affSColin Finck  * It is the stated policy of ACPICA that new _OSI strings will be integrated
57c2c66affSColin Finck  * into this module as soon as possible after they are defined. It is strongly
58c2c66affSColin Finck  * recommended that all ACPICA hosts mirror this policy and integrate any
59c2c66affSColin Finck  * changes to this module as soon as possible. There are several historical
60c2c66affSColin Finck  * reasons behind this policy:
61c2c66affSColin Finck  *
62c2c66affSColin Finck  * 1) New BIOSs tend to test only the case where the host responds TRUE to
63c2c66affSColin Finck  *    the latest version of Windows, which would respond to the latest/newest
64c2c66affSColin Finck  *    _OSI string. Not responding TRUE to the latest version of Windows will
65c2c66affSColin Finck  *    risk executing untested code paths throughout the DSDT and SSDTs.
66c2c66affSColin Finck  *
67c2c66affSColin Finck  * 2) If a new _OSI string is recognized only after a significant delay, this
68c2c66affSColin Finck  *    has the potential to cause problems on existing working machines because
69c2c66affSColin Finck  *    of the possibility that a new and different path through the ASL code
70c2c66affSColin Finck  *    will be executed.
71c2c66affSColin Finck  *
72c2c66affSColin Finck  * 3) New _OSI strings are tending to come out about once per year. A delay
73c2c66affSColin Finck  *    in recognizing a new string for a significant amount of time risks the
74c2c66affSColin Finck  *    release of another string which only compounds the initial problem.
75c2c66affSColin Finck  *
76c2c66affSColin Finck  *****************************************************************************/
77c2c66affSColin Finck 
78c2c66affSColin Finck 
79c2c66affSColin Finck /*
80c2c66affSColin Finck  * Strings supported by the _OSI predefined control method (which is
81c2c66affSColin Finck  * implemented internally within this module.)
82c2c66affSColin Finck  *
83c2c66affSColin Finck  * March 2009: Removed "Linux" as this host no longer wants to respond true
84c2c66affSColin Finck  * for this string. Basically, the only safe OS strings are windows-related
85c2c66affSColin Finck  * and in many or most cases represent the only test path within the
86c2c66affSColin Finck  * BIOS-provided ASL code.
87c2c66affSColin Finck  *
88c2c66affSColin Finck  * The last element of each entry is used to track the newest version of
89c2c66affSColin Finck  * Windows that the BIOS has requested.
90c2c66affSColin Finck  */
91c2c66affSColin Finck static ACPI_INTERFACE_INFO    AcpiDefaultSupportedInterfaces[] =
92c2c66affSColin Finck {
93c2c66affSColin Finck     /* Operating System Vendor Strings */
94c2c66affSColin Finck 
95c2c66affSColin Finck     {"Windows 2000",        NULL, 0, ACPI_OSI_WIN_2000},         /* Windows 2000 */
96c2c66affSColin Finck     {"Windows 2001",        NULL, 0, ACPI_OSI_WIN_XP},           /* Windows XP */
97c2c66affSColin Finck     {"Windows 2001 SP1",    NULL, 0, ACPI_OSI_WIN_XP_SP1},       /* Windows XP SP1 */
98c2c66affSColin Finck     {"Windows 2001.1",      NULL, 0, ACPI_OSI_WINSRV_2003},      /* Windows Server 2003 */
99c2c66affSColin Finck     {"Windows 2001 SP2",    NULL, 0, ACPI_OSI_WIN_XP_SP2},       /* Windows XP SP2 */
100c2c66affSColin Finck     {"Windows 2001.1 SP1",  NULL, 0, ACPI_OSI_WINSRV_2003_SP1},  /* Windows Server 2003 SP1 - Added 03/2006 */
101c2c66affSColin Finck     {"Windows 2006",        NULL, 0, ACPI_OSI_WIN_VISTA},        /* Windows Vista - Added 03/2006 */
102c2c66affSColin Finck     {"Windows 2006.1",      NULL, 0, ACPI_OSI_WINSRV_2008},      /* Windows Server 2008 - Added 09/2009 */
103c2c66affSColin Finck     {"Windows 2006 SP1",    NULL, 0, ACPI_OSI_WIN_VISTA_SP1},    /* Windows Vista SP1 - Added 09/2009 */
104c2c66affSColin Finck     {"Windows 2006 SP2",    NULL, 0, ACPI_OSI_WIN_VISTA_SP2},    /* Windows Vista SP2 - Added 09/2010 */
105c2c66affSColin Finck     {"Windows 2009",        NULL, 0, ACPI_OSI_WIN_7},            /* Windows 7 and Server 2008 R2 - Added 09/2009 */
106c2c66affSColin Finck     {"Windows 2012",        NULL, 0, ACPI_OSI_WIN_8},            /* Windows 8 and Server 2012 - Added 08/2012 */
1075d4f13f6SThomas Faber     {"Windows 2013",        NULL, 0, ACPI_OSI_WIN_8_1},          /* Windows 8.1 and Server 2012 R2 - Added 01/2014 */
108c2c66affSColin Finck     {"Windows 2015",        NULL, 0, ACPI_OSI_WIN_10},           /* Windows 10 - Added 03/2015 */
109ec55f0ebSThomas Faber     {"Windows 2016",        NULL, 0, ACPI_OSI_WIN_10_RS1},       /* Windows 10 version 1607 - Added 12/2017 */
110ec55f0ebSThomas Faber     {"Windows 2017",        NULL, 0, ACPI_OSI_WIN_10_RS2},       /* Windows 10 version 1703 - Added 12/2017 */
1116847cc3aSThomas Faber     {"Windows 2017.2",      NULL, 0, ACPI_OSI_WIN_10_RS3},       /* Windows 10 version 1709 - Added 02/2018 */
112ecbd6353SThomas Faber     {"Windows 2018",        NULL, 0, ACPI_OSI_WIN_10_RS4},       /* Windows 10 version 1803 - Added 11/2018 */
113ecbd6353SThomas Faber     {"Windows 2018.2",      NULL, 0, ACPI_OSI_WIN_10_RS5},       /* Windows 10 version 1809 - Added 11/2018 */
1145d4f13f6SThomas Faber     {"Windows 2019",        NULL, 0, ACPI_OSI_WIN_10_19H1},      /* Windows 10 version 1903 - Added 08/2019 */
1159b247f6aSThomas Faber     {"Windows 2020",        NULL, 0, ACPI_OSI_WIN_10_20H1},      /* Windows 10 version 2004 - Added 08/2021 */
116*03b24380SThomas Faber     {"Windows 2021",        NULL, 0, ACPI_OSI_WIN_11},           /* Windows 11 - Added 01/2022 */
117c2c66affSColin Finck 
118c2c66affSColin Finck     /* Feature Group Strings */
119c2c66affSColin Finck 
120c2c66affSColin Finck     {"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0},
121c2c66affSColin Finck 
122c2c66affSColin Finck     /*
123c2c66affSColin Finck      * All "optional" feature group strings (features that are implemented
124c2c66affSColin Finck      * by the host) should be dynamically modified to VALID by the host via
125c2c66affSColin Finck      * AcpiInstallInterface or AcpiUpdateInterfaces. Such optional feature
126c2c66affSColin Finck      * group strings are set as INVALID by default here.
127c2c66affSColin Finck      */
128c2c66affSColin Finck 
129c2c66affSColin Finck     {"Module Device",               NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
130c2c66affSColin Finck     {"Processor Device",            NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
131c2c66affSColin Finck     {"3.0 Thermal Model",           NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
132c2c66affSColin Finck     {"3.0 _SCP Extensions",         NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
133c2c66affSColin Finck     {"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}
134c2c66affSColin Finck };
135c2c66affSColin Finck 
136c2c66affSColin Finck 
137c2c66affSColin Finck /*******************************************************************************
138c2c66affSColin Finck  *
139c2c66affSColin Finck  * FUNCTION:    AcpiUtInitializeInterfaces
140c2c66affSColin Finck  *
141c2c66affSColin Finck  * PARAMETERS:  None
142c2c66affSColin Finck  *
143c2c66affSColin Finck  * RETURN:      Status
144c2c66affSColin Finck  *
145c2c66affSColin Finck  * DESCRIPTION: Initialize the global _OSI supported interfaces list
146c2c66affSColin Finck  *
147c2c66affSColin Finck  ******************************************************************************/
148c2c66affSColin Finck 
149c2c66affSColin Finck ACPI_STATUS
AcpiUtInitializeInterfaces(void)150c2c66affSColin Finck AcpiUtInitializeInterfaces (
151c2c66affSColin Finck     void)
152c2c66affSColin Finck {
153c2c66affSColin Finck     ACPI_STATUS             Status;
154c2c66affSColin Finck     UINT32                  i;
155c2c66affSColin Finck 
156c2c66affSColin Finck 
157c2c66affSColin Finck     Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
158c2c66affSColin Finck     if (ACPI_FAILURE (Status))
159c2c66affSColin Finck     {
160c2c66affSColin Finck         return (Status);
161c2c66affSColin Finck     }
162c2c66affSColin Finck 
163c2c66affSColin Finck     AcpiGbl_SupportedInterfaces = AcpiDefaultSupportedInterfaces;
164c2c66affSColin Finck 
165c2c66affSColin Finck     /* Link the static list of supported interfaces */
166c2c66affSColin Finck 
167c2c66affSColin Finck     for (i = 0;
168c2c66affSColin Finck         i < (ACPI_ARRAY_LENGTH (AcpiDefaultSupportedInterfaces) - 1);
169c2c66affSColin Finck         i++)
170c2c66affSColin Finck     {
171c2c66affSColin Finck         AcpiDefaultSupportedInterfaces[i].Next =
172c2c66affSColin Finck             &AcpiDefaultSupportedInterfaces[(ACPI_SIZE) i + 1];
173c2c66affSColin Finck     }
174c2c66affSColin Finck 
175c2c66affSColin Finck     AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
176c2c66affSColin Finck     return (AE_OK);
177c2c66affSColin Finck }
178c2c66affSColin Finck 
179c2c66affSColin Finck 
180c2c66affSColin Finck /*******************************************************************************
181c2c66affSColin Finck  *
182c2c66affSColin Finck  * FUNCTION:    AcpiUtInterfaceTerminate
183c2c66affSColin Finck  *
184c2c66affSColin Finck  * PARAMETERS:  None
185c2c66affSColin Finck  *
186c2c66affSColin Finck  * RETURN:      Status
187c2c66affSColin Finck  *
188c2c66affSColin Finck  * DESCRIPTION: Delete all interfaces in the global list. Sets
189c2c66affSColin Finck  *              AcpiGbl_SupportedInterfaces to NULL.
190c2c66affSColin Finck  *
191c2c66affSColin Finck  ******************************************************************************/
192c2c66affSColin Finck 
193c2c66affSColin Finck ACPI_STATUS
AcpiUtInterfaceTerminate(void)194c2c66affSColin Finck AcpiUtInterfaceTerminate (
195c2c66affSColin Finck     void)
196c2c66affSColin Finck {
197c2c66affSColin Finck     ACPI_STATUS             Status;
198c2c66affSColin Finck     ACPI_INTERFACE_INFO     *NextInterface;
199c2c66affSColin Finck 
200c2c66affSColin Finck 
201c2c66affSColin Finck     Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
202c2c66affSColin Finck     if (ACPI_FAILURE (Status))
203c2c66affSColin Finck     {
204c2c66affSColin Finck         return (Status);
205c2c66affSColin Finck     }
206c2c66affSColin Finck 
207c2c66affSColin Finck     NextInterface = AcpiGbl_SupportedInterfaces;
208c2c66affSColin Finck     while (NextInterface)
209c2c66affSColin Finck     {
210c2c66affSColin Finck         AcpiGbl_SupportedInterfaces = NextInterface->Next;
211c2c66affSColin Finck 
212c2c66affSColin Finck         if (NextInterface->Flags & ACPI_OSI_DYNAMIC)
213c2c66affSColin Finck         {
214c2c66affSColin Finck             /* Only interfaces added at runtime can be freed */
215c2c66affSColin Finck 
216c2c66affSColin Finck             ACPI_FREE (NextInterface->Name);
217c2c66affSColin Finck             ACPI_FREE (NextInterface);
218c2c66affSColin Finck         }
219c2c66affSColin Finck         else
220c2c66affSColin Finck         {
221c2c66affSColin Finck             /* Interface is in static list. Reset it to invalid or valid. */
222c2c66affSColin Finck 
223c2c66affSColin Finck             if (NextInterface->Flags & ACPI_OSI_DEFAULT_INVALID)
224c2c66affSColin Finck             {
225c2c66affSColin Finck                 NextInterface->Flags |= ACPI_OSI_INVALID;
226c2c66affSColin Finck             }
227c2c66affSColin Finck             else
228c2c66affSColin Finck             {
229c2c66affSColin Finck                 NextInterface->Flags &= ~ACPI_OSI_INVALID;
230c2c66affSColin Finck             }
231c2c66affSColin Finck         }
232c2c66affSColin Finck 
233c2c66affSColin Finck         NextInterface = AcpiGbl_SupportedInterfaces;
234c2c66affSColin Finck     }
235c2c66affSColin Finck 
236c2c66affSColin Finck     AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
237c2c66affSColin Finck     return (AE_OK);
238c2c66affSColin Finck }
239c2c66affSColin Finck 
240c2c66affSColin Finck 
241c2c66affSColin Finck /*******************************************************************************
242c2c66affSColin Finck  *
243c2c66affSColin Finck  * FUNCTION:    AcpiUtInstallInterface
244c2c66affSColin Finck  *
245c2c66affSColin Finck  * PARAMETERS:  InterfaceName       - The interface to install
246c2c66affSColin Finck  *
247c2c66affSColin Finck  * RETURN:      Status
248c2c66affSColin Finck  *
249c2c66affSColin Finck  * DESCRIPTION: Install the interface into the global interface list.
250c2c66affSColin Finck  *              Caller MUST hold AcpiGbl_OsiMutex
251c2c66affSColin Finck  *
252c2c66affSColin Finck  ******************************************************************************/
253c2c66affSColin Finck 
254c2c66affSColin Finck ACPI_STATUS
AcpiUtInstallInterface(ACPI_STRING InterfaceName)255c2c66affSColin Finck AcpiUtInstallInterface (
256c2c66affSColin Finck     ACPI_STRING             InterfaceName)
257c2c66affSColin Finck {
258c2c66affSColin Finck     ACPI_INTERFACE_INFO     *InterfaceInfo;
259c2c66affSColin Finck 
260c2c66affSColin Finck 
261c2c66affSColin Finck     /* Allocate info block and space for the name string */
262c2c66affSColin Finck 
263c2c66affSColin Finck     InterfaceInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_INTERFACE_INFO));
264c2c66affSColin Finck     if (!InterfaceInfo)
265c2c66affSColin Finck     {
266c2c66affSColin Finck         return (AE_NO_MEMORY);
267c2c66affSColin Finck     }
268c2c66affSColin Finck 
269c2c66affSColin Finck     InterfaceInfo->Name = ACPI_ALLOCATE_ZEROED (strlen (InterfaceName) + 1);
270c2c66affSColin Finck     if (!InterfaceInfo->Name)
271c2c66affSColin Finck     {
272c2c66affSColin Finck         ACPI_FREE (InterfaceInfo);
273c2c66affSColin Finck         return (AE_NO_MEMORY);
274c2c66affSColin Finck     }
275c2c66affSColin Finck 
276c2c66affSColin Finck     /* Initialize new info and insert at the head of the global list */
277c2c66affSColin Finck 
278c2c66affSColin Finck     strcpy (InterfaceInfo->Name, InterfaceName);
279c2c66affSColin Finck     InterfaceInfo->Flags = ACPI_OSI_DYNAMIC;
280c2c66affSColin Finck     InterfaceInfo->Next = AcpiGbl_SupportedInterfaces;
281c2c66affSColin Finck 
282c2c66affSColin Finck     AcpiGbl_SupportedInterfaces = InterfaceInfo;
283c2c66affSColin Finck     return (AE_OK);
284c2c66affSColin Finck }
285c2c66affSColin Finck 
286c2c66affSColin Finck 
287c2c66affSColin Finck /*******************************************************************************
288c2c66affSColin Finck  *
289c2c66affSColin Finck  * FUNCTION:    AcpiUtRemoveInterface
290c2c66affSColin Finck  *
291c2c66affSColin Finck  * PARAMETERS:  InterfaceName       - The interface to remove
292c2c66affSColin Finck  *
293c2c66affSColin Finck  * RETURN:      Status
294c2c66affSColin Finck  *
295c2c66affSColin Finck  * DESCRIPTION: Remove the interface from the global interface list.
296c2c66affSColin Finck  *              Caller MUST hold AcpiGbl_OsiMutex
297c2c66affSColin Finck  *
298c2c66affSColin Finck  ******************************************************************************/
299c2c66affSColin Finck 
300c2c66affSColin Finck ACPI_STATUS
AcpiUtRemoveInterface(ACPI_STRING InterfaceName)301c2c66affSColin Finck AcpiUtRemoveInterface (
302c2c66affSColin Finck     ACPI_STRING             InterfaceName)
303c2c66affSColin Finck {
304c2c66affSColin Finck     ACPI_INTERFACE_INFO     *PreviousInterface;
305c2c66affSColin Finck     ACPI_INTERFACE_INFO     *NextInterface;
306c2c66affSColin Finck 
307c2c66affSColin Finck 
308c2c66affSColin Finck     PreviousInterface = NextInterface = AcpiGbl_SupportedInterfaces;
309c2c66affSColin Finck     while (NextInterface)
310c2c66affSColin Finck     {
311c2c66affSColin Finck         if (!strcmp (InterfaceName, NextInterface->Name))
312c2c66affSColin Finck         {
313c2c66affSColin Finck             /*
314c2c66affSColin Finck              * Found: name is in either the static list
315c2c66affSColin Finck              * or was added at runtime
316c2c66affSColin Finck              */
317c2c66affSColin Finck             if (NextInterface->Flags & ACPI_OSI_DYNAMIC)
318c2c66affSColin Finck             {
319c2c66affSColin Finck                 /* Interface was added dynamically, remove and free it */
320c2c66affSColin Finck 
321c2c66affSColin Finck                 if (PreviousInterface == NextInterface)
322c2c66affSColin Finck                 {
323c2c66affSColin Finck                     AcpiGbl_SupportedInterfaces = NextInterface->Next;
324c2c66affSColin Finck                 }
325c2c66affSColin Finck                 else
326c2c66affSColin Finck                 {
327c2c66affSColin Finck                     PreviousInterface->Next = NextInterface->Next;
328c2c66affSColin Finck                 }
329c2c66affSColin Finck 
330c2c66affSColin Finck                 ACPI_FREE (NextInterface->Name);
331c2c66affSColin Finck                 ACPI_FREE (NextInterface);
332c2c66affSColin Finck             }
333c2c66affSColin Finck             else
334c2c66affSColin Finck             {
335c2c66affSColin Finck                 /*
336c2c66affSColin Finck                  * Interface is in static list. If marked invalid, then
337c2c66affSColin Finck                  * it does not actually exist. Else, mark it invalid.
338c2c66affSColin Finck                  */
339c2c66affSColin Finck                 if (NextInterface->Flags & ACPI_OSI_INVALID)
340c2c66affSColin Finck                 {
341c2c66affSColin Finck                     return (AE_NOT_EXIST);
342c2c66affSColin Finck                 }
343c2c66affSColin Finck 
344c2c66affSColin Finck                 NextInterface->Flags |= ACPI_OSI_INVALID;
345c2c66affSColin Finck             }
346c2c66affSColin Finck 
347c2c66affSColin Finck             return (AE_OK);
348c2c66affSColin Finck         }
349c2c66affSColin Finck 
350c2c66affSColin Finck         PreviousInterface = NextInterface;
351c2c66affSColin Finck         NextInterface = NextInterface->Next;
352c2c66affSColin Finck     }
353c2c66affSColin Finck 
354c2c66affSColin Finck     /* Interface was not found */
355c2c66affSColin Finck 
356c2c66affSColin Finck     return (AE_NOT_EXIST);
357c2c66affSColin Finck }
358c2c66affSColin Finck 
359c2c66affSColin Finck 
360c2c66affSColin Finck /*******************************************************************************
361c2c66affSColin Finck  *
362c2c66affSColin Finck  * FUNCTION:    AcpiUtUpdateInterfaces
363c2c66affSColin Finck  *
364c2c66affSColin Finck  * PARAMETERS:  Action              - Actions to be performed during the
365c2c66affSColin Finck  *                                    update
366c2c66affSColin Finck  *
367c2c66affSColin Finck  * RETURN:      Status
368c2c66affSColin Finck  *
369c2c66affSColin Finck  * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor
370c2c66affSColin Finck  *              strings or/and feature group strings.
371c2c66affSColin Finck  *              Caller MUST hold AcpiGbl_OsiMutex
372c2c66affSColin Finck  *
373c2c66affSColin Finck  ******************************************************************************/
374c2c66affSColin Finck 
375c2c66affSColin Finck ACPI_STATUS
AcpiUtUpdateInterfaces(UINT8 Action)376c2c66affSColin Finck AcpiUtUpdateInterfaces (
377c2c66affSColin Finck     UINT8                   Action)
378c2c66affSColin Finck {
379c2c66affSColin Finck     ACPI_INTERFACE_INFO     *NextInterface;
380c2c66affSColin Finck 
381c2c66affSColin Finck 
382c2c66affSColin Finck     NextInterface = AcpiGbl_SupportedInterfaces;
383c2c66affSColin Finck     while (NextInterface)
384c2c66affSColin Finck     {
385c2c66affSColin Finck         if (((NextInterface->Flags & ACPI_OSI_FEATURE) &&
386c2c66affSColin Finck              (Action & ACPI_FEATURE_STRINGS)) ||
387c2c66affSColin Finck             (!(NextInterface->Flags & ACPI_OSI_FEATURE) &&
388c2c66affSColin Finck              (Action & ACPI_VENDOR_STRINGS)))
389c2c66affSColin Finck         {
390c2c66affSColin Finck             if (Action & ACPI_DISABLE_INTERFACES)
391c2c66affSColin Finck             {
392c2c66affSColin Finck                 /* Mark the interfaces as invalid */
393c2c66affSColin Finck 
394c2c66affSColin Finck                 NextInterface->Flags |= ACPI_OSI_INVALID;
395c2c66affSColin Finck             }
396c2c66affSColin Finck             else
397c2c66affSColin Finck             {
398c2c66affSColin Finck                 /* Mark the interfaces as valid */
399c2c66affSColin Finck 
400c2c66affSColin Finck                 NextInterface->Flags &= ~ACPI_OSI_INVALID;
401c2c66affSColin Finck             }
402c2c66affSColin Finck         }
403c2c66affSColin Finck 
404c2c66affSColin Finck         NextInterface = NextInterface->Next;
405c2c66affSColin Finck     }
406c2c66affSColin Finck 
407c2c66affSColin Finck     return (AE_OK);
408c2c66affSColin Finck }
409c2c66affSColin Finck 
410c2c66affSColin Finck 
411c2c66affSColin Finck /*******************************************************************************
412c2c66affSColin Finck  *
413c2c66affSColin Finck  * FUNCTION:    AcpiUtGetInterface
414c2c66affSColin Finck  *
415c2c66affSColin Finck  * PARAMETERS:  InterfaceName       - The interface to find
416c2c66affSColin Finck  *
417c2c66affSColin Finck  * RETURN:      ACPI_INTERFACE_INFO if found. NULL if not found.
418c2c66affSColin Finck  *
419c2c66affSColin Finck  * DESCRIPTION: Search for the specified interface name in the global list.
420c2c66affSColin Finck  *              Caller MUST hold AcpiGbl_OsiMutex
421c2c66affSColin Finck  *
422c2c66affSColin Finck  ******************************************************************************/
423c2c66affSColin Finck 
424c2c66affSColin Finck ACPI_INTERFACE_INFO *
AcpiUtGetInterface(ACPI_STRING InterfaceName)425c2c66affSColin Finck AcpiUtGetInterface (
426c2c66affSColin Finck     ACPI_STRING             InterfaceName)
427c2c66affSColin Finck {
428c2c66affSColin Finck     ACPI_INTERFACE_INFO     *NextInterface;
429c2c66affSColin Finck 
430c2c66affSColin Finck 
431c2c66affSColin Finck     NextInterface = AcpiGbl_SupportedInterfaces;
432c2c66affSColin Finck     while (NextInterface)
433c2c66affSColin Finck     {
434c2c66affSColin Finck         if (!strcmp (InterfaceName, NextInterface->Name))
435c2c66affSColin Finck         {
436c2c66affSColin Finck             return (NextInterface);
437c2c66affSColin Finck         }
438c2c66affSColin Finck 
439c2c66affSColin Finck         NextInterface = NextInterface->Next;
440c2c66affSColin Finck     }
441c2c66affSColin Finck 
442c2c66affSColin Finck     return (NULL);
443c2c66affSColin Finck }
444c2c66affSColin Finck 
445c2c66affSColin Finck 
446c2c66affSColin Finck /*******************************************************************************
447c2c66affSColin Finck  *
448c2c66affSColin Finck  * FUNCTION:    AcpiUtOsiImplementation
449c2c66affSColin Finck  *
450c2c66affSColin Finck  * PARAMETERS:  WalkState           - Current walk state
451c2c66affSColin Finck  *
452c2c66affSColin Finck  * RETURN:      Status
453c2c66affSColin Finck  *              Integer: TRUE (0) if input string is matched
454c2c66affSColin Finck  *                       FALSE (-1) if string is not matched
455c2c66affSColin Finck  *
456c2c66affSColin Finck  * DESCRIPTION: Implementation of the _OSI predefined control method. When
457c2c66affSColin Finck  *              an invocation of _OSI is encountered in the system AML,
458c2c66affSColin Finck  *              control is transferred to this function.
459c2c66affSColin Finck  *
460c2c66affSColin Finck  * (August 2016)
461c2c66affSColin Finck  * Note:  _OSI is now defined to return "Ones" to indicate a match, for
462c2c66affSColin Finck  * compatibility with other ACPI implementations. On a 32-bit DSDT, Ones
463c2c66affSColin Finck  * is 0xFFFFFFFF. On a 64-bit DSDT, Ones is 0xFFFFFFFFFFFFFFFF
464c2c66affSColin Finck  * (ACPI_UINT64_MAX).
465c2c66affSColin Finck  *
466c2c66affSColin Finck  * This function always returns ACPI_UINT64_MAX for TRUE, and later code
467c2c66affSColin Finck  * will truncate this to 32 bits if necessary.
468c2c66affSColin Finck  *
469c2c66affSColin Finck  ******************************************************************************/
470c2c66affSColin Finck 
471c2c66affSColin Finck ACPI_STATUS
AcpiUtOsiImplementation(ACPI_WALK_STATE * WalkState)472c2c66affSColin Finck AcpiUtOsiImplementation (
473c2c66affSColin Finck     ACPI_WALK_STATE         *WalkState)
474c2c66affSColin Finck {
475c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *StringDesc;
476c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *ReturnDesc;
477c2c66affSColin Finck     ACPI_INTERFACE_INFO     *InterfaceInfo;
478c2c66affSColin Finck     ACPI_INTERFACE_HANDLER  InterfaceHandler;
479c2c66affSColin Finck     ACPI_STATUS             Status;
480c2c66affSColin Finck     UINT64                  ReturnValue;
481c2c66affSColin Finck 
482c2c66affSColin Finck 
483c2c66affSColin Finck     ACPI_FUNCTION_TRACE (UtOsiImplementation);
484c2c66affSColin Finck 
485c2c66affSColin Finck 
486c2c66affSColin Finck     /* Validate the string input argument (from the AML caller) */
487c2c66affSColin Finck 
488c2c66affSColin Finck     StringDesc = WalkState->Arguments[0].Object;
489c2c66affSColin Finck     if (!StringDesc ||
490c2c66affSColin Finck         (StringDesc->Common.Type != ACPI_TYPE_STRING))
491c2c66affSColin Finck     {
492c2c66affSColin Finck         return_ACPI_STATUS (AE_TYPE);
493c2c66affSColin Finck     }
494c2c66affSColin Finck 
495c2c66affSColin Finck     /* Create a return object */
496c2c66affSColin Finck 
497c2c66affSColin Finck     ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
498c2c66affSColin Finck     if (!ReturnDesc)
499c2c66affSColin Finck     {
500c2c66affSColin Finck         return_ACPI_STATUS (AE_NO_MEMORY);
501c2c66affSColin Finck     }
502c2c66affSColin Finck 
503c2c66affSColin Finck     /* Default return value is 0, NOT SUPPORTED */
504c2c66affSColin Finck 
505c2c66affSColin Finck     ReturnValue = 0;
506c2c66affSColin Finck     Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
507c2c66affSColin Finck     if (ACPI_FAILURE (Status))
508c2c66affSColin Finck     {
509c2c66affSColin Finck         AcpiUtRemoveReference (ReturnDesc);
510c2c66affSColin Finck         return_ACPI_STATUS (Status);
511c2c66affSColin Finck     }
512c2c66affSColin Finck 
513c2c66affSColin Finck     /* Lookup the interface in the global _OSI list */
514c2c66affSColin Finck 
515c2c66affSColin Finck     InterfaceInfo = AcpiUtGetInterface (StringDesc->String.Pointer);
516c2c66affSColin Finck     if (InterfaceInfo &&
517c2c66affSColin Finck         !(InterfaceInfo->Flags & ACPI_OSI_INVALID))
518c2c66affSColin Finck     {
519c2c66affSColin Finck         /*
520c2c66affSColin Finck          * The interface is supported.
521c2c66affSColin Finck          * Update the OsiData if necessary. We keep track of the latest
522c2c66affSColin Finck          * version of Windows that has been requested by the BIOS.
523c2c66affSColin Finck          */
524c2c66affSColin Finck         if (InterfaceInfo->Value > AcpiGbl_OsiData)
525c2c66affSColin Finck         {
526c2c66affSColin Finck             AcpiGbl_OsiData = InterfaceInfo->Value;
527c2c66affSColin Finck         }
528c2c66affSColin Finck 
529c2c66affSColin Finck         ReturnValue = ACPI_UINT64_MAX;
530c2c66affSColin Finck     }
531c2c66affSColin Finck 
532c2c66affSColin Finck     AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
533c2c66affSColin Finck 
534c2c66affSColin Finck     /*
535c2c66affSColin Finck      * Invoke an optional _OSI interface handler. The host OS may wish
536c2c66affSColin Finck      * to do some interface-specific handling. For example, warn about
537c2c66affSColin Finck      * certain interfaces or override the true/false support value.
538c2c66affSColin Finck      */
539c2c66affSColin Finck     InterfaceHandler = AcpiGbl_InterfaceHandler;
540c2c66affSColin Finck     if (InterfaceHandler)
541c2c66affSColin Finck     {
542c2c66affSColin Finck         if (InterfaceHandler (
543c2c66affSColin Finck             StringDesc->String.Pointer, (UINT32) ReturnValue))
544c2c66affSColin Finck         {
545c2c66affSColin Finck             ReturnValue = ACPI_UINT64_MAX;
546c2c66affSColin Finck         }
547c2c66affSColin Finck     }
548c2c66affSColin Finck 
549c2c66affSColin Finck     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
550c2c66affSColin Finck         "ACPI: BIOS _OSI(\"%s\") is %ssupported\n",
551c2c66affSColin Finck         StringDesc->String.Pointer, ReturnValue == 0 ? "not " : ""));
552c2c66affSColin Finck 
553c2c66affSColin Finck     /* Complete the return object */
554c2c66affSColin Finck 
555c2c66affSColin Finck     ReturnDesc->Integer.Value = ReturnValue;
556c2c66affSColin Finck     WalkState->ReturnDesc = ReturnDesc;
557c2c66affSColin Finck     return_ACPI_STATUS (AE_OK);
558c2c66affSColin Finck }
559