1210944Sjkim/****************************************************************************** 2210944Sjkim * 3210944Sjkim * Module Name: utosi - Support for the _OSI predefined control method 4210944Sjkim * 5210944Sjkim *****************************************************************************/ 6210944Sjkim 7217365Sjkim/* 8281075Sdim * Copyright (C) 2000 - 2015, Intel Corp. 9210944Sjkim * All rights reserved. 10210944Sjkim * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25210944Sjkim * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29210944Sjkim * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43210944Sjkim 44210976Sjkim#include <contrib/dev/acpica/include/acpi.h> 45210976Sjkim#include <contrib/dev/acpica/include/accommon.h> 46210944Sjkim 47210944Sjkim 48210944Sjkim#define _COMPONENT ACPI_UTILITIES 49210944Sjkim ACPI_MODULE_NAME ("utosi") 50210944Sjkim 51281075Sdim 52281075Sdim/****************************************************************************** 53281075Sdim * 54281075Sdim * ACPICA policy for new _OSI strings: 55281075Sdim * 56281075Sdim * It is the stated policy of ACPICA that new _OSI strings will be integrated 57281075Sdim * into this module as soon as possible after they are defined. It is strongly 58281075Sdim * recommended that all ACPICA hosts mirror this policy and integrate any 59281075Sdim * changes to this module as soon as possible. There are several historical 60281075Sdim * reasons behind this policy: 61281075Sdim * 62281075Sdim * 1) New BIOSs tend to test only the case where the host responds TRUE to 63281075Sdim * the latest version of Windows, which would respond to the latest/newest 64281075Sdim * _OSI string. Not responding TRUE to the latest version of Windows will 65281075Sdim * risk executing untested code paths throughout the DSDT and SSDTs. 66281075Sdim * 67281075Sdim * 2) If a new _OSI string is recognized only after a significant delay, this 68281075Sdim * has the potential to cause problems on existing working machines because 69281075Sdim * of the possibility that a new and different path through the ASL code 70281075Sdim * will be executed. 71281075Sdim * 72281075Sdim * 3) New _OSI strings are tending to come out about once per year. A delay 73281075Sdim * in recognizing a new string for a significant amount of time risks the 74281075Sdim * release of another string which only compounds the initial problem. 75281075Sdim * 76281075Sdim *****************************************************************************/ 77281075Sdim 78281075Sdim 79210944Sjkim/* 80210944Sjkim * Strings supported by the _OSI predefined control method (which is 81210944Sjkim * implemented internally within this module.) 82210944Sjkim * 83210944Sjkim * March 2009: Removed "Linux" as this host no longer wants to respond true 84210944Sjkim * for this string. Basically, the only safe OS strings are windows-related 85210944Sjkim * and in many or most cases represent the only test path within the 86210944Sjkim * BIOS-provided ASL code. 87210944Sjkim * 88210944Sjkim * The last element of each entry is used to track the newest version of 89210944Sjkim * Windows that the BIOS has requested. 90210944Sjkim */ 91210944Sjkimstatic ACPI_INTERFACE_INFO AcpiDefaultSupportedInterfaces[] = 92210944Sjkim{ 93210944Sjkim /* Operating System Vendor Strings */ 94210944Sjkim 95210944Sjkim {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000}, /* Windows 2000 */ 96210944Sjkim {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP}, /* Windows XP */ 97210944Sjkim {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */ 98210944Sjkim {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */ 99210944Sjkim {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ 100210944Sjkim {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ 101210944Sjkim {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ 102210944Sjkim {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ 103210944Sjkim {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ 104213806Sjkim {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */ 105210944Sjkim {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ 106239340Sjkim {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */ 107281075Sdim {"Windows 2013", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8.1 and Server 2012 R2 - Added 01/2014 */ 108281687Sjkim {"Windows 2015", NULL, 0, ACPI_OSI_WIN_10}, /* Windows 10 - Added 03/2015 */ 109210944Sjkim 110210944Sjkim /* Feature Group Strings */ 111210944Sjkim 112253690Sjkim {"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0}, 113210944Sjkim 114210944Sjkim /* 115210944Sjkim * All "optional" feature group strings (features that are implemented 116253690Sjkim * by the host) should be dynamically modified to VALID by the host via 117253690Sjkim * AcpiInstallInterface or AcpiUpdateInterfaces. Such optional feature 118253690Sjkim * group strings are set as INVALID by default here. 119210944Sjkim */ 120253690Sjkim 121253690Sjkim {"Module Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, 122253690Sjkim {"Processor Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, 123253690Sjkim {"3.0 Thermal Model", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, 124253690Sjkim {"3.0 _SCP Extensions", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, 125253690Sjkim {"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0} 126210944Sjkim}; 127210944Sjkim 128210944Sjkim 129210944Sjkim/******************************************************************************* 130210944Sjkim * 131210944Sjkim * FUNCTION: AcpiUtInitializeInterfaces 132210944Sjkim * 133210944Sjkim * PARAMETERS: None 134210944Sjkim * 135210944Sjkim * RETURN: Status 136210944Sjkim * 137210944Sjkim * DESCRIPTION: Initialize the global _OSI supported interfaces list 138210944Sjkim * 139210944Sjkim ******************************************************************************/ 140210944Sjkim 141210944SjkimACPI_STATUS 142210944SjkimAcpiUtInitializeInterfaces ( 143210944Sjkim void) 144210944Sjkim{ 145249112Sjkim ACPI_STATUS Status; 146210944Sjkim UINT32 i; 147210944Sjkim 148210944Sjkim 149249112Sjkim Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); 150249112Sjkim if (ACPI_FAILURE (Status)) 151249112Sjkim { 152249112Sjkim return (Status); 153249112Sjkim } 154249112Sjkim 155210944Sjkim AcpiGbl_SupportedInterfaces = AcpiDefaultSupportedInterfaces; 156210944Sjkim 157210944Sjkim /* Link the static list of supported interfaces */ 158210944Sjkim 159210944Sjkim for (i = 0; i < (ACPI_ARRAY_LENGTH (AcpiDefaultSupportedInterfaces) - 1); i++) 160210944Sjkim { 161210944Sjkim AcpiDefaultSupportedInterfaces[i].Next = 162210944Sjkim &AcpiDefaultSupportedInterfaces[(ACPI_SIZE) i + 1]; 163210944Sjkim } 164210944Sjkim 165210944Sjkim AcpiOsReleaseMutex (AcpiGbl_OsiMutex); 166210944Sjkim return (AE_OK); 167210944Sjkim} 168210944Sjkim 169210944Sjkim 170210944Sjkim/******************************************************************************* 171210944Sjkim * 172210944Sjkim * FUNCTION: AcpiUtInterfaceTerminate 173210944Sjkim * 174210944Sjkim * PARAMETERS: None 175210944Sjkim * 176249112Sjkim * RETURN: Status 177210944Sjkim * 178210944Sjkim * DESCRIPTION: Delete all interfaces in the global list. Sets 179210944Sjkim * AcpiGbl_SupportedInterfaces to NULL. 180210944Sjkim * 181210944Sjkim ******************************************************************************/ 182210944Sjkim 183249112SjkimACPI_STATUS 184210944SjkimAcpiUtInterfaceTerminate ( 185210944Sjkim void) 186210944Sjkim{ 187249112Sjkim ACPI_STATUS Status; 188210944Sjkim ACPI_INTERFACE_INFO *NextInterface; 189210944Sjkim 190210944Sjkim 191249112Sjkim Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); 192249112Sjkim if (ACPI_FAILURE (Status)) 193249112Sjkim { 194249112Sjkim return (Status); 195249112Sjkim } 196249112Sjkim 197210944Sjkim NextInterface = AcpiGbl_SupportedInterfaces; 198210944Sjkim while (NextInterface) 199210944Sjkim { 200210944Sjkim AcpiGbl_SupportedInterfaces = NextInterface->Next; 201210944Sjkim 202210944Sjkim if (NextInterface->Flags & ACPI_OSI_DYNAMIC) 203210944Sjkim { 204253690Sjkim /* Only interfaces added at runtime can be freed */ 205253690Sjkim 206210944Sjkim ACPI_FREE (NextInterface->Name); 207210944Sjkim ACPI_FREE (NextInterface); 208210944Sjkim } 209253690Sjkim else 210253690Sjkim { 211253690Sjkim /* Interface is in static list. Reset it to invalid or valid. */ 212210944Sjkim 213253690Sjkim if (NextInterface->Flags & ACPI_OSI_DEFAULT_INVALID) 214253690Sjkim { 215253690Sjkim NextInterface->Flags |= ACPI_OSI_INVALID; 216253690Sjkim } 217253690Sjkim else 218253690Sjkim { 219253690Sjkim NextInterface->Flags &= ~ACPI_OSI_INVALID; 220253690Sjkim } 221253690Sjkim } 222253690Sjkim 223210944Sjkim NextInterface = AcpiGbl_SupportedInterfaces; 224210944Sjkim } 225210944Sjkim 226210944Sjkim AcpiOsReleaseMutex (AcpiGbl_OsiMutex); 227249112Sjkim return (AE_OK); 228210944Sjkim} 229210944Sjkim 230210944Sjkim 231210944Sjkim/******************************************************************************* 232210944Sjkim * 233210944Sjkim * FUNCTION: AcpiUtInstallInterface 234210944Sjkim * 235210944Sjkim * PARAMETERS: InterfaceName - The interface to install 236210944Sjkim * 237210944Sjkim * RETURN: Status 238210944Sjkim * 239210944Sjkim * DESCRIPTION: Install the interface into the global interface list. 240210944Sjkim * Caller MUST hold AcpiGbl_OsiMutex 241210944Sjkim * 242210944Sjkim ******************************************************************************/ 243210944Sjkim 244210944SjkimACPI_STATUS 245210944SjkimAcpiUtInstallInterface ( 246210944Sjkim ACPI_STRING InterfaceName) 247210944Sjkim{ 248210944Sjkim ACPI_INTERFACE_INFO *InterfaceInfo; 249210944Sjkim 250210944Sjkim 251210944Sjkim /* Allocate info block and space for the name string */ 252210944Sjkim 253210944Sjkim InterfaceInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_INTERFACE_INFO)); 254210944Sjkim if (!InterfaceInfo) 255210944Sjkim { 256210944Sjkim return (AE_NO_MEMORY); 257210944Sjkim } 258210944Sjkim 259210944Sjkim InterfaceInfo->Name = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (InterfaceName) + 1); 260210944Sjkim if (!InterfaceInfo->Name) 261210944Sjkim { 262210944Sjkim ACPI_FREE (InterfaceInfo); 263210944Sjkim return (AE_NO_MEMORY); 264210944Sjkim } 265210944Sjkim 266210944Sjkim /* Initialize new info and insert at the head of the global list */ 267210944Sjkim 268210944Sjkim ACPI_STRCPY (InterfaceInfo->Name, InterfaceName); 269210944Sjkim InterfaceInfo->Flags = ACPI_OSI_DYNAMIC; 270210944Sjkim InterfaceInfo->Next = AcpiGbl_SupportedInterfaces; 271210944Sjkim 272210944Sjkim AcpiGbl_SupportedInterfaces = InterfaceInfo; 273210944Sjkim return (AE_OK); 274210944Sjkim} 275210944Sjkim 276210944Sjkim 277210944Sjkim/******************************************************************************* 278210944Sjkim * 279210944Sjkim * FUNCTION: AcpiUtRemoveInterface 280210944Sjkim * 281210944Sjkim * PARAMETERS: InterfaceName - The interface to remove 282210944Sjkim * 283210944Sjkim * RETURN: Status 284210944Sjkim * 285210944Sjkim * DESCRIPTION: Remove the interface from the global interface list. 286210944Sjkim * Caller MUST hold AcpiGbl_OsiMutex 287210944Sjkim * 288210944Sjkim ******************************************************************************/ 289210944Sjkim 290210944SjkimACPI_STATUS 291210944SjkimAcpiUtRemoveInterface ( 292210944Sjkim ACPI_STRING InterfaceName) 293210944Sjkim{ 294210944Sjkim ACPI_INTERFACE_INFO *PreviousInterface; 295210944Sjkim ACPI_INTERFACE_INFO *NextInterface; 296210944Sjkim 297210944Sjkim 298210944Sjkim PreviousInterface = NextInterface = AcpiGbl_SupportedInterfaces; 299210944Sjkim while (NextInterface) 300210944Sjkim { 301210944Sjkim if (!ACPI_STRCMP (InterfaceName, NextInterface->Name)) 302210944Sjkim { 303210944Sjkim /* Found: name is in either the static list or was added at runtime */ 304210944Sjkim 305210944Sjkim if (NextInterface->Flags & ACPI_OSI_DYNAMIC) 306210944Sjkim { 307210944Sjkim /* Interface was added dynamically, remove and free it */ 308210944Sjkim 309210944Sjkim if (PreviousInterface == NextInterface) 310210944Sjkim { 311210944Sjkim AcpiGbl_SupportedInterfaces = NextInterface->Next; 312210944Sjkim } 313210944Sjkim else 314210944Sjkim { 315210944Sjkim PreviousInterface->Next = NextInterface->Next; 316210944Sjkim } 317210944Sjkim 318210944Sjkim ACPI_FREE (NextInterface->Name); 319210944Sjkim ACPI_FREE (NextInterface); 320210944Sjkim } 321210944Sjkim else 322210944Sjkim { 323210944Sjkim /* 324210944Sjkim * Interface is in static list. If marked invalid, then it 325210944Sjkim * does not actually exist. Else, mark it invalid. 326210944Sjkim */ 327210944Sjkim if (NextInterface->Flags & ACPI_OSI_INVALID) 328210944Sjkim { 329210944Sjkim return (AE_NOT_EXIST); 330210944Sjkim } 331210944Sjkim 332210944Sjkim NextInterface->Flags |= ACPI_OSI_INVALID; 333210944Sjkim } 334210944Sjkim 335210944Sjkim return (AE_OK); 336210944Sjkim } 337210944Sjkim 338210944Sjkim PreviousInterface = NextInterface; 339210944Sjkim NextInterface = NextInterface->Next; 340210944Sjkim } 341210944Sjkim 342210944Sjkim /* Interface was not found */ 343210944Sjkim 344210944Sjkim return (AE_NOT_EXIST); 345210944Sjkim} 346210944Sjkim 347210944Sjkim 348210944Sjkim/******************************************************************************* 349210944Sjkim * 350253690Sjkim * FUNCTION: AcpiUtUpdateInterfaces 351253690Sjkim * 352253690Sjkim * PARAMETERS: Action - Actions to be performed during the 353253690Sjkim * update 354253690Sjkim * 355253690Sjkim * RETURN: Status 356253690Sjkim * 357253690Sjkim * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor 358253690Sjkim * strings or/and feature group strings. 359253690Sjkim * Caller MUST hold AcpiGbl_OsiMutex 360253690Sjkim * 361253690Sjkim ******************************************************************************/ 362253690Sjkim 363253690SjkimACPI_STATUS 364253690SjkimAcpiUtUpdateInterfaces ( 365253690Sjkim UINT8 Action) 366253690Sjkim{ 367253690Sjkim ACPI_INTERFACE_INFO *NextInterface; 368253690Sjkim 369253690Sjkim 370253690Sjkim NextInterface = AcpiGbl_SupportedInterfaces; 371253690Sjkim while (NextInterface) 372253690Sjkim { 373253690Sjkim if (((NextInterface->Flags & ACPI_OSI_FEATURE) && 374253690Sjkim (Action & ACPI_FEATURE_STRINGS)) || 375253690Sjkim (!(NextInterface->Flags & ACPI_OSI_FEATURE) && 376253690Sjkim (Action & ACPI_VENDOR_STRINGS))) 377253690Sjkim { 378253690Sjkim if (Action & ACPI_DISABLE_INTERFACES) 379253690Sjkim { 380253690Sjkim /* Mark the interfaces as invalid */ 381253690Sjkim 382253690Sjkim NextInterface->Flags |= ACPI_OSI_INVALID; 383253690Sjkim } 384253690Sjkim else 385253690Sjkim { 386253690Sjkim /* Mark the interfaces as valid */ 387253690Sjkim 388253690Sjkim NextInterface->Flags &= ~ACPI_OSI_INVALID; 389253690Sjkim } 390253690Sjkim } 391253690Sjkim 392253690Sjkim NextInterface = NextInterface->Next; 393253690Sjkim } 394253690Sjkim 395253690Sjkim return (AE_OK); 396253690Sjkim} 397253690Sjkim 398253690Sjkim 399253690Sjkim/******************************************************************************* 400253690Sjkim * 401210944Sjkim * FUNCTION: AcpiUtGetInterface 402210944Sjkim * 403210944Sjkim * PARAMETERS: InterfaceName - The interface to find 404210944Sjkim * 405210944Sjkim * RETURN: ACPI_INTERFACE_INFO if found. NULL if not found. 406210944Sjkim * 407210944Sjkim * DESCRIPTION: Search for the specified interface name in the global list. 408210944Sjkim * Caller MUST hold AcpiGbl_OsiMutex 409210944Sjkim * 410210944Sjkim ******************************************************************************/ 411210944Sjkim 412210944SjkimACPI_INTERFACE_INFO * 413210944SjkimAcpiUtGetInterface ( 414210944Sjkim ACPI_STRING InterfaceName) 415210944Sjkim{ 416210944Sjkim ACPI_INTERFACE_INFO *NextInterface; 417210944Sjkim 418210944Sjkim 419210944Sjkim NextInterface = AcpiGbl_SupportedInterfaces; 420210944Sjkim while (NextInterface) 421210944Sjkim { 422210944Sjkim if (!ACPI_STRCMP (InterfaceName, NextInterface->Name)) 423210944Sjkim { 424210944Sjkim return (NextInterface); 425210944Sjkim } 426210944Sjkim 427210944Sjkim NextInterface = NextInterface->Next; 428210944Sjkim } 429210944Sjkim 430210944Sjkim return (NULL); 431210944Sjkim} 432210944Sjkim 433210944Sjkim 434210944Sjkim/******************************************************************************* 435210944Sjkim * 436210944Sjkim * FUNCTION: AcpiUtOsiImplementation 437210944Sjkim * 438210944Sjkim * PARAMETERS: WalkState - Current walk state 439210944Sjkim * 440210944Sjkim * RETURN: Status 441210944Sjkim * 442210944Sjkim * DESCRIPTION: Implementation of the _OSI predefined control method. When 443210944Sjkim * an invocation of _OSI is encountered in the system AML, 444210944Sjkim * control is transferred to this function. 445210944Sjkim * 446210944Sjkim ******************************************************************************/ 447210944Sjkim 448210944SjkimACPI_STATUS 449210944SjkimAcpiUtOsiImplementation ( 450210944Sjkim ACPI_WALK_STATE *WalkState) 451210944Sjkim{ 452210944Sjkim ACPI_OPERAND_OBJECT *StringDesc; 453210944Sjkim ACPI_OPERAND_OBJECT *ReturnDesc; 454210944Sjkim ACPI_INTERFACE_INFO *InterfaceInfo; 455210944Sjkim ACPI_INTERFACE_HANDLER InterfaceHandler; 456249112Sjkim ACPI_STATUS Status; 457210944Sjkim UINT32 ReturnValue; 458210944Sjkim 459210944Sjkim 460210944Sjkim ACPI_FUNCTION_TRACE (UtOsiImplementation); 461210944Sjkim 462210944Sjkim 463210944Sjkim /* Validate the string input argument (from the AML caller) */ 464210944Sjkim 465210944Sjkim StringDesc = WalkState->Arguments[0].Object; 466210944Sjkim if (!StringDesc || 467210944Sjkim (StringDesc->Common.Type != ACPI_TYPE_STRING)) 468210944Sjkim { 469210944Sjkim return_ACPI_STATUS (AE_TYPE); 470210944Sjkim } 471210944Sjkim 472210944Sjkim /* Create a return object */ 473210944Sjkim 474210944Sjkim ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 475210944Sjkim if (!ReturnDesc) 476210944Sjkim { 477210944Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 478210944Sjkim } 479210944Sjkim 480210944Sjkim /* Default return value is 0, NOT SUPPORTED */ 481210944Sjkim 482210944Sjkim ReturnValue = 0; 483249112Sjkim Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); 484249112Sjkim if (ACPI_FAILURE (Status)) 485249112Sjkim { 486249663Sjkim AcpiUtRemoveReference (ReturnDesc); 487249112Sjkim return_ACPI_STATUS (Status); 488249112Sjkim } 489210944Sjkim 490210944Sjkim /* Lookup the interface in the global _OSI list */ 491210944Sjkim 492210944Sjkim InterfaceInfo = AcpiUtGetInterface (StringDesc->String.Pointer); 493210944Sjkim if (InterfaceInfo && 494210944Sjkim !(InterfaceInfo->Flags & ACPI_OSI_INVALID)) 495210944Sjkim { 496210944Sjkim /* 497210944Sjkim * The interface is supported. 498210944Sjkim * Update the OsiData if necessary. We keep track of the latest 499210944Sjkim * version of Windows that has been requested by the BIOS. 500210944Sjkim */ 501210944Sjkim if (InterfaceInfo->Value > AcpiGbl_OsiData) 502210944Sjkim { 503210944Sjkim AcpiGbl_OsiData = InterfaceInfo->Value; 504210944Sjkim } 505210944Sjkim 506210944Sjkim ReturnValue = ACPI_UINT32_MAX; 507210944Sjkim } 508210944Sjkim 509210944Sjkim AcpiOsReleaseMutex (AcpiGbl_OsiMutex); 510210944Sjkim 511210944Sjkim /* 512210944Sjkim * Invoke an optional _OSI interface handler. The host OS may wish 513210944Sjkim * to do some interface-specific handling. For example, warn about 514210944Sjkim * certain interfaces or override the true/false support value. 515210944Sjkim */ 516210944Sjkim InterfaceHandler = AcpiGbl_InterfaceHandler; 517210944Sjkim if (InterfaceHandler) 518210944Sjkim { 519210944Sjkim ReturnValue = InterfaceHandler ( 520210944Sjkim StringDesc->String.Pointer, ReturnValue); 521210944Sjkim } 522210944Sjkim 523210944Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, 524210944Sjkim "ACPI: BIOS _OSI(\"%s\") is %ssupported\n", 525210944Sjkim StringDesc->String.Pointer, ReturnValue == 0 ? "not " : "")); 526210944Sjkim 527210944Sjkim /* Complete the return object */ 528210944Sjkim 529210944Sjkim ReturnDesc->Integer.Value = ReturnValue; 530210944Sjkim WalkState->ReturnDesc = ReturnDesc; 531210944Sjkim return_ACPI_STATUS (AE_OK); 532210944Sjkim} 533