Deleted Added
full compact
utosi.c (231844) utosi.c (239340)
1/******************************************************************************
2 *
3 * Module Name: utosi - Support for the _OSI predefined control method
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#define __UTOSI_C__
45
46#include <contrib/dev/acpica/include/acpi.h>
47#include <contrib/dev/acpica/include/accommon.h>
48
49
50#define _COMPONENT ACPI_UTILITIES
51 ACPI_MODULE_NAME ("utosi")
52
53/*
54 * Strings supported by the _OSI predefined control method (which is
55 * implemented internally within this module.)
56 *
57 * March 2009: Removed "Linux" as this host no longer wants to respond true
58 * for this string. Basically, the only safe OS strings are windows-related
59 * and in many or most cases represent the only test path within the
60 * BIOS-provided ASL code.
61 *
62 * The last element of each entry is used to track the newest version of
63 * Windows that the BIOS has requested.
64 */
65static ACPI_INTERFACE_INFO AcpiDefaultSupportedInterfaces[] =
66{
67 /* Operating System Vendor Strings */
68
69 {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000}, /* Windows 2000 */
70 {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP}, /* Windows XP */
71 {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
72 {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
73 {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
74 {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
75 {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
76 {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */
77 {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
78 {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */
79 {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
1/******************************************************************************
2 *
3 * Module Name: utosi - Support for the _OSI predefined control method
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#define __UTOSI_C__
45
46#include <contrib/dev/acpica/include/acpi.h>
47#include <contrib/dev/acpica/include/accommon.h>
48
49
50#define _COMPONENT ACPI_UTILITIES
51 ACPI_MODULE_NAME ("utosi")
52
53/*
54 * Strings supported by the _OSI predefined control method (which is
55 * implemented internally within this module.)
56 *
57 * March 2009: Removed "Linux" as this host no longer wants to respond true
58 * for this string. Basically, the only safe OS strings are windows-related
59 * and in many or most cases represent the only test path within the
60 * BIOS-provided ASL code.
61 *
62 * The last element of each entry is used to track the newest version of
63 * Windows that the BIOS has requested.
64 */
65static ACPI_INTERFACE_INFO AcpiDefaultSupportedInterfaces[] =
66{
67 /* Operating System Vendor Strings */
68
69 {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000}, /* Windows 2000 */
70 {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP}, /* Windows XP */
71 {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
72 {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
73 {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
74 {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
75 {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
76 {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */
77 {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
78 {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */
79 {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
80 {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */
80
81 /* Feature Group Strings */
82
83 {"Extended Address Space Descriptor", NULL, 0, 0}
84
85 /*
86 * All "optional" feature group strings (features that are implemented
87 * by the host) should be dynamically added by the host via
88 * AcpiInstallInterface and should not be manually added here.
89 *
90 * Examples of optional feature group strings:
91 *
92 * "Module Device"
93 * "Processor Device"
94 * "3.0 Thermal Model"
95 * "3.0 _SCP Extensions"
96 * "Processor Aggregator Device"
97 */
98};
99
100
101/*******************************************************************************
102 *
103 * FUNCTION: AcpiUtInitializeInterfaces
104 *
105 * PARAMETERS: None
106 *
107 * RETURN: Status
108 *
109 * DESCRIPTION: Initialize the global _OSI supported interfaces list
110 *
111 ******************************************************************************/
112
113ACPI_STATUS
114AcpiUtInitializeInterfaces (
115 void)
116{
117 UINT32 i;
118
119
120 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
121 AcpiGbl_SupportedInterfaces = AcpiDefaultSupportedInterfaces;
122
123 /* Link the static list of supported interfaces */
124
125 for (i = 0; i < (ACPI_ARRAY_LENGTH (AcpiDefaultSupportedInterfaces) - 1); i++)
126 {
127 AcpiDefaultSupportedInterfaces[i].Next =
128 &AcpiDefaultSupportedInterfaces[(ACPI_SIZE) i + 1];
129 }
130
131 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
132 return (AE_OK);
133}
134
135
136/*******************************************************************************
137 *
138 * FUNCTION: AcpiUtInterfaceTerminate
139 *
140 * PARAMETERS: None
141 *
142 * RETURN: None
143 *
144 * DESCRIPTION: Delete all interfaces in the global list. Sets
145 * AcpiGbl_SupportedInterfaces to NULL.
146 *
147 ******************************************************************************/
148
149void
150AcpiUtInterfaceTerminate (
151 void)
152{
153 ACPI_INTERFACE_INFO *NextInterface;
154
155
156 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
157 NextInterface = AcpiGbl_SupportedInterfaces;
158
159 while (NextInterface)
160 {
161 AcpiGbl_SupportedInterfaces = NextInterface->Next;
162
163 /* Only interfaces added at runtime can be freed */
164
165 if (NextInterface->Flags & ACPI_OSI_DYNAMIC)
166 {
167 ACPI_FREE (NextInterface->Name);
168 ACPI_FREE (NextInterface);
169 }
170
171 NextInterface = AcpiGbl_SupportedInterfaces;
172 }
173
174 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
175}
176
177
178/*******************************************************************************
179 *
180 * FUNCTION: AcpiUtInstallInterface
181 *
182 * PARAMETERS: InterfaceName - The interface to install
183 *
184 * RETURN: Status
185 *
186 * DESCRIPTION: Install the interface into the global interface list.
187 * Caller MUST hold AcpiGbl_OsiMutex
188 *
189 ******************************************************************************/
190
191ACPI_STATUS
192AcpiUtInstallInterface (
193 ACPI_STRING InterfaceName)
194{
195 ACPI_INTERFACE_INFO *InterfaceInfo;
196
197
198 /* Allocate info block and space for the name string */
199
200 InterfaceInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_INTERFACE_INFO));
201 if (!InterfaceInfo)
202 {
203 return (AE_NO_MEMORY);
204 }
205
206 InterfaceInfo->Name = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (InterfaceName) + 1);
207 if (!InterfaceInfo->Name)
208 {
209 ACPI_FREE (InterfaceInfo);
210 return (AE_NO_MEMORY);
211 }
212
213 /* Initialize new info and insert at the head of the global list */
214
215 ACPI_STRCPY (InterfaceInfo->Name, InterfaceName);
216 InterfaceInfo->Flags = ACPI_OSI_DYNAMIC;
217 InterfaceInfo->Next = AcpiGbl_SupportedInterfaces;
218
219 AcpiGbl_SupportedInterfaces = InterfaceInfo;
220 return (AE_OK);
221}
222
223
224/*******************************************************************************
225 *
226 * FUNCTION: AcpiUtRemoveInterface
227 *
228 * PARAMETERS: InterfaceName - The interface to remove
229 *
230 * RETURN: Status
231 *
232 * DESCRIPTION: Remove the interface from the global interface list.
233 * Caller MUST hold AcpiGbl_OsiMutex
234 *
235 ******************************************************************************/
236
237ACPI_STATUS
238AcpiUtRemoveInterface (
239 ACPI_STRING InterfaceName)
240{
241 ACPI_INTERFACE_INFO *PreviousInterface;
242 ACPI_INTERFACE_INFO *NextInterface;
243
244
245 PreviousInterface = NextInterface = AcpiGbl_SupportedInterfaces;
246 while (NextInterface)
247 {
248 if (!ACPI_STRCMP (InterfaceName, NextInterface->Name))
249 {
250 /* Found: name is in either the static list or was added at runtime */
251
252 if (NextInterface->Flags & ACPI_OSI_DYNAMIC)
253 {
254 /* Interface was added dynamically, remove and free it */
255
256 if (PreviousInterface == NextInterface)
257 {
258 AcpiGbl_SupportedInterfaces = NextInterface->Next;
259 }
260 else
261 {
262 PreviousInterface->Next = NextInterface->Next;
263 }
264
265 ACPI_FREE (NextInterface->Name);
266 ACPI_FREE (NextInterface);
267 }
268 else
269 {
270 /*
271 * Interface is in static list. If marked invalid, then it
272 * does not actually exist. Else, mark it invalid.
273 */
274 if (NextInterface->Flags & ACPI_OSI_INVALID)
275 {
276 return (AE_NOT_EXIST);
277 }
278
279 NextInterface->Flags |= ACPI_OSI_INVALID;
280 }
281
282 return (AE_OK);
283 }
284
285 PreviousInterface = NextInterface;
286 NextInterface = NextInterface->Next;
287 }
288
289 /* Interface was not found */
290
291 return (AE_NOT_EXIST);
292}
293
294
295/*******************************************************************************
296 *
297 * FUNCTION: AcpiUtGetInterface
298 *
299 * PARAMETERS: InterfaceName - The interface to find
300 *
301 * RETURN: ACPI_INTERFACE_INFO if found. NULL if not found.
302 *
303 * DESCRIPTION: Search for the specified interface name in the global list.
304 * Caller MUST hold AcpiGbl_OsiMutex
305 *
306 ******************************************************************************/
307
308ACPI_INTERFACE_INFO *
309AcpiUtGetInterface (
310 ACPI_STRING InterfaceName)
311{
312 ACPI_INTERFACE_INFO *NextInterface;
313
314
315 NextInterface = AcpiGbl_SupportedInterfaces;
316 while (NextInterface)
317 {
318 if (!ACPI_STRCMP (InterfaceName, NextInterface->Name))
319 {
320 return (NextInterface);
321 }
322
323 NextInterface = NextInterface->Next;
324 }
325
326 return (NULL);
327}
328
329
330/*******************************************************************************
331 *
332 * FUNCTION: AcpiUtOsiImplementation
333 *
334 * PARAMETERS: WalkState - Current walk state
335 *
336 * RETURN: Status
337 *
338 * DESCRIPTION: Implementation of the _OSI predefined control method. When
339 * an invocation of _OSI is encountered in the system AML,
340 * control is transferred to this function.
341 *
342 ******************************************************************************/
343
344ACPI_STATUS
345AcpiUtOsiImplementation (
346 ACPI_WALK_STATE *WalkState)
347{
348 ACPI_OPERAND_OBJECT *StringDesc;
349 ACPI_OPERAND_OBJECT *ReturnDesc;
350 ACPI_INTERFACE_INFO *InterfaceInfo;
351 ACPI_INTERFACE_HANDLER InterfaceHandler;
352 UINT32 ReturnValue;
353
354
355 ACPI_FUNCTION_TRACE (UtOsiImplementation);
356
357
358 /* Validate the string input argument (from the AML caller) */
359
360 StringDesc = WalkState->Arguments[0].Object;
361 if (!StringDesc ||
362 (StringDesc->Common.Type != ACPI_TYPE_STRING))
363 {
364 return_ACPI_STATUS (AE_TYPE);
365 }
366
367 /* Create a return object */
368
369 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
370 if (!ReturnDesc)
371 {
372 return_ACPI_STATUS (AE_NO_MEMORY);
373 }
374
375 /* Default return value is 0, NOT SUPPORTED */
376
377 ReturnValue = 0;
378 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
379
380 /* Lookup the interface in the global _OSI list */
381
382 InterfaceInfo = AcpiUtGetInterface (StringDesc->String.Pointer);
383 if (InterfaceInfo &&
384 !(InterfaceInfo->Flags & ACPI_OSI_INVALID))
385 {
386 /*
387 * The interface is supported.
388 * Update the OsiData if necessary. We keep track of the latest
389 * version of Windows that has been requested by the BIOS.
390 */
391 if (InterfaceInfo->Value > AcpiGbl_OsiData)
392 {
393 AcpiGbl_OsiData = InterfaceInfo->Value;
394 }
395
396 ReturnValue = ACPI_UINT32_MAX;
397 }
398
399 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
400
401 /*
402 * Invoke an optional _OSI interface handler. The host OS may wish
403 * to do some interface-specific handling. For example, warn about
404 * certain interfaces or override the true/false support value.
405 */
406 InterfaceHandler = AcpiGbl_InterfaceHandler;
407 if (InterfaceHandler)
408 {
409 ReturnValue = InterfaceHandler (
410 StringDesc->String.Pointer, ReturnValue);
411 }
412
413 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
414 "ACPI: BIOS _OSI(\"%s\") is %ssupported\n",
415 StringDesc->String.Pointer, ReturnValue == 0 ? "not " : ""));
416
417 /* Complete the return object */
418
419 ReturnDesc->Integer.Value = ReturnValue;
420 WalkState->ReturnDesc = ReturnDesc;
421 return_ACPI_STATUS (AE_OK);
422}
81
82 /* Feature Group Strings */
83
84 {"Extended Address Space Descriptor", NULL, 0, 0}
85
86 /*
87 * All "optional" feature group strings (features that are implemented
88 * by the host) should be dynamically added by the host via
89 * AcpiInstallInterface and should not be manually added here.
90 *
91 * Examples of optional feature group strings:
92 *
93 * "Module Device"
94 * "Processor Device"
95 * "3.0 Thermal Model"
96 * "3.0 _SCP Extensions"
97 * "Processor Aggregator Device"
98 */
99};
100
101
102/*******************************************************************************
103 *
104 * FUNCTION: AcpiUtInitializeInterfaces
105 *
106 * PARAMETERS: None
107 *
108 * RETURN: Status
109 *
110 * DESCRIPTION: Initialize the global _OSI supported interfaces list
111 *
112 ******************************************************************************/
113
114ACPI_STATUS
115AcpiUtInitializeInterfaces (
116 void)
117{
118 UINT32 i;
119
120
121 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
122 AcpiGbl_SupportedInterfaces = AcpiDefaultSupportedInterfaces;
123
124 /* Link the static list of supported interfaces */
125
126 for (i = 0; i < (ACPI_ARRAY_LENGTH (AcpiDefaultSupportedInterfaces) - 1); i++)
127 {
128 AcpiDefaultSupportedInterfaces[i].Next =
129 &AcpiDefaultSupportedInterfaces[(ACPI_SIZE) i + 1];
130 }
131
132 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
133 return (AE_OK);
134}
135
136
137/*******************************************************************************
138 *
139 * FUNCTION: AcpiUtInterfaceTerminate
140 *
141 * PARAMETERS: None
142 *
143 * RETURN: None
144 *
145 * DESCRIPTION: Delete all interfaces in the global list. Sets
146 * AcpiGbl_SupportedInterfaces to NULL.
147 *
148 ******************************************************************************/
149
150void
151AcpiUtInterfaceTerminate (
152 void)
153{
154 ACPI_INTERFACE_INFO *NextInterface;
155
156
157 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
158 NextInterface = AcpiGbl_SupportedInterfaces;
159
160 while (NextInterface)
161 {
162 AcpiGbl_SupportedInterfaces = NextInterface->Next;
163
164 /* Only interfaces added at runtime can be freed */
165
166 if (NextInterface->Flags & ACPI_OSI_DYNAMIC)
167 {
168 ACPI_FREE (NextInterface->Name);
169 ACPI_FREE (NextInterface);
170 }
171
172 NextInterface = AcpiGbl_SupportedInterfaces;
173 }
174
175 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
176}
177
178
179/*******************************************************************************
180 *
181 * FUNCTION: AcpiUtInstallInterface
182 *
183 * PARAMETERS: InterfaceName - The interface to install
184 *
185 * RETURN: Status
186 *
187 * DESCRIPTION: Install the interface into the global interface list.
188 * Caller MUST hold AcpiGbl_OsiMutex
189 *
190 ******************************************************************************/
191
192ACPI_STATUS
193AcpiUtInstallInterface (
194 ACPI_STRING InterfaceName)
195{
196 ACPI_INTERFACE_INFO *InterfaceInfo;
197
198
199 /* Allocate info block and space for the name string */
200
201 InterfaceInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_INTERFACE_INFO));
202 if (!InterfaceInfo)
203 {
204 return (AE_NO_MEMORY);
205 }
206
207 InterfaceInfo->Name = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (InterfaceName) + 1);
208 if (!InterfaceInfo->Name)
209 {
210 ACPI_FREE (InterfaceInfo);
211 return (AE_NO_MEMORY);
212 }
213
214 /* Initialize new info and insert at the head of the global list */
215
216 ACPI_STRCPY (InterfaceInfo->Name, InterfaceName);
217 InterfaceInfo->Flags = ACPI_OSI_DYNAMIC;
218 InterfaceInfo->Next = AcpiGbl_SupportedInterfaces;
219
220 AcpiGbl_SupportedInterfaces = InterfaceInfo;
221 return (AE_OK);
222}
223
224
225/*******************************************************************************
226 *
227 * FUNCTION: AcpiUtRemoveInterface
228 *
229 * PARAMETERS: InterfaceName - The interface to remove
230 *
231 * RETURN: Status
232 *
233 * DESCRIPTION: Remove the interface from the global interface list.
234 * Caller MUST hold AcpiGbl_OsiMutex
235 *
236 ******************************************************************************/
237
238ACPI_STATUS
239AcpiUtRemoveInterface (
240 ACPI_STRING InterfaceName)
241{
242 ACPI_INTERFACE_INFO *PreviousInterface;
243 ACPI_INTERFACE_INFO *NextInterface;
244
245
246 PreviousInterface = NextInterface = AcpiGbl_SupportedInterfaces;
247 while (NextInterface)
248 {
249 if (!ACPI_STRCMP (InterfaceName, NextInterface->Name))
250 {
251 /* Found: name is in either the static list or was added at runtime */
252
253 if (NextInterface->Flags & ACPI_OSI_DYNAMIC)
254 {
255 /* Interface was added dynamically, remove and free it */
256
257 if (PreviousInterface == NextInterface)
258 {
259 AcpiGbl_SupportedInterfaces = NextInterface->Next;
260 }
261 else
262 {
263 PreviousInterface->Next = NextInterface->Next;
264 }
265
266 ACPI_FREE (NextInterface->Name);
267 ACPI_FREE (NextInterface);
268 }
269 else
270 {
271 /*
272 * Interface is in static list. If marked invalid, then it
273 * does not actually exist. Else, mark it invalid.
274 */
275 if (NextInterface->Flags & ACPI_OSI_INVALID)
276 {
277 return (AE_NOT_EXIST);
278 }
279
280 NextInterface->Flags |= ACPI_OSI_INVALID;
281 }
282
283 return (AE_OK);
284 }
285
286 PreviousInterface = NextInterface;
287 NextInterface = NextInterface->Next;
288 }
289
290 /* Interface was not found */
291
292 return (AE_NOT_EXIST);
293}
294
295
296/*******************************************************************************
297 *
298 * FUNCTION: AcpiUtGetInterface
299 *
300 * PARAMETERS: InterfaceName - The interface to find
301 *
302 * RETURN: ACPI_INTERFACE_INFO if found. NULL if not found.
303 *
304 * DESCRIPTION: Search for the specified interface name in the global list.
305 * Caller MUST hold AcpiGbl_OsiMutex
306 *
307 ******************************************************************************/
308
309ACPI_INTERFACE_INFO *
310AcpiUtGetInterface (
311 ACPI_STRING InterfaceName)
312{
313 ACPI_INTERFACE_INFO *NextInterface;
314
315
316 NextInterface = AcpiGbl_SupportedInterfaces;
317 while (NextInterface)
318 {
319 if (!ACPI_STRCMP (InterfaceName, NextInterface->Name))
320 {
321 return (NextInterface);
322 }
323
324 NextInterface = NextInterface->Next;
325 }
326
327 return (NULL);
328}
329
330
331/*******************************************************************************
332 *
333 * FUNCTION: AcpiUtOsiImplementation
334 *
335 * PARAMETERS: WalkState - Current walk state
336 *
337 * RETURN: Status
338 *
339 * DESCRIPTION: Implementation of the _OSI predefined control method. When
340 * an invocation of _OSI is encountered in the system AML,
341 * control is transferred to this function.
342 *
343 ******************************************************************************/
344
345ACPI_STATUS
346AcpiUtOsiImplementation (
347 ACPI_WALK_STATE *WalkState)
348{
349 ACPI_OPERAND_OBJECT *StringDesc;
350 ACPI_OPERAND_OBJECT *ReturnDesc;
351 ACPI_INTERFACE_INFO *InterfaceInfo;
352 ACPI_INTERFACE_HANDLER InterfaceHandler;
353 UINT32 ReturnValue;
354
355
356 ACPI_FUNCTION_TRACE (UtOsiImplementation);
357
358
359 /* Validate the string input argument (from the AML caller) */
360
361 StringDesc = WalkState->Arguments[0].Object;
362 if (!StringDesc ||
363 (StringDesc->Common.Type != ACPI_TYPE_STRING))
364 {
365 return_ACPI_STATUS (AE_TYPE);
366 }
367
368 /* Create a return object */
369
370 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
371 if (!ReturnDesc)
372 {
373 return_ACPI_STATUS (AE_NO_MEMORY);
374 }
375
376 /* Default return value is 0, NOT SUPPORTED */
377
378 ReturnValue = 0;
379 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
380
381 /* Lookup the interface in the global _OSI list */
382
383 InterfaceInfo = AcpiUtGetInterface (StringDesc->String.Pointer);
384 if (InterfaceInfo &&
385 !(InterfaceInfo->Flags & ACPI_OSI_INVALID))
386 {
387 /*
388 * The interface is supported.
389 * Update the OsiData if necessary. We keep track of the latest
390 * version of Windows that has been requested by the BIOS.
391 */
392 if (InterfaceInfo->Value > AcpiGbl_OsiData)
393 {
394 AcpiGbl_OsiData = InterfaceInfo->Value;
395 }
396
397 ReturnValue = ACPI_UINT32_MAX;
398 }
399
400 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
401
402 /*
403 * Invoke an optional _OSI interface handler. The host OS may wish
404 * to do some interface-specific handling. For example, warn about
405 * certain interfaces or override the true/false support value.
406 */
407 InterfaceHandler = AcpiGbl_InterfaceHandler;
408 if (InterfaceHandler)
409 {
410 ReturnValue = InterfaceHandler (
411 StringDesc->String.Pointer, ReturnValue);
412 }
413
414 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
415 "ACPI: BIOS _OSI(\"%s\") is %ssupported\n",
416 StringDesc->String.Pointer, ReturnValue == 0 ? "not " : ""));
417
418 /* Complete the return object */
419
420 ReturnDesc->Integer.Value = ReturnValue;
421 WalkState->ReturnDesc = ReturnDesc;
422 return_ACPI_STATUS (AE_OK);
423}