1210944Sjkim/****************************************************************************** 2210944Sjkim * 3210944Sjkim * Module Name: utosi - Support for the _OSI predefined control method 4210944Sjkim * 5210944Sjkim *****************************************************************************/ 6210944Sjkim 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, 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 159306536Sjkim for (i = 0; 160306536Sjkim i < (ACPI_ARRAY_LENGTH (AcpiDefaultSupportedInterfaces) - 1); 161306536Sjkim i++) 162210944Sjkim { 163210944Sjkim AcpiDefaultSupportedInterfaces[i].Next = 164210944Sjkim &AcpiDefaultSupportedInterfaces[(ACPI_SIZE) i + 1]; 165210944Sjkim } 166210944Sjkim 167210944Sjkim AcpiOsReleaseMutex (AcpiGbl_OsiMutex); 168210944Sjkim return (AE_OK); 169210944Sjkim} 170210944Sjkim 171210944Sjkim 172210944Sjkim/******************************************************************************* 173210944Sjkim * 174210944Sjkim * FUNCTION: AcpiUtInterfaceTerminate 175210944Sjkim * 176210944Sjkim * PARAMETERS: None 177210944Sjkim * 178249112Sjkim * RETURN: Status 179210944Sjkim * 180210944Sjkim * DESCRIPTION: Delete all interfaces in the global list. Sets 181210944Sjkim * AcpiGbl_SupportedInterfaces to NULL. 182210944Sjkim * 183210944Sjkim ******************************************************************************/ 184210944Sjkim 185249112SjkimACPI_STATUS 186210944SjkimAcpiUtInterfaceTerminate ( 187210944Sjkim void) 188210944Sjkim{ 189249112Sjkim ACPI_STATUS Status; 190210944Sjkim ACPI_INTERFACE_INFO *NextInterface; 191210944Sjkim 192210944Sjkim 193249112Sjkim Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); 194249112Sjkim if (ACPI_FAILURE (Status)) 195249112Sjkim { 196249112Sjkim return (Status); 197249112Sjkim } 198249112Sjkim 199210944Sjkim NextInterface = AcpiGbl_SupportedInterfaces; 200210944Sjkim while (NextInterface) 201210944Sjkim { 202210944Sjkim AcpiGbl_SupportedInterfaces = NextInterface->Next; 203210944Sjkim 204210944Sjkim if (NextInterface->Flags & ACPI_OSI_DYNAMIC) 205210944Sjkim { 206253690Sjkim /* Only interfaces added at runtime can be freed */ 207253690Sjkim 208210944Sjkim ACPI_FREE (NextInterface->Name); 209210944Sjkim ACPI_FREE (NextInterface); 210210944Sjkim } 211253690Sjkim else 212253690Sjkim { 213253690Sjkim /* Interface is in static list. Reset it to invalid or valid. */ 214210944Sjkim 215253690Sjkim if (NextInterface->Flags & ACPI_OSI_DEFAULT_INVALID) 216253690Sjkim { 217253690Sjkim NextInterface->Flags |= ACPI_OSI_INVALID; 218253690Sjkim } 219253690Sjkim else 220253690Sjkim { 221253690Sjkim NextInterface->Flags &= ~ACPI_OSI_INVALID; 222253690Sjkim } 223253690Sjkim } 224253690Sjkim 225210944Sjkim NextInterface = AcpiGbl_SupportedInterfaces; 226210944Sjkim } 227210944Sjkim 228210944Sjkim AcpiOsReleaseMutex (AcpiGbl_OsiMutex); 229249112Sjkim return (AE_OK); 230210944Sjkim} 231210944Sjkim 232210944Sjkim 233210944Sjkim/******************************************************************************* 234210944Sjkim * 235210944Sjkim * FUNCTION: AcpiUtInstallInterface 236210944Sjkim * 237210944Sjkim * PARAMETERS: InterfaceName - The interface to install 238210944Sjkim * 239210944Sjkim * RETURN: Status 240210944Sjkim * 241210944Sjkim * DESCRIPTION: Install the interface into the global interface list. 242210944Sjkim * Caller MUST hold AcpiGbl_OsiMutex 243210944Sjkim * 244210944Sjkim ******************************************************************************/ 245210944Sjkim 246210944SjkimACPI_STATUS 247210944SjkimAcpiUtInstallInterface ( 248210944Sjkim ACPI_STRING InterfaceName) 249210944Sjkim{ 250210944Sjkim ACPI_INTERFACE_INFO *InterfaceInfo; 251210944Sjkim 252210944Sjkim 253210944Sjkim /* Allocate info block and space for the name string */ 254210944Sjkim 255210944Sjkim InterfaceInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_INTERFACE_INFO)); 256210944Sjkim if (!InterfaceInfo) 257210944Sjkim { 258210944Sjkim return (AE_NO_MEMORY); 259210944Sjkim } 260210944Sjkim 261306536Sjkim InterfaceInfo->Name = ACPI_ALLOCATE_ZEROED (strlen (InterfaceName) + 1); 262210944Sjkim if (!InterfaceInfo->Name) 263210944Sjkim { 264210944Sjkim ACPI_FREE (InterfaceInfo); 265210944Sjkim return (AE_NO_MEMORY); 266210944Sjkim } 267210944Sjkim 268210944Sjkim /* Initialize new info and insert at the head of the global list */ 269210944Sjkim 270306536Sjkim strcpy (InterfaceInfo->Name, InterfaceName); 271210944Sjkim InterfaceInfo->Flags = ACPI_OSI_DYNAMIC; 272210944Sjkim InterfaceInfo->Next = AcpiGbl_SupportedInterfaces; 273210944Sjkim 274210944Sjkim AcpiGbl_SupportedInterfaces = InterfaceInfo; 275210944Sjkim return (AE_OK); 276210944Sjkim} 277210944Sjkim 278210944Sjkim 279210944Sjkim/******************************************************************************* 280210944Sjkim * 281210944Sjkim * FUNCTION: AcpiUtRemoveInterface 282210944Sjkim * 283210944Sjkim * PARAMETERS: InterfaceName - The interface to remove 284210944Sjkim * 285210944Sjkim * RETURN: Status 286210944Sjkim * 287210944Sjkim * DESCRIPTION: Remove the interface from the global interface list. 288210944Sjkim * Caller MUST hold AcpiGbl_OsiMutex 289210944Sjkim * 290210944Sjkim ******************************************************************************/ 291210944Sjkim 292210944SjkimACPI_STATUS 293210944SjkimAcpiUtRemoveInterface ( 294210944Sjkim ACPI_STRING InterfaceName) 295210944Sjkim{ 296210944Sjkim ACPI_INTERFACE_INFO *PreviousInterface; 297210944Sjkim ACPI_INTERFACE_INFO *NextInterface; 298210944Sjkim 299210944Sjkim 300210944Sjkim PreviousInterface = NextInterface = AcpiGbl_SupportedInterfaces; 301210944Sjkim while (NextInterface) 302210944Sjkim { 303306536Sjkim if (!strcmp (InterfaceName, NextInterface->Name)) 304210944Sjkim { 305306536Sjkim /* 306306536Sjkim * Found: name is in either the static list 307306536Sjkim * or was added at runtime 308306536Sjkim */ 309210944Sjkim if (NextInterface->Flags & ACPI_OSI_DYNAMIC) 310210944Sjkim { 311210944Sjkim /* Interface was added dynamically, remove and free it */ 312210944Sjkim 313210944Sjkim if (PreviousInterface == NextInterface) 314210944Sjkim { 315210944Sjkim AcpiGbl_SupportedInterfaces = NextInterface->Next; 316210944Sjkim } 317210944Sjkim else 318210944Sjkim { 319210944Sjkim PreviousInterface->Next = NextInterface->Next; 320210944Sjkim } 321210944Sjkim 322210944Sjkim ACPI_FREE (NextInterface->Name); 323210944Sjkim ACPI_FREE (NextInterface); 324210944Sjkim } 325210944Sjkim else 326210944Sjkim { 327210944Sjkim /* 328306536Sjkim * Interface is in static list. If marked invalid, then 329306536Sjkim * it does not actually exist. Else, mark it invalid. 330210944Sjkim */ 331210944Sjkim if (NextInterface->Flags & ACPI_OSI_INVALID) 332210944Sjkim { 333210944Sjkim return (AE_NOT_EXIST); 334210944Sjkim } 335210944Sjkim 336210944Sjkim NextInterface->Flags |= ACPI_OSI_INVALID; 337210944Sjkim } 338210944Sjkim 339210944Sjkim return (AE_OK); 340210944Sjkim } 341210944Sjkim 342210944Sjkim PreviousInterface = NextInterface; 343210944Sjkim NextInterface = NextInterface->Next; 344210944Sjkim } 345210944Sjkim 346210944Sjkim /* Interface was not found */ 347210944Sjkim 348210944Sjkim return (AE_NOT_EXIST); 349210944Sjkim} 350210944Sjkim 351210944Sjkim 352210944Sjkim/******************************************************************************* 353210944Sjkim * 354253690Sjkim * FUNCTION: AcpiUtUpdateInterfaces 355253690Sjkim * 356253690Sjkim * PARAMETERS: Action - Actions to be performed during the 357253690Sjkim * update 358253690Sjkim * 359253690Sjkim * RETURN: Status 360253690Sjkim * 361253690Sjkim * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor 362253690Sjkim * strings or/and feature group strings. 363253690Sjkim * Caller MUST hold AcpiGbl_OsiMutex 364253690Sjkim * 365253690Sjkim ******************************************************************************/ 366253690Sjkim 367253690SjkimACPI_STATUS 368253690SjkimAcpiUtUpdateInterfaces ( 369253690Sjkim UINT8 Action) 370253690Sjkim{ 371253690Sjkim ACPI_INTERFACE_INFO *NextInterface; 372253690Sjkim 373253690Sjkim 374253690Sjkim NextInterface = AcpiGbl_SupportedInterfaces; 375253690Sjkim while (NextInterface) 376253690Sjkim { 377253690Sjkim if (((NextInterface->Flags & ACPI_OSI_FEATURE) && 378253690Sjkim (Action & ACPI_FEATURE_STRINGS)) || 379253690Sjkim (!(NextInterface->Flags & ACPI_OSI_FEATURE) && 380253690Sjkim (Action & ACPI_VENDOR_STRINGS))) 381253690Sjkim { 382253690Sjkim if (Action & ACPI_DISABLE_INTERFACES) 383253690Sjkim { 384253690Sjkim /* Mark the interfaces as invalid */ 385253690Sjkim 386253690Sjkim NextInterface->Flags |= ACPI_OSI_INVALID; 387253690Sjkim } 388253690Sjkim else 389253690Sjkim { 390253690Sjkim /* Mark the interfaces as valid */ 391253690Sjkim 392253690Sjkim NextInterface->Flags &= ~ACPI_OSI_INVALID; 393253690Sjkim } 394253690Sjkim } 395253690Sjkim 396253690Sjkim NextInterface = NextInterface->Next; 397253690Sjkim } 398253690Sjkim 399253690Sjkim return (AE_OK); 400253690Sjkim} 401253690Sjkim 402253690Sjkim 403253690Sjkim/******************************************************************************* 404253690Sjkim * 405210944Sjkim * FUNCTION: AcpiUtGetInterface 406210944Sjkim * 407210944Sjkim * PARAMETERS: InterfaceName - The interface to find 408210944Sjkim * 409210944Sjkim * RETURN: ACPI_INTERFACE_INFO if found. NULL if not found. 410210944Sjkim * 411210944Sjkim * DESCRIPTION: Search for the specified interface name in the global list. 412210944Sjkim * Caller MUST hold AcpiGbl_OsiMutex 413210944Sjkim * 414210944Sjkim ******************************************************************************/ 415210944Sjkim 416210944SjkimACPI_INTERFACE_INFO * 417210944SjkimAcpiUtGetInterface ( 418210944Sjkim ACPI_STRING InterfaceName) 419210944Sjkim{ 420210944Sjkim ACPI_INTERFACE_INFO *NextInterface; 421210944Sjkim 422210944Sjkim 423210944Sjkim NextInterface = AcpiGbl_SupportedInterfaces; 424210944Sjkim while (NextInterface) 425210944Sjkim { 426306536Sjkim if (!strcmp (InterfaceName, NextInterface->Name)) 427210944Sjkim { 428210944Sjkim return (NextInterface); 429210944Sjkim } 430210944Sjkim 431210944Sjkim NextInterface = NextInterface->Next; 432210944Sjkim } 433210944Sjkim 434210944Sjkim return (NULL); 435210944Sjkim} 436210944Sjkim 437210944Sjkim 438210944Sjkim/******************************************************************************* 439210944Sjkim * 440210944Sjkim * FUNCTION: AcpiUtOsiImplementation 441210944Sjkim * 442210944Sjkim * PARAMETERS: WalkState - Current walk state 443210944Sjkim * 444210944Sjkim * RETURN: Status 445210944Sjkim * 446210944Sjkim * DESCRIPTION: Implementation of the _OSI predefined control method. When 447210944Sjkim * an invocation of _OSI is encountered in the system AML, 448210944Sjkim * control is transferred to this function. 449210944Sjkim * 450210944Sjkim ******************************************************************************/ 451210944Sjkim 452210944SjkimACPI_STATUS 453210944SjkimAcpiUtOsiImplementation ( 454210944Sjkim ACPI_WALK_STATE *WalkState) 455210944Sjkim{ 456210944Sjkim ACPI_OPERAND_OBJECT *StringDesc; 457210944Sjkim ACPI_OPERAND_OBJECT *ReturnDesc; 458210944Sjkim ACPI_INTERFACE_INFO *InterfaceInfo; 459210944Sjkim ACPI_INTERFACE_HANDLER InterfaceHandler; 460249112Sjkim ACPI_STATUS Status; 461210944Sjkim UINT32 ReturnValue; 462210944Sjkim 463210944Sjkim 464210944Sjkim ACPI_FUNCTION_TRACE (UtOsiImplementation); 465210944Sjkim 466210944Sjkim 467210944Sjkim /* Validate the string input argument (from the AML caller) */ 468210944Sjkim 469210944Sjkim StringDesc = WalkState->Arguments[0].Object; 470210944Sjkim if (!StringDesc || 471210944Sjkim (StringDesc->Common.Type != ACPI_TYPE_STRING)) 472210944Sjkim { 473210944Sjkim return_ACPI_STATUS (AE_TYPE); 474210944Sjkim } 475210944Sjkim 476210944Sjkim /* Create a return object */ 477210944Sjkim 478210944Sjkim ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 479210944Sjkim if (!ReturnDesc) 480210944Sjkim { 481210944Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 482210944Sjkim } 483210944Sjkim 484210944Sjkim /* Default return value is 0, NOT SUPPORTED */ 485210944Sjkim 486210944Sjkim ReturnValue = 0; 487249112Sjkim Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); 488249112Sjkim if (ACPI_FAILURE (Status)) 489249112Sjkim { 490249663Sjkim AcpiUtRemoveReference (ReturnDesc); 491249112Sjkim return_ACPI_STATUS (Status); 492249112Sjkim } 493210944Sjkim 494210944Sjkim /* Lookup the interface in the global _OSI list */ 495210944Sjkim 496210944Sjkim InterfaceInfo = AcpiUtGetInterface (StringDesc->String.Pointer); 497210944Sjkim if (InterfaceInfo && 498210944Sjkim !(InterfaceInfo->Flags & ACPI_OSI_INVALID)) 499210944Sjkim { 500210944Sjkim /* 501210944Sjkim * The interface is supported. 502210944Sjkim * Update the OsiData if necessary. We keep track of the latest 503210944Sjkim * version of Windows that has been requested by the BIOS. 504210944Sjkim */ 505210944Sjkim if (InterfaceInfo->Value > AcpiGbl_OsiData) 506210944Sjkim { 507210944Sjkim AcpiGbl_OsiData = InterfaceInfo->Value; 508210944Sjkim } 509210944Sjkim 510210944Sjkim ReturnValue = ACPI_UINT32_MAX; 511210944Sjkim } 512210944Sjkim 513210944Sjkim AcpiOsReleaseMutex (AcpiGbl_OsiMutex); 514210944Sjkim 515210944Sjkim /* 516210944Sjkim * Invoke an optional _OSI interface handler. The host OS may wish 517210944Sjkim * to do some interface-specific handling. For example, warn about 518210944Sjkim * certain interfaces or override the true/false support value. 519210944Sjkim */ 520210944Sjkim InterfaceHandler = AcpiGbl_InterfaceHandler; 521210944Sjkim if (InterfaceHandler) 522210944Sjkim { 523210944Sjkim ReturnValue = InterfaceHandler ( 524210944Sjkim StringDesc->String.Pointer, ReturnValue); 525210944Sjkim } 526210944Sjkim 527210944Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, 528210944Sjkim "ACPI: BIOS _OSI(\"%s\") is %ssupported\n", 529210944Sjkim StringDesc->String.Pointer, ReturnValue == 0 ? "not " : "")); 530210944Sjkim 531210944Sjkim /* Complete the return object */ 532210944Sjkim 533210944Sjkim ReturnDesc->Integer.Value = ReturnValue; 534210944Sjkim WalkState->ReturnDesc = ReturnDesc; 535210944Sjkim return_ACPI_STATUS (AE_OK); 536210944Sjkim} 537