xref: /minix3/minix/drivers/power/acpi/utilities/utosi.c (revision 29492bb71c7148a089a5afafa0c99409161218df)
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