discussion about acpi_osi

来源:互联网 发布:三年二班文具淘宝店 编辑:程序博客网 时间:2024/04/30 22:34

 Let's take acpi_osi=! acpi_osi=!Darwin for example.

Initially, 

static struct osi_setup_entryosi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {{"Module Device", true},{"Processor Device", true},{"3.0 _SCP Extensions", true},{"Processor Aggregator Device", true},};

all the prepare things are done in acpi_osi_setup,

since it is a '!', we disable all the vendor strings,

if (*str == '!') {str++;if (*str == '\0') {osi_linux.default_disabling = 1;return;} }
and later in acpi_osi_setup_late, 
if (osi_linux.default_disabling) {status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);

will disable all the vendor string in acpica, such as Windows 2009, Windows 2012, etc:

static struct acpi_interface_info acpi_default_supported_interfaces[] = {/* Operating System Vendor Strings */{"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000},/* Windows 2000 */{"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP},/* Windows XP */{"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1},/* Windows XP SP1 */{"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003},/* Windows Server 2003 */{"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2},/* Windows XP SP2 */{"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1},/* Windows Server 2003 SP1 - Added 03/2006 */{"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA},/* Windows vista - Added 03/2006 */{"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008},/* Windows Server 2008 - Added 09/2009 */{"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1},/* Windows Vista SP1 - Added 09/2009 */{"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2},/* Windows Vista SP2 - Added 09/2010 */{"Windows 2009", NULL, 0, ACPI_OSI_WIN_7},/* Windows 7 and Server 2008 R2 - Added 09/2009 */{"Windows 2012", NULL, 0, ACPI_OSI_WIN_8},/* Windows 8 and Server 2012 - Added 08/2012 */{"Windows 2013", NULL, 0, ACPI_OSI_WIN_8},/* Windows 8.1 and Server 2012 R2 - Added 01/2014 */{"Windows 2015", NULL, 0, ACPI_OSI_WIN_10},/* Windows 10 - Added 03/2015 *//* Feature Group Strings */{"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0},/* * All "optional" feature group strings (features that are implemented * by the host) should be dynamically modified to VALID by the host via * acpi_install_interface or acpi_update_interfaces. Such optional feature * group strings are set as INVALID by default here. */{"Module Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},{"Processor Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},{"3.0 Thermal Model", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},{"3.0 _SCP Extensions", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},{"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}};

After acpi_osi=! , let's check how acpi_osi=Darwin is implemented:

It is also deal in:

void __init acpi_osi_setup(char *str){for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {osi = &osi_setup_entries[i];if (!strcmp(osi->string, str)) {osi->enable = enable;break;} else if (osi->string[0] == '\0') {osi->enable = enable;strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);break;}}}
So it looks if there is Darwin entry in the osi_setup_entries,

we set the flag for it; other wise find an empty entry to copy

the Darwin name to it and update its flag. In our case we fall

into the second case and set Darwin entry with disabled.


So come to acpi_osi_setup_late again:

for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {osi = &osi_setup_entries[i];str = osi->string;if (*str == '\0')break;if (osi->enable) {status = acpi_install_interface(str);if (ACPI_SUCCESS(status))printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);} else {status = acpi_remove_interface(str);if (ACPI_SUCCESS(status))printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);}}

We try to find an entry in the acpi_default_supported_interfaces however

there is no match entry, so we failed in acpi_remove_interface(Darwin).


So it remind us that, if you want to disable Darwin by acpi_osi command,

you should firstly add Darwin  support in the acpi_default_supported_interfaces

array, otherwise we don't get acpi_osi=!Darwin working. 

So why don't we add Darwin in the array? This is because,

the Apply product would query many OS version, such as:

 If (_OSI ("Darwin"))                {                    OSYS = 0x2710                }                If (\_OSI ("Linux"))                {                    OSYS = 0x03E8                }                If (\_OSI ("Windows 2009"))                {                    OSYS = 0x07D9                }                If (\_OSI ("Windows 2012"))                {                    OSYS = 0x07DC                }
This is ridiculous because even we support Darwin in the entry,and Linux 

return _OSI(Darwin) with true, we could possibly also get

_OSI(Windows 2009) of true, then the Apple product might regard

this platform as a non-apple platform, then close the Thunderbolt interface.

So here comes the first solution:

authorMatthew Garrett <matthew.garrett@nebula.com>Sat, 20 Sep 2014 19:19:47 +0800 (13:19 +0200)committerRafael J. Wysocki <rafael.j.wysocki@intel.com>Thu, 25 Sep 2014 05:31:12 +0800 (23:31 +0200)commit7bc5a2bad0b8d9d1ac9f7b8b33150e4ddf197334treea0dd3037aa6494c53edf89abb5e790f37a938d11tree | snapshotparent9faf6136ff4647452580b019f4b16f8c5082e589commit | diffACPI: Support _OSI("Darwin") correctlyApple hardware queries _OSI("Darwin") in order to determine whether thesystem is running OS X, and changes firmware behaviour based on theanswer.  The most obvious difference in behaviour is that Thunderbolthardware is forcibly powered down unless the system is running OS X. Theobvious solution would be to simply add Darwin to the list of supported_OSI strings, but this causes problems.Recent Apple hardware includes two separate methods for checking _OSIstrings. The first will check whether Darwin is supported, and if sowill exit. The second will check whether Darwin is supported, but willthen continue to check for further operating systems. If a furtheroperating system is found then later firmware code will assume that theOS is not OS X.  This results in the unfortunate situation where theThunderbolt controller is available at boot time but remains powereddown after suspend.The easiest way to handle this is to special-case it in theLinux-specific OSI handling code. If we see Darwin, we should answertrue and then disable all other _OSI vendor strings.


As we disccussed before, this does not solve acpi_osi=!Darwin not working problem,

so what we do is to introduce a DMI method that, when an Apple produce is detected,

we enable the Darwin by default, thus first disable all the default Vendor string by 

acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
and then enable Darwin string by acpi_install_interface(str); so that any

_OSI(Windows) would return false, however _OSI(Darwin) returns true.

 And for acpi_osi=!Darwin, we firstly should re-enable default vendor string such

as Windows 2009 Windows 2012, etc, which are disabled in dmi match, and then

we should disable Darwin by acpi_remove_interface(Darwin);  to achieve this goal.

And this patch is sent at:

https://patchwork.kernel.org/patch/8953891/





0 0
原创粉丝点击