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