diff options
author | Lv Zheng <lv.zheng@intel.com> | 2013-07-22 04:08:25 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-07-22 22:06:56 -0400 |
commit | 5dc17986fdc3d2425838cb8d699152c3c30d1208 (patch) | |
tree | 7937dfdaacca0a6613daed8e50468d4fe2df697a /drivers/acpi/osl.c | |
parent | 2cf9f5bcc8d8cb31d6ea7baebac5056f39fb4f40 (diff) |
ACPI: Add facility to disable all _OSI OS vendor strings
This patch introduces "acpi_osi=!" command line to force Linux replying
"UNSUPPORTED" to all of the _OSI strings. This patch is based on an
ACPICA enhancement - the new API acpi_update_interfaces().
The _OSI object provides the platform with the ability to query OSPM
to determine the set of ACPI related interfaces, behaviors, or
features that the operating system supports. The argument passed to
the _OSI is a string like the followings:
1. Feature Group String, examples include
Module Device
Processor Device
3.0 _SCP Extensions
Processor Aggregator Device
...
2. OS Vendor String, examples include
Linux
FreeBSD
Windows
...
There are AML codes provided in the ACPI namespace written in the
following style to determine OSPM interfaces / features:
Method(OSCK)
{
if (CondRefOf(_OSI, Local0))
{
if (\_OSI("Windows"))
{
Return (One)
}
if (\_OSI("Windows 2006"))
{
Return (Ones)
}
Return (Zero)
}
Return (Zero)
}
There is a debugging facility implemented in Linux. Users can pass
"acpi_osi=" boot parameters to the kernel to tune the _OSI evaluation
result so that certain AML codes can be executed. Current
implementation includes:
1. 'acpi_osi=' - this makes CondRefOf(_OSI, Local0) TRUE
2. 'acpi_osi="Windows"' - this makes \_OSI("Windows") TRUE
3. 'acpi_osi="!Windows"' - this makes \_OSI("Windows") FALSE
The function to implement this feature is also used as a quirk mechanism
in the Linux ACPI subystem.
When _OSI is evaluatated by the AML codes, ACPICA replies "SUPPORTED"
to all Windows operating system vendor strings. This is because
Windows operating systems return "SUPPORTED" if the argument to the
_OSI method specifies an earlier version of Windows. Please refer to
the following MSDN document:
How to Identify the Windows Version in ACPI by Using _OSI
http://msdn.microsoft.com/en-us/library/hardware/gg463275.aspx
This adds difficulties when developers want to feed specific Windows
operating system vendor string to the BIOS codes for debugging
purpose, multiple acpi_osi="!xxx" have to be specified in the command
line to force Linux replying "UNSUPPORTED" to the Windows OS vendor
strings listed in the AML codes.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
Acked-by: Len Brown <len.brown@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6ab2c3505520..e8baa408faef 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -140,7 +140,8 @@ static struct osi_linux { | |||
140 | unsigned int enable:1; | 140 | unsigned int enable:1; |
141 | unsigned int dmi:1; | 141 | unsigned int dmi:1; |
142 | unsigned int cmdline:1; | 142 | unsigned int cmdline:1; |
143 | } osi_linux = {0, 0, 0}; | 143 | unsigned int default_disabling:1; |
144 | } osi_linux = {0, 0, 0, 0}; | ||
144 | 145 | ||
145 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | 146 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) |
146 | { | 147 | { |
@@ -1376,6 +1377,10 @@ void __init acpi_osi_setup(char *str) | |||
1376 | 1377 | ||
1377 | if (*str == '!') { | 1378 | if (*str == '!') { |
1378 | str++; | 1379 | str++; |
1380 | if (*str == '\0') { | ||
1381 | osi_linux.default_disabling = 1; | ||
1382 | return; | ||
1383 | } | ||
1379 | enable = false; | 1384 | enable = false; |
1380 | } | 1385 | } |
1381 | 1386 | ||
@@ -1441,6 +1446,13 @@ static void __init acpi_osi_setup_late(void) | |||
1441 | int i; | 1446 | int i; |
1442 | acpi_status status; | 1447 | acpi_status status; |
1443 | 1448 | ||
1449 | if (osi_linux.default_disabling) { | ||
1450 | status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS); | ||
1451 | |||
1452 | if (ACPI_SUCCESS(status)) | ||
1453 | printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors\n"); | ||
1454 | } | ||
1455 | |||
1444 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | 1456 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { |
1445 | osi = &osi_setup_entries[i]; | 1457 | osi = &osi_setup_entries[i]; |
1446 | str = osi->string; | 1458 | str = osi->string; |