2016-04-26 07:40:05

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH 0/4] ACPI / osi: Fix several issues in _OSI handling

This patchset cleans up _OSI handling code and fixes several issues in it.

Chen Yu (1):
ACPI / osi: Change default _OSI(Darwin) support

Lv Zheng (3):
ACPI / osi: Fix an issue that acpi_osi=!* cannot disable ACPICA
internal strings
ACPI / osi: Cleanup _OSI("Linux") related code before introducing new
support
ACPI / osi: Collect _OSI handling into one single file

Documentation/kernel-parameters.txt | 2 +
drivers/acpi/Makefile | 2 +-
drivers/acpi/blacklist.c | 196 +------------
drivers/acpi/internal.h | 2 +
drivers/acpi/osi.c | 521 +++++++++++++++++++++++++++++++++++
drivers/acpi/osl.c | 228 +--------------
include/linux/acpi.h | 1 -
7 files changed, 533 insertions(+), 419 deletions(-)
create mode 100644 drivers/acpi/osi.c

--
1.7.10


2016-04-26 07:40:21

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH 2/4] ACPI / osi: Cleanup _OSI("Linux") related code before introducing new support

This patch cleans up OSI code in osl.c in order to make osi_linux not
_OSI("Linux") specific to allow new features to reuse this structure.

Signed-off-by: Lv Zheng <[email protected]>
---
drivers/acpi/blacklist.c | 2 +-
drivers/acpi/osl.c | 83 +++++++++++++++++++---------------------------
include/linux/acpi.h | 2 +-
3 files changed, 36 insertions(+), 51 deletions(-)

diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index 96809cd..675a941 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -135,7 +135,7 @@ int __init acpi_blacklisted(void)
#ifdef CONFIG_DMI
static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
{
- acpi_dmi_osi_linux(1, d); /* enable */
+ acpi_dmi_osi_linux(true, d); /* enable */
return 0;
}
static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index d7d84a8..df1101e 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -131,24 +131,22 @@ static void __init acpi_osi_setup_late(void);
* or boot with "acpi_osi=Linux"
*/

-static struct osi_linux {
- unsigned int enable:1;
- unsigned int dmi:1;
- unsigned int cmdline:1;
+static struct acpi_osi_config {
u8 default_disabling;
-} osi_linux = {0, 0, 0, 0};
+ unsigned int linux_enable:1;
+ unsigned int linux_dmi:1;
+ unsigned int linux_cmdline:1;
+} osi_config;

static u32 acpi_osi_handler(acpi_string interface, u32 supported)
{
if (!strcmp("Linux", interface)) {
-
- printk_once(KERN_NOTICE FW_BUG PREFIX
+ pr_notice_once(FW_BUG
"BIOS _OSI(Linux) query %s%s\n",
- osi_linux.enable ? "honored" : "ignored",
- osi_linux.cmdline ? " via cmdline" :
- osi_linux.dmi ? " via DMI" : "");
+ osi_config.linux_enable ? "honored" : "ignored",
+ osi_config.linux_cmdline ? " via cmdline" :
+ osi_config.linux_dmi ? " via DMI" : "");
}
-
if (!strcmp("Darwin", interface)) {
/*
* Apple firmware will behave poorly if it receives positive
@@ -264,8 +262,7 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
return efi.acpi;
else {
- printk(KERN_ERR PREFIX
- "System description tables not found\n");
+ pr_err("System description tables not found\n");
return 0;
}
} else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
@@ -1469,7 +1466,7 @@ void __init acpi_osi_setup(char *str)
return;

if (str == NULL || *str == '\0') {
- printk(KERN_INFO PREFIX "_OSI method disabled\n");
+ pr_info("_OSI method disabled\n");
acpi_gbl_create_osi_method = FALSE;
return;
}
@@ -1478,12 +1475,12 @@ void __init acpi_osi_setup(char *str)
str++;
if (*str == '\0') {
/* Do not override acpi_osi=!* */
- if (!osi_linux.default_disabling)
- osi_linux.default_disabling =
+ if (!osi_config.default_disabling)
+ osi_config.default_disabling =
ACPI_DISABLE_ALL_VENDOR_STRINGS;
return;
} else if (*str == '*') {
- osi_linux.default_disabling = ACPI_DISABLE_ALL_STRINGS;
+ osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS;
for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
osi = &osi_setup_entries[i];
osi->enable = false;
@@ -1506,39 +1503,28 @@ void __init acpi_osi_setup(char *str)
}
}

-static void __init set_osi_linux(unsigned int enable)
+static void __init __acpi_osi_setup_linux(bool enable)
{
- if (osi_linux.enable != enable)
- osi_linux.enable = enable;
-
- if (osi_linux.enable)
+ osi_config.linux_enable = !!enable;
+ if (enable)
acpi_osi_setup("Linux");
else
acpi_osi_setup("!Linux");
-
- return;
}

-static void __init acpi_cmdline_osi_linux(unsigned int enable)
+static void __init acpi_osi_setup_linux(bool enable)
{
- osi_linux.cmdline = 1; /* cmdline set the default and override DMI */
- osi_linux.dmi = 0;
- set_osi_linux(enable);
-
- return;
+ osi_config.linux_cmdline = 1;
+ /* Override acpi_blacklisted() */
+ osi_config.linux_dmi = 0;
+ __acpi_osi_setup_linux(enable);
}

-void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
+void __init acpi_dmi_osi_linux(bool enable, const struct dmi_system_id *d)
{
- printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
-
- if (enable == -1)
- return;
-
- osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
- set_osi_linux(enable);
-
- return;
+ pr_notice("DMI detected to setup _OSI(\"Linux\"): %s\n", d->ident);
+ osi_config.linux_dmi = 1;
+ __acpi_osi_setup_linux(enable);
}

/*
@@ -1555,12 +1541,11 @@ static void __init acpi_osi_setup_late(void)
int i;
acpi_status status;

- if (osi_linux.default_disabling) {
- status = acpi_update_interfaces(osi_linux.default_disabling);
-
+ if (osi_config.default_disabling) {
+ status = acpi_update_interfaces(osi_config.default_disabling);
if (ACPI_SUCCESS(status))
- printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n",
- osi_linux.default_disabling ==
+ pr_info("Disabled all _OSI OS vendors%s\n",
+ osi_config.default_disabling ==
ACPI_DISABLE_ALL_STRINGS ?
" and feature groups" : "");
}
@@ -1575,12 +1560,12 @@ static void __init acpi_osi_setup_late(void)
status = acpi_install_interface(str);

if (ACPI_SUCCESS(status))
- printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+ pr_info("Added _OSI(%s)\n", str);
} else {
status = acpi_remove_interface(str);

if (ACPI_SUCCESS(status))
- printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+ pr_info("Deleted _OSI(%s)\n", str);
}
}
}
@@ -1588,9 +1573,9 @@ static void __init acpi_osi_setup_late(void)
static int __init osi_setup(char *str)
{
if (str && !strcmp("Linux", str))
- acpi_cmdline_osi_linux(1);
+ acpi_osi_setup_linux(true);
else if (str && !strcmp("!Linux", str))
- acpi_cmdline_osi_linux(0);
+ acpi_osi_setup_linux(false);
else
acpi_osi_setup(str);

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index be5d206..fceea1e 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -353,7 +353,7 @@ extern bool wmi_has_guid(const char *guid);
extern char acpi_video_backlight_string[];
extern long acpi_is_video_device(acpi_handle handle);
extern int acpi_blacklisted(void);
-extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
+extern void acpi_dmi_osi_linux(bool enable, const struct dmi_system_id *d);
extern void acpi_osi_setup(char *str);
extern bool acpi_osi_is_win8(void);

--
1.7.10

2016-04-26 07:40:39

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH 3/4] ACPI / osi: Change default _OSI(Darwin) support

From: Chen Yu <[email protected]>

Commit 7bc5a2bad0b8 ("ACPI: Support _OSI("Darwin") correctly") always
reports positive value when Apple hardware queries _OSI("Darwin"). However
since this implementation places the judgement in runtime, it breaks
acpi_osi=!Darwin and cannot return unsupported for _OSI("WinXXX") invoked
before invoking _OSI("Darwin").

This patch fixes the issues by reverting the wrong support and implementing
the default behavior of _OSI("Darwin")/_OSI("WinXXX") on Apple hardware via
DMI matching.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=92111
Reported-by: Lukas Wunner <[email protected]>
Signed-off-by: Chen Yu <[email protected]>
Signed-off-by: Lv Zheng <[email protected]>
---
Documentation/kernel-parameters.txt | 2 ++
drivers/acpi/blacklist.c | 23 ++++++++++++++++
drivers/acpi/osl.c | 49 ++++++++++++++++++++++++++++++-----
include/linux/acpi.h | 1 +
4 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 0b3de80..c48f387 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -312,6 +312,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
acpi_osi=!* # remove all strings
acpi_osi=! # disable all built-in OS vendor
strings
+ acpi_osi=!! # enable all built-in OS vendor
+ strings
acpi_osi= # disable all strings

'acpi_osi=!' can be used in combination with single or
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index 675a941..8fc1afe 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -133,6 +133,11 @@ int __init acpi_blacklisted(void)
return blacklisted;
}
#ifdef CONFIG_DMI
+static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d)
+{
+ acpi_dmi_osi_darwin(true, d); /* enable */
+ return 0;
+}
static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
{
acpi_dmi_osi_linux(true, d); /* enable */
@@ -331,6 +336,24 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
},
},

+ /*
+ * Enable _OSI("Darwin") for all apple platforms.
+ */
+ {
+ .callback = dmi_enable_osi_darwin,
+ .ident = "Apple hardware",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple INC."),
+ },
+ },
+ {
+ .callback = dmi_enable_osi_darwin,
+ .ident = "Apple hardware",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, INC."),
+ },
+ },
+
#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
/*
* DELL XPS 13 (2015) switches sound between HDA and I2S
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index df1101e..b00657b 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -136,6 +136,9 @@ static struct acpi_osi_config {
unsigned int linux_enable:1;
unsigned int linux_dmi:1;
unsigned int linux_cmdline:1;
+ unsigned int darwin_enable:1;
+ unsigned int darwin_dmi:1;
+ unsigned int darwin_cmdline:1;
} osi_config;

static u32 acpi_osi_handler(acpi_string interface, u32 supported)
@@ -148,13 +151,11 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported)
osi_config.linux_dmi ? " via DMI" : "");
}
if (!strcmp("Darwin", interface)) {
- /*
- * Apple firmware will behave poorly if it receives positive
- * answers to "Darwin" and any other OS. Respond positively
- * to Darwin and then disable all other vendor strings.
- */
- acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
- supported = ACPI_UINT32_MAX;
+ pr_notice_once(
+ "BIOS _OSI(Darwin) query %s%s\n",
+ osi_config.darwin_enable ? "honored" : "ignored",
+ osi_config.darwin_cmdline ? " via cmdline" :
+ osi_config.darwin_dmi ? " via DMI" : "");
}

return supported;
@@ -1486,6 +1487,9 @@ void __init acpi_osi_setup(char *str)
osi->enable = false;
}
return;
+ } else if (*str == '!') {
+ osi_config.default_disabling = 0;
+ return;
}
enable = false;
}
@@ -1503,6 +1507,33 @@ void __init acpi_osi_setup(char *str)
}
}

+static void __init __acpi_osi_setup_darwin(bool enable)
+{
+ osi_config.darwin_enable = !!enable;
+ if (enable) {
+ acpi_osi_setup("!");
+ acpi_osi_setup("Darwin");
+ } else {
+ acpi_osi_setup("!!");
+ acpi_osi_setup("!Darwin");
+ }
+}
+
+static void __init acpi_osi_setup_darwin(bool enable)
+{
+ osi_config.darwin_cmdline = 1;
+ /* Override acpi_blacklisted() */
+ osi_config.darwin_dmi = 0;
+ __acpi_osi_setup_darwin(enable);
+}
+
+void __init acpi_dmi_osi_darwin(bool enable, const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected to setup _OSI(\"Darwin\"): %s\n", d->ident);
+ osi_config.darwin_dmi = 1;
+ __acpi_osi_setup_darwin(enable);
+}
+
static void __init __acpi_osi_setup_linux(bool enable)
{
osi_config.linux_enable = !!enable;
@@ -1576,6 +1607,10 @@ static int __init osi_setup(char *str)
acpi_osi_setup_linux(true);
else if (str && !strcmp("!Linux", str))
acpi_osi_setup_linux(false);
+ else if (str && !strcmp("Darwin", str))
+ acpi_osi_setup_darwin(true);
+ else if (str && !strcmp("!Darwin", str))
+ acpi_osi_setup_darwin(false);
else
acpi_osi_setup(str);

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index fceea1e..1455919 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -354,6 +354,7 @@ extern char acpi_video_backlight_string[];
extern long acpi_is_video_device(acpi_handle handle);
extern int acpi_blacklisted(void);
extern void acpi_dmi_osi_linux(bool enable, const struct dmi_system_id *d);
+extern void acpi_dmi_osi_darwin(bool enable, const struct dmi_system_id *d);
extern void acpi_osi_setup(char *str);
extern bool acpi_osi_is_win8(void);

--
1.7.10

2016-04-26 07:40:41

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH 4/4] ACPI / osi: Collect _OSI handling into one single file

_OSI handling code grows giant and it's time to move them into one file.

This patch collects all _OSI handling code into one single file.
So that we only have the following functions to be used externally:
early_acpi_osi_init(): Used by DMI detections;
acpi_osi_init(): Used to initialize OSI command line settings and install
Linux specific _OSI handler;
acpi_osi_setup(): The API that should be used by the external quirks.
acpi_osi_is_win8(): The API is used by the external drivers to determine
if BIOS supports Win8.

CONFIG_DMI is not useful as stub dmi_check_system() can make everything
stub because of strip.

No functional changes.

Signed-off-by: Lv Zheng <[email protected]>
---
drivers/acpi/Makefile | 2 +-
drivers/acpi/blacklist.c | 219 +------------------
drivers/acpi/internal.h | 2 +
drivers/acpi/osi.c | 521 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/acpi/osl.c | 252 +---------------------
include/linux/acpi.h | 2 -
6 files changed, 530 insertions(+), 468 deletions(-)
create mode 100644 drivers/acpi/osi.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 5a65f85..251ce85 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -18,7 +18,7 @@ obj-$(CONFIG_ACPI) += acpi.o \
acpica/

# All the builtin files are in the "acpi." module_param namespace.
-acpi-y += osl.o utils.o reboot.o
+acpi-y += osi.o osl.o utils.o reboot.o
acpi-y += nvs.o

# Power management related files
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index 8fc1afe..bdc67ba 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -3,7 +3,7 @@
*
* Check to see if the given machine has a known bad ACPI BIOS
* or if the BIOS is too old.
- * Check given machine against acpi_osi_dmi_table[].
+ * Check given machine against acpi_rev_dmi_table[].
*
* Copyright (C) 2004 Len Brown <[email protected]>
* Copyright (C) 2002 Andy Grover <[email protected]>
@@ -47,7 +47,7 @@ struct acpi_blacklist_item {
u32 is_critical_error;
};

-static struct dmi_system_id acpi_osi_dmi_table[] __initdata;
+static struct dmi_system_id acpi_rev_dmi_table[] __initdata;

/*
* POLICY: If *anything* doesn't work, put it on the blacklist.
@@ -128,41 +128,12 @@ int __init acpi_blacklisted(void)
}
}

- dmi_check_system(acpi_osi_dmi_table);
+ (void)early_acpi_osi_init();
+ dmi_check_system(acpi_rev_dmi_table);

return blacklisted;
}
#ifdef CONFIG_DMI
-static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d)
-{
- acpi_dmi_osi_darwin(true, d); /* enable */
- return 0;
-}
-static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
-{
- acpi_dmi_osi_linux(true, d); /* enable */
- return 0;
-}
-static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
-{
- printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
- acpi_osi_setup("!Windows 2006");
- acpi_osi_setup("!Windows 2006 SP1");
- acpi_osi_setup("!Windows 2006 SP2");
- return 0;
-}
-static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
-{
- printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
- acpi_osi_setup("!Windows 2009");
- return 0;
-}
-static int __init dmi_disable_osi_win8(const struct dmi_system_id *d)
-{
- printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
- acpi_osi_setup("!Windows 2012");
- return 0;
-}
#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
static int __init dmi_enable_rev_override(const struct dmi_system_id *d)
{
@@ -173,187 +144,7 @@ static int __init dmi_enable_rev_override(const struct dmi_system_id *d)
}
#endif

-static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Fujitsu Siemens",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
- DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
- },
- },
- {
- /*
- * There have a NVIF method in MSI GX723 DSDT need call by Nvidia
- * driver (e.g. nouveau) when user press brightness hotkey.
- * Currently, nouveau driver didn't do the job and it causes there
- * have a infinite while loop in DSDT when user press hotkey.
- * We add MSI GX723's dmi information to this table for workaround
- * this issue.
- * Will remove MSI GX723 from the table after nouveau grows support.
- */
- .callback = dmi_disable_osi_vista,
- .ident = "MSI GX723",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
- DMI_MATCH(DMI_PRODUCT_NAME, "GX723"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Sony VGN-NS10J_S",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Sony VGN-SR290J",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "VGN-NS50B_L",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "VGN-SR19XN",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Toshiba Satellite L355",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"),
- },
- },
- {
- .callback = dmi_disable_osi_win7,
- .ident = "ASUS K50IJ",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Toshiba P305D",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Toshiba NB100",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
- DMI_MATCH(DMI_PRODUCT_NAME, "NB100"),
- },
- },
-
- /*
- * The wireless hotkey does not work on those machines when
- * returning true for _OSI("Windows 2012")
- */
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Inspiron 7737",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Inspiron 7537",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Inspiron 5437",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Inspiron 3437",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Vostro 3446",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Vostro 3546",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"),
- },
- },
-
- /*
- * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
- * Linux ignores it, except for the machines enumerated below.
- */
-
- /*
- * Without this this EEEpc exports a non working WMI interface, with
- * this it exports a working "good old" eeepc_laptop interface, fixing
- * both brightness control, and rfkill not working.
- */
- {
- .callback = dmi_enable_osi_linux,
- .ident = "Asus EEE PC 1015PX",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
- DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"),
- },
- },
-
- /*
- * Enable _OSI("Darwin") for all apple platforms.
- */
- {
- .callback = dmi_enable_osi_darwin,
- .ident = "Apple hardware",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Apple INC."),
- },
- },
- {
- .callback = dmi_enable_osi_darwin,
- .ident = "Apple hardware",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, INC."),
- },
- },
-
+static struct dmi_system_id acpi_rev_dmi_table[] __initdata = {
#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
/*
* DELL XPS 13 (2015) switches sound between HDA and I2S
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 1b0e6fd..9bb0773 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -20,6 +20,8 @@

#define PREFIX "ACPI: "

+int early_acpi_osi_init(void);
+int acpi_osi_init(void);
acpi_status acpi_os_initialize1(void);
void init_acpi_device_notify(void);
int acpi_scan_init(void);
diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c
new file mode 100644
index 0000000..2870bec
--- /dev/null
+++ b/drivers/acpi/osi.c
@@ -0,0 +1,521 @@
+/*
+ * osi.c - _OSI implementation
+ *
+ * Copyright (C) 2016 Intel Corporation
+ * Author: Lv Zheng <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+
+#include "internal.h"
+
+
+#define OSI_STRING_LENGTH_MAX 64
+#define OSI_STRING_ENTRIES_MAX 16
+
+struct acpi_osi_entry {
+ char string[OSI_STRING_LENGTH_MAX];
+ bool enable;
+};
+
+static struct acpi_osi_config {
+ u8 default_disabling;
+ unsigned int linux_enable:1;
+ unsigned int linux_dmi:1;
+ unsigned int linux_cmdline:1;
+ unsigned int darwin_enable:1;
+ unsigned int darwin_dmi:1;
+ unsigned int darwin_cmdline:1;
+} osi_config;
+
+static struct acpi_osi_config osi_config;
+static struct acpi_osi_entry
+osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {
+ {"Module Device", true},
+ {"Processor Device", true},
+ {"3.0 _SCP Extensions", true},
+ {"Processor Aggregator Device", true},
+};
+
+static u32 acpi_osi_handler(acpi_string interface, u32 supported)
+{
+ if (!strcmp("Linux", interface)) {
+ pr_notice_once(FW_BUG
+ "BIOS _OSI(Linux) query %s%s\n",
+ osi_config.linux_enable ? "honored" : "ignored",
+ osi_config.linux_cmdline ? " via cmdline" :
+ osi_config.linux_dmi ? " via DMI" : "");
+ }
+ if (!strcmp("Darwin", interface)) {
+ pr_notice_once(
+ "BIOS _OSI(Darwin) query %s%s\n",
+ osi_config.darwin_enable ? "honored" : "ignored",
+ osi_config.darwin_cmdline ? " via cmdline" :
+ osi_config.darwin_dmi ? " via DMI" : "");
+ }
+
+ return supported;
+}
+
+void __init acpi_osi_setup(char *str)
+{
+ struct acpi_osi_entry *osi;
+ bool enable = true;
+ int i;
+
+ if (!acpi_gbl_create_osi_method)
+ return;
+
+ if (str == NULL || *str == '\0') {
+ pr_info("_OSI method disabled\n");
+ acpi_gbl_create_osi_method = FALSE;
+ return;
+ }
+
+ if (*str == '!') {
+ str++;
+ if (*str == '\0') {
+ /* Do not override acpi_osi=!* */
+ if (!osi_config.default_disabling)
+ osi_config.default_disabling =
+ ACPI_DISABLE_ALL_VENDOR_STRINGS;
+ return;
+ } else if (*str == '*') {
+ osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS;
+ for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+ osi = &osi_setup_entries[i];
+ osi->enable = false;
+ }
+ return;
+ } else if (*str == '!') {
+ osi_config.default_disabling = 0;
+ return;
+ }
+ enable = false;
+ }
+
+ 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;
+ }
+ }
+}
+
+static void __init __acpi_osi_setup_darwin(bool enable)
+{
+ osi_config.darwin_enable = !!enable;
+ if (enable) {
+ acpi_osi_setup("!");
+ acpi_osi_setup("Darwin");
+ } else {
+ acpi_osi_setup("!!");
+ acpi_osi_setup("!Darwin");
+ }
+}
+
+static void __init acpi_osi_setup_darwin(bool enable)
+{
+ osi_config.darwin_cmdline = 1;
+ /* Override acpi_osi_dmi_blacklisted() */
+ osi_config.darwin_dmi = 0;
+ __acpi_osi_setup_darwin(enable);
+}
+
+/*
+ * The story of _OSI(Linux)
+ *
+ * From pre-history through Linux-2.6.22, Linux responded TRUE upon a BIOS
+ * OSI(Linux) query.
+ *
+ * Unfortunately, reference BIOS writers got wind of this and put
+ * OSI(Linux) in their example code, quickly exposing this string as
+ * ill-conceived and opening the door to an un-bounded number of BIOS
+ * incompatibilities.
+ *
+ * For example, OSI(Linux) was used on resume to re-POST a video card on
+ * one system, because Linux at that time could not do a speedy restore in
+ * its native driver. But then upon gaining quick native restore
+ * capability, Linux has no way to tell the BIOS to skip the time-consuming
+ * POST -- putting Linux at a permanent performance disadvantage. On
+ * another system, the BIOS writer used OSI(Linux) to infer native OS
+ * support for IPMI! On other systems, OSI(Linux) simply got in the way of
+ * Linux claiming to be compatible with other operating systems, exposing
+ * BIOS issues such as skipped device initialization.
+ *
+ * So "Linux" turned out to be a really poor chose of OSI string, and from
+ * Linux-2.6.23 onward we respond FALSE.
+ *
+ * BIOS writers should NOT query _OSI(Linux) on future systems. Linux will
+ * complain on the console when it sees it, and return FALSE. To get Linux
+ * to return TRUE for your system will require a kernel source update to
+ * add a DMI entry, or boot with "acpi_osi=Linux"
+ */
+static void __init __acpi_osi_setup_linux(bool enable)
+{
+ osi_config.linux_enable = !!enable;
+ if (enable)
+ acpi_osi_setup("Linux");
+ else
+ acpi_osi_setup("!Linux");
+}
+
+static void __init acpi_osi_setup_linux(bool enable)
+{
+ osi_config.linux_cmdline = 1;
+ /* Override acpi_osi_dmi_blacklisted() */
+ osi_config.linux_dmi = 0;
+ __acpi_osi_setup_linux(enable);
+}
+
+/*
+ * Modify the list of "OS Interfaces" reported to BIOS via _OSI
+ *
+ * empty string disables _OSI
+ * string starting with '!' disables that string
+ * otherwise string is added to list, augmenting built-in strings
+ */
+static void __init acpi_osi_setup_late(void)
+{
+ struct acpi_osi_entry *osi;
+ char *str;
+ int i;
+ acpi_status status;
+
+ if (osi_config.default_disabling) {
+ status = acpi_update_interfaces(osi_config.default_disabling);
+ if (ACPI_SUCCESS(status))
+ pr_info("Disabled all _OSI OS vendors%s\n",
+ osi_config.default_disabling ==
+ ACPI_DISABLE_ALL_STRINGS ?
+ " and feature groups" : "");
+ }
+
+ 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))
+ pr_info("Added _OSI(%s)\n", str);
+ } else {
+ status = acpi_remove_interface(str);
+
+ if (ACPI_SUCCESS(status))
+ pr_info("Deleted _OSI(%s)\n", str);
+ }
+ }
+}
+
+static int __init osi_setup(char *str)
+{
+ if (str && !strcmp("Linux", str))
+ acpi_osi_setup_linux(true);
+ else if (str && !strcmp("!Linux", str))
+ acpi_osi_setup_linux(false);
+ else if (str && !strcmp("Darwin", str))
+ acpi_osi_setup_darwin(true);
+ else if (str && !strcmp("!Darwin", str))
+ acpi_osi_setup_darwin(false);
+ else
+ acpi_osi_setup(str);
+
+ return 1;
+}
+__setup("acpi_osi=", osi_setup);
+
+bool acpi_osi_is_win8(void)
+{
+ return acpi_gbl_osi_data >= ACPI_OSI_WIN_8;
+}
+EXPORT_SYMBOL(acpi_osi_is_win8);
+
+static void __init acpi_osi_dmi_darwin(bool enable,
+ const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected to setup _OSI(\"Darwin\"): %s\n", d->ident);
+ osi_config.darwin_dmi = 1;
+ __acpi_osi_setup_darwin(enable);
+}
+
+void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected to setup _OSI(\"Linux\"): %s\n", d->ident);
+ osi_config.linux_dmi = 1;
+ __acpi_osi_setup_linux(enable);
+}
+
+static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d)
+{
+ acpi_osi_dmi_darwin(true, d);
+
+ return 0;
+}
+
+static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
+{
+ acpi_osi_dmi_linux(true, d);
+
+ return 0;
+}
+
+static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected: %s\n", d->ident);
+ acpi_osi_setup("!Windows 2006");
+ acpi_osi_setup("!Windows 2006 SP1");
+ acpi_osi_setup("!Windows 2006 SP2");
+
+ return 0;
+}
+
+static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected: %s\n", d->ident);
+ acpi_osi_setup("!Windows 2009");
+
+ return 0;
+}
+
+static int __init dmi_disable_osi_win8(const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected: %s\n", d->ident);
+ acpi_osi_setup("!Windows 2012");
+
+ return 0;
+}
+
+/*
+ * Linux default _OSI response behavior is determined by this DMI table.
+ *
+ * Note that _OSI("Linux")/_OSI("Darwin") determined here can be overridden
+ * by acpi_osi=!Linux/acpi_osi=!Darwin command line options.
+ */
+static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Fujitsu Siemens",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
+ },
+ },
+ {
+ /*
+ * There have a NVIF method in MSI GX723 DSDT need call by Nvidia
+ * driver (e.g. nouveau) when user press brightness hotkey.
+ * Currently, nouveau driver didn't do the job and it causes there
+ * have a infinite while loop in DSDT when user press hotkey.
+ * We add MSI GX723's dmi information to this table for workaround
+ * this issue.
+ * Will remove MSI GX723 from the table after nouveau grows support.
+ */
+ .callback = dmi_disable_osi_vista,
+ .ident = "MSI GX723",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GX723"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Sony VGN-NS10J_S",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Sony VGN-SR290J",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "VGN-NS50B_L",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "VGN-SR19XN",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Toshiba Satellite L355",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win7,
+ .ident = "ASUS K50IJ",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Toshiba P305D",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Toshiba NB100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "NB100"),
+ },
+ },
+
+ /*
+ * The wireless hotkey does not work on those machines when
+ * returning true for _OSI("Windows 2012")
+ */
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Inspiron 7737",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Inspiron 7537",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Inspiron 5437",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Inspiron 3437",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Vostro 3446",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Vostro 3546",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"),
+ },
+ },
+
+ /*
+ * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
+ * Linux ignores it, except for the machines enumerated below.
+ */
+
+ /*
+ * Without this this EEEpc exports a non working WMI interface, with
+ * this it exports a working "good old" eeepc_laptop interface, fixing
+ * both brightness control, and rfkill not working.
+ */
+ {
+ .callback = dmi_enable_osi_linux,
+ .ident = "Asus EEE PC 1015PX",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"),
+ },
+ },
+
+ /*
+ * Enable _OSI("Darwin") for all apple platforms.
+ */
+ {
+ .callback = dmi_enable_osi_darwin,
+ .ident = "Apple hardware",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple INC."),
+ },
+ },
+ {
+ .callback = dmi_enable_osi_darwin,
+ .ident = "Apple hardware",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, INC."),
+ },
+ },
+ {}
+};
+
+static __init void acpi_osi_dmi_blacklisted(void)
+{
+ dmi_check_system(acpi_osi_dmi_table);
+}
+
+int __init early_acpi_osi_init(void)
+{
+ acpi_osi_dmi_blacklisted();
+
+ return 0;
+}
+
+int __init acpi_osi_init(void)
+{
+ acpi_install_interface_handler(acpi_osi_handler);
+ acpi_osi_setup_late();
+
+ return 0;
+}
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index b00657b..45cab33 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -96,71 +96,6 @@ struct acpi_ioremap {
static LIST_HEAD(acpi_ioremaps);
static DEFINE_MUTEX(acpi_ioremap_lock);

-static void __init acpi_osi_setup_late(void);
-
-/*
- * The story of _OSI(Linux)
- *
- * From pre-history through Linux-2.6.22,
- * Linux responded TRUE upon a BIOS OSI(Linux) query.
- *
- * Unfortunately, reference BIOS writers got wind of this
- * and put OSI(Linux) in their example code, quickly exposing
- * this string as ill-conceived and opening the door to
- * an un-bounded number of BIOS incompatibilities.
- *
- * For example, OSI(Linux) was used on resume to re-POST a
- * video card on one system, because Linux at that time
- * could not do a speedy restore in its native driver.
- * But then upon gaining quick native restore capability,
- * Linux has no way to tell the BIOS to skip the time-consuming
- * POST -- putting Linux at a permanent performance disadvantage.
- * On another system, the BIOS writer used OSI(Linux)
- * to infer native OS support for IPMI! On other systems,
- * OSI(Linux) simply got in the way of Linux claiming to
- * be compatible with other operating systems, exposing
- * BIOS issues such as skipped device initialization.
- *
- * So "Linux" turned out to be a really poor chose of
- * OSI string, and from Linux-2.6.23 onward we respond FALSE.
- *
- * BIOS writers should NOT query _OSI(Linux) on future systems.
- * Linux will complain on the console when it sees it, and return FALSE.
- * To get Linux to return TRUE for your system will require
- * a kernel source update to add a DMI entry,
- * or boot with "acpi_osi=Linux"
- */
-
-static struct acpi_osi_config {
- u8 default_disabling;
- unsigned int linux_enable:1;
- unsigned int linux_dmi:1;
- unsigned int linux_cmdline:1;
- unsigned int darwin_enable:1;
- unsigned int darwin_dmi:1;
- unsigned int darwin_cmdline:1;
-} osi_config;
-
-static u32 acpi_osi_handler(acpi_string interface, u32 supported)
-{
- if (!strcmp("Linux", interface)) {
- pr_notice_once(FW_BUG
- "BIOS _OSI(Linux) query %s%s\n",
- osi_config.linux_enable ? "honored" : "ignored",
- osi_config.linux_cmdline ? " via cmdline" :
- osi_config.linux_dmi ? " via DMI" : "");
- }
- if (!strcmp("Darwin", interface)) {
- pr_notice_once(
- "BIOS _OSI(Darwin) query %s%s\n",
- osi_config.darwin_enable ? "honored" : "ignored",
- osi_config.darwin_cmdline ? " via cmdline" :
- osi_config.darwin_dmi ? " via DMI" : "");
- }
-
- return supported;
-}
-
static void __init acpi_request_region (struct acpi_generic_address *gas,
unsigned int length, char *desc)
{
@@ -1441,184 +1376,6 @@ static int __init acpi_os_name_setup(char *str)

__setup("acpi_os_name=", acpi_os_name_setup);

-#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
-#define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */
-
-struct osi_setup_entry {
- char string[OSI_STRING_LENGTH_MAX];
- bool enable;
-};
-
-static struct osi_setup_entry
- osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {
- {"Module Device", true},
- {"Processor Device", true},
- {"3.0 _SCP Extensions", true},
- {"Processor Aggregator Device", true},
-};
-
-void __init acpi_osi_setup(char *str)
-{
- struct osi_setup_entry *osi;
- bool enable = true;
- int i;
-
- if (!acpi_gbl_create_osi_method)
- return;
-
- if (str == NULL || *str == '\0') {
- pr_info("_OSI method disabled\n");
- acpi_gbl_create_osi_method = FALSE;
- return;
- }
-
- if (*str == '!') {
- str++;
- if (*str == '\0') {
- /* Do not override acpi_osi=!* */
- if (!osi_config.default_disabling)
- osi_config.default_disabling =
- ACPI_DISABLE_ALL_VENDOR_STRINGS;
- return;
- } else if (*str == '*') {
- osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS;
- for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
- osi = &osi_setup_entries[i];
- osi->enable = false;
- }
- return;
- } else if (*str == '!') {
- osi_config.default_disabling = 0;
- return;
- }
- enable = false;
- }
-
- 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;
- }
- }
-}
-
-static void __init __acpi_osi_setup_darwin(bool enable)
-{
- osi_config.darwin_enable = !!enable;
- if (enable) {
- acpi_osi_setup("!");
- acpi_osi_setup("Darwin");
- } else {
- acpi_osi_setup("!!");
- acpi_osi_setup("!Darwin");
- }
-}
-
-static void __init acpi_osi_setup_darwin(bool enable)
-{
- osi_config.darwin_cmdline = 1;
- /* Override acpi_blacklisted() */
- osi_config.darwin_dmi = 0;
- __acpi_osi_setup_darwin(enable);
-}
-
-void __init acpi_dmi_osi_darwin(bool enable, const struct dmi_system_id *d)
-{
- pr_notice("DMI detected to setup _OSI(\"Darwin\"): %s\n", d->ident);
- osi_config.darwin_dmi = 1;
- __acpi_osi_setup_darwin(enable);
-}
-
-static void __init __acpi_osi_setup_linux(bool enable)
-{
- osi_config.linux_enable = !!enable;
- if (enable)
- acpi_osi_setup("Linux");
- else
- acpi_osi_setup("!Linux");
-}
-
-static void __init acpi_osi_setup_linux(bool enable)
-{
- osi_config.linux_cmdline = 1;
- /* Override acpi_blacklisted() */
- osi_config.linux_dmi = 0;
- __acpi_osi_setup_linux(enable);
-}
-
-void __init acpi_dmi_osi_linux(bool enable, const struct dmi_system_id *d)
-{
- pr_notice("DMI detected to setup _OSI(\"Linux\"): %s\n", d->ident);
- osi_config.linux_dmi = 1;
- __acpi_osi_setup_linux(enable);
-}
-
-/*
- * Modify the list of "OS Interfaces" reported to BIOS via _OSI
- *
- * empty string disables _OSI
- * string starting with '!' disables that string
- * otherwise string is added to list, augmenting built-in strings
- */
-static void __init acpi_osi_setup_late(void)
-{
- struct osi_setup_entry *osi;
- char *str;
- int i;
- acpi_status status;
-
- if (osi_config.default_disabling) {
- status = acpi_update_interfaces(osi_config.default_disabling);
- if (ACPI_SUCCESS(status))
- pr_info("Disabled all _OSI OS vendors%s\n",
- osi_config.default_disabling ==
- ACPI_DISABLE_ALL_STRINGS ?
- " and feature groups" : "");
- }
-
- 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))
- pr_info("Added _OSI(%s)\n", str);
- } else {
- status = acpi_remove_interface(str);
-
- if (ACPI_SUCCESS(status))
- pr_info("Deleted _OSI(%s)\n", str);
- }
- }
-}
-
-static int __init osi_setup(char *str)
-{
- if (str && !strcmp("Linux", str))
- acpi_osi_setup_linux(true);
- else if (str && !strcmp("!Linux", str))
- acpi_osi_setup_linux(false);
- else if (str && !strcmp("Darwin", str))
- acpi_osi_setup_darwin(true);
- else if (str && !strcmp("!Darwin", str))
- acpi_osi_setup_darwin(false);
- else
- acpi_osi_setup(str);
-
- return 1;
-}
-
-__setup("acpi_osi=", osi_setup);
-
/*
* Disable the auto-serialization of named objects creation methods.
*
@@ -1738,12 +1495,6 @@ int acpi_resources_are_enforced(void)
}
EXPORT_SYMBOL(acpi_resources_are_enforced);

-bool acpi_osi_is_win8(void)
-{
- return acpi_gbl_osi_data >= ACPI_OSI_WIN_8;
-}
-EXPORT_SYMBOL(acpi_osi_is_win8);
-
/*
* Deallocate the memory for a spinlock.
*/
@@ -1909,8 +1660,7 @@ acpi_status __init acpi_os_initialize1(void)
BUG_ON(!kacpid_wq);
BUG_ON(!kacpi_notify_wq);
BUG_ON(!kacpi_hotplug_wq);
- acpi_install_interface_handler(acpi_osi_handler);
- acpi_osi_setup_late();
+ acpi_osi_init();
return AE_OK;
}

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 1455919..b25690b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -353,8 +353,6 @@ extern bool wmi_has_guid(const char *guid);
extern char acpi_video_backlight_string[];
extern long acpi_is_video_device(acpi_handle handle);
extern int acpi_blacklisted(void);
-extern void acpi_dmi_osi_linux(bool enable, const struct dmi_system_id *d);
-extern void acpi_dmi_osi_darwin(bool enable, const struct dmi_system_id *d);
extern void acpi_osi_setup(char *str);
extern bool acpi_osi_is_win8(void);

--
1.7.10

2016-04-26 07:41:28

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH 1/4] ACPI / osi: Fix an issue that acpi_osi=!* cannot disable ACPICA internal strings

The order of the _OSI related functionalities is as follows:
acpi_blacklisted()
acpi_dmi_osi_linux()
acpi_osi_setup()
acpi_osi_setup()
acpi_update_interfaces() if "!*"
<<<<<<<<<<<<<<<<<<<<<<<<
parse_args()
__setup("acpi_osi=")
acpi_osi_setup_linux()
acpi_update_interfaces() if "!*"
<<<<<<<<<<<<<<<<<<<<<<<<
acpi_early_init()
acpi_initialize_subsystem()
acpi_ut_initialize_interfaces()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
acpi_bus_init()
acpi_os_initialize1()
acpi_install_interface_handler(acpi_osi_handler)
acpi_osi_setup_late()
acpi_update_interfaces() for "!"
>>>>>>>>>>>>>>>>>>>>>>>>
acpi_osi_handler()
Since acpi_osi_setup_linux() can override acpi_dmi_osi_linux(), the command
line setting can override the DMI detection. That's why acpi_blacklisted()
is put before __setup("acpi_osi=").

Then we can notice the following wrong invocation order. There are
acpi_update_interfaces() (marked by <<<<) calls invoked before
acpi_ut_initialize_interfaces() (marked by ^^^^). This makes it impossible
to use acpi_osi=!* correctly from OSI DMI table or from the command line.
The use of acpi_osi=!* is meant to disable both ACPICA
(acpi_gbl_supported_interfaces) and Linux specific strings
(osi_setup_entries) while the ACPICA part should have stopped working
because of the order issue.

This patch fixes this issue by moving acpi_update_interfaces() to where
it is invoked for acpi_osi=! (marked by >>>>) as this is ensured to be
invoked after acpi_ut_initialize_interfaces() (marked by ^^^^). Linux
specific strings are still handled in the original place in order to make
the following command line working: acpi_osi=!* acpi_osi="Module Device".

Note that since acpi_osi=!* is meant to further disable linux specific
string comparing to the acpi_osi=!, there is no such use case in our bug
fixing work and hence there is no one using acpi_osi=!* either from the
command line or from the DMI quirks, this issue is just a theoretical
issue.

Cc: <[email protected]> # all applicable
Signed-off-by: Lv Zheng <[email protected]>
---
drivers/acpi/osl.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 00d2a22..d7d84a8 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -135,7 +135,7 @@ static struct osi_linux {
unsigned int enable:1;
unsigned int dmi:1;
unsigned int cmdline:1;
- unsigned int default_disabling:1;
+ u8 default_disabling;
} osi_linux = {0, 0, 0, 0};

static u32 acpi_osi_handler(acpi_string interface, u32 supported)
@@ -1477,10 +1477,13 @@ void __init acpi_osi_setup(char *str)
if (*str == '!') {
str++;
if (*str == '\0') {
- osi_linux.default_disabling = 1;
+ /* Do not override acpi_osi=!* */
+ if (!osi_linux.default_disabling)
+ osi_linux.default_disabling =
+ ACPI_DISABLE_ALL_VENDOR_STRINGS;
return;
} else if (*str == '*') {
- acpi_update_interfaces(ACPI_DISABLE_ALL_STRINGS);
+ osi_linux.default_disabling = ACPI_DISABLE_ALL_STRINGS;
for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
osi = &osi_setup_entries[i];
osi->enable = false;
@@ -1553,10 +1556,13 @@ static void __init acpi_osi_setup_late(void)
acpi_status status;

if (osi_linux.default_disabling) {
- status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
+ status = acpi_update_interfaces(osi_linux.default_disabling);

if (ACPI_SUCCESS(status))
- printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors\n");
+ printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n",
+ osi_linux.default_disabling ==
+ ACPI_DISABLE_ALL_STRINGS ?
+ " and feature groups" : "");
}

for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
--
1.7.10

2016-04-26 20:10:44

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH 2/4] ACPI / osi: Cleanup _OSI("Linux") related code before introducing new support

On Tue, Apr 26, 2016 at 9:40 AM, Lv Zheng <[email protected]> wrote:
> This patch cleans up OSI code in osl.c in order to make osi_linux not
> _OSI("Linux") specific to allow new features to reuse this structure.

I guess what you mean here is something like:

Clean up OSI code in osl.c to make osi_linux work for OSI strings
other than "Linux", so it can be re-used for other purposes.

Is that correct?

2016-04-26 20:13:31

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH 3/4] ACPI / osi: Change default _OSI(Darwin) support

On Tue, Apr 26, 2016 at 9:40 AM, Lv Zheng <[email protected]> wrote:
> From: Chen Yu <[email protected]>
>
> Commit 7bc5a2bad0b8 ("ACPI: Support _OSI("Darwin") correctly") always
> reports positive value when Apple hardware queries _OSI("Darwin"). However
> since this implementation places the judgement in runtime, it breaks
> acpi_osi=!Darwin and cannot return unsupported for _OSI("WinXXX") invoked
> before invoking _OSI("Darwin").
>
> This patch fixes the issues by reverting the wrong support and implementing
> the default behavior of _OSI("Darwin")/_OSI("WinXXX") on Apple hardware via
> DMI matching.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=92111
> Reported-by: Lukas Wunner <[email protected]>
> Signed-off-by: Chen Yu <[email protected]>
> Signed-off-by: Lv Zheng <[email protected]>

Why don't you add a Fixes tag pointing to the problematic commit?

2016-04-27 02:00:13

by Zheng, Lv

[permalink] [raw]
Subject: RE: [PATCH 2/4] ACPI / osi: Cleanup _OSI("Linux") related code before introducing new support

Hi, Rafael

> From: [email protected] [mailto:[email protected]] On Behalf Of
> Rafael J. Wysocki
> Sent: Wednesday, April 27, 2016 4:11 AM
> Subject: Re: [PATCH 2/4] ACPI / osi: Cleanup _OSI("Linux") related code before
> introducing new support
>
> On Tue, Apr 26, 2016 at 9:40 AM, Lv Zheng <[email protected]> wrote:
> > This patch cleans up OSI code in osl.c in order to make osi_linux not
> > _OSI("Linux") specific to allow new features to reuse this structure.
>
> I guess what you mean here is something like:
>
> Clean up OSI code in osl.c to make osi_linux work for OSI strings
> other than "Linux", so it can be re-used for other purposes.
>
> Is that correct?
[Lv Zheng]
Exactly!

Thanks
-Lv

2016-04-27 02:01:44

by Zheng, Lv

[permalink] [raw]
Subject: RE: [PATCH 3/4] ACPI / osi: Change default _OSI(Darwin) support

Hi,

> From: [email protected] [mailto:[email protected]] On Behalf Of
> Rafael J. Wysocki
> Sent: Wednesday, April 27, 2016 4:13 AM
> Subject: Re: [PATCH 3/4] ACPI / osi: Change default _OSI(Darwin) support
>
> On Tue, Apr 26, 2016 at 9:40 AM, Lv Zheng <[email protected]> wrote:
> > From: Chen Yu <[email protected]>
> >
> > Commit 7bc5a2bad0b8 ("ACPI: Support _OSI("Darwin") correctly") always
> > reports positive value when Apple hardware queries _OSI("Darwin"). However
> > since this implementation places the judgement in runtime, it breaks
> > acpi_osi=!Darwin and cannot return unsupported for _OSI("WinXXX") invoked
> > before invoking _OSI("Darwin").
> >
> > This patch fixes the issues by reverting the wrong support and implementing
> > the default behavior of _OSI("Darwin")/_OSI("WinXXX") on Apple hardware
> via
> > DMI matching.
> >
> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=92111
> > Reported-by: Lukas Wunner <[email protected]>
> > Signed-off-by: Chen Yu <[email protected]>
> > Signed-off-by: Lv Zheng <[email protected]>
>
> Why don't you add a Fixes tag pointing to the problematic commit?
[Lv Zheng]
OK, I'll help to add it and re-send an UPDATE for this patch.

Thanks
-Lv

2016-04-27 08:54:25

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH v2 0/6] ACPI / osi: Fix several issues in _OSI handling

This patchset cleans up _OSI handling code and fixes several issues in it.

In the v2 version, as one fix has been changed to be a stable material,
patches originally put before it need to be rebased. The necessary changes
that are required by this fix are still kept before the fix patch, and the
unnecessary changes that are not required by this fix are moved after the
fix patch. So that the back porting of the stable materials could be
easier. The coding style in the stable materials is kept wrong to be
consistent to the coding style used by the old code, so checkpatch.pl may
report warnings on the stable materials.

Chen Yu (1):
ACPI / osi: Fix default _OSI(Darwin) support

Lv Zheng (5):
ACPI / osi: Fix an issue that acpi_osi=!* cannot disable ACPICA
internal strings
ACPI / osi: Cleanup _OSI("Linux") related code before introducing new
support
ACPI / osi: Add acpi_osi=!! to allow reverting acpi_osi=!
ACPI / osi: Cleanup coding style issues before creating a separate
OSI source file
ACPI / osi: Collect _OSI handling into one single file

Documentation/kernel-parameters.txt | 2 +
drivers/acpi/Makefile | 2 +-
drivers/acpi/blacklist.c | 196 +------------
drivers/acpi/internal.h | 2 +
drivers/acpi/osi.c | 518 +++++++++++++++++++++++++++++++++++
drivers/acpi/osl.c | 228 +--------------
include/linux/acpi.h | 1 -
7 files changed, 530 insertions(+), 419 deletions(-)
create mode 100644 drivers/acpi/osi.c

--
1.7.10

2016-04-27 08:54:33

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH v2 1/6] ACPI / osi: Fix an issue that acpi_osi=!* cannot disable ACPICA internal strings

The order of the _OSI related functionalities is as follows:
acpi_blacklisted()
acpi_dmi_osi_linux()
acpi_osi_setup()
acpi_osi_setup()
acpi_update_interfaces() if "!*"
<<<<<<<<<<<<<<<<<<<<<<<<
parse_args()
__setup("acpi_osi=")
acpi_osi_setup_linux()
acpi_update_interfaces() if "!*"
<<<<<<<<<<<<<<<<<<<<<<<<
acpi_early_init()
acpi_initialize_subsystem()
acpi_ut_initialize_interfaces()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
acpi_bus_init()
acpi_os_initialize1()
acpi_install_interface_handler(acpi_osi_handler)
acpi_osi_setup_late()
acpi_update_interfaces() for "!"
>>>>>>>>>>>>>>>>>>>>>>>>
acpi_osi_handler()
Since acpi_osi_setup_linux() can override acpi_dmi_osi_linux(), the command
line setting can override the DMI detection. That's why acpi_blacklisted()
is put before __setup("acpi_osi=").

Then we can notice the following wrong invocation order. There are
acpi_update_interfaces() (marked by <<<<) calls invoked before
acpi_ut_initialize_interfaces() (marked by ^^^^). This makes it impossible
to use acpi_osi=!* correctly from OSI DMI table or from the command line.
The use of acpi_osi=!* is meant to disable both ACPICA
(acpi_gbl_supported_interfaces) and Linux specific strings
(osi_setup_entries) while the ACPICA part should have stopped working
because of the order issue.

This patch fixes this issue by moving acpi_update_interfaces() to where
it is invoked for acpi_osi=! (marked by >>>>) as this is ensured to be
invoked after acpi_ut_initialize_interfaces() (marked by ^^^^). Linux
specific strings are still handled in the original place in order to make
the following command line working: acpi_osi=!* acpi_osi="Module Device".

Note that since acpi_osi=!* is meant to further disable linux specific
string comparing to the acpi_osi=!, there is no such use case in our bug
fixing work and hence there is no one using acpi_osi=!* either from the
command line or from the DMI quirks, this issue is just a theoretical
issue.

Fixes: 741d81280ad2 ("ACPI: Add facility to remove all _OSI strings")
Cc: <[email protected]> # 3.12+
Signed-off-by: Lv Zheng <[email protected]>
---
drivers/acpi/osl.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 00d2a22..d7d84a8 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -135,7 +135,7 @@ static struct osi_linux {
unsigned int enable:1;
unsigned int dmi:1;
unsigned int cmdline:1;
- unsigned int default_disabling:1;
+ u8 default_disabling;
} osi_linux = {0, 0, 0, 0};

static u32 acpi_osi_handler(acpi_string interface, u32 supported)
@@ -1477,10 +1477,13 @@ void __init acpi_osi_setup(char *str)
if (*str == '!') {
str++;
if (*str == '\0') {
- osi_linux.default_disabling = 1;
+ /* Do not override acpi_osi=!* */
+ if (!osi_linux.default_disabling)
+ osi_linux.default_disabling =
+ ACPI_DISABLE_ALL_VENDOR_STRINGS;
return;
} else if (*str == '*') {
- acpi_update_interfaces(ACPI_DISABLE_ALL_STRINGS);
+ osi_linux.default_disabling = ACPI_DISABLE_ALL_STRINGS;
for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
osi = &osi_setup_entries[i];
osi->enable = false;
@@ -1553,10 +1556,13 @@ static void __init acpi_osi_setup_late(void)
acpi_status status;

if (osi_linux.default_disabling) {
- status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
+ status = acpi_update_interfaces(osi_linux.default_disabling);

if (ACPI_SUCCESS(status))
- printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors\n");
+ printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n",
+ osi_linux.default_disabling ==
+ ACPI_DISABLE_ALL_STRINGS ?
+ " and feature groups" : "");
}

for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
--
1.7.10

2016-04-27 08:54:40

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH v2 2/6] ACPI / osi: Cleanup _OSI("Linux") related code before introducing new support

This patch cleans up OSI code in osl.c to make osi_linux work for OSI
strings other than "Linux", so it can be re-used for other purposes.

Signed-off-by: Lv Zheng <[email protected]>
---
drivers/acpi/osl.c | 42 ++++++++++++++++++++++--------------------
1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index d7d84a8..cd9667f 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -131,12 +131,12 @@ static void __init acpi_osi_setup_late(void);
* or boot with "acpi_osi=Linux"
*/

-static struct osi_linux {
- unsigned int enable:1;
- unsigned int dmi:1;
- unsigned int cmdline:1;
+static struct acpi_osi_config {
+ unsigned int linux_enable:1;
+ unsigned int linux_dmi:1;
+ unsigned int linux_cmdline:1;
u8 default_disabling;
-} osi_linux = {0, 0, 0, 0};
+} osi_config = {0, 0, 0, 0};

static u32 acpi_osi_handler(acpi_string interface, u32 supported)
{
@@ -144,9 +144,9 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported)

printk_once(KERN_NOTICE FW_BUG PREFIX
"BIOS _OSI(Linux) query %s%s\n",
- osi_linux.enable ? "honored" : "ignored",
- osi_linux.cmdline ? " via cmdline" :
- osi_linux.dmi ? " via DMI" : "");
+ osi_config.linux_enable ? "honored" : "ignored",
+ osi_config.linux_cmdline ? " via cmdline" :
+ osi_config.linux_dmi ? " via DMI" : "");
}

if (!strcmp("Darwin", interface)) {
@@ -1478,12 +1478,12 @@ void __init acpi_osi_setup(char *str)
str++;
if (*str == '\0') {
/* Do not override acpi_osi=!* */
- if (!osi_linux.default_disabling)
- osi_linux.default_disabling =
+ if (!osi_config.default_disabling)
+ osi_config.default_disabling =
ACPI_DISABLE_ALL_VENDOR_STRINGS;
return;
} else if (*str == '*') {
- osi_linux.default_disabling = ACPI_DISABLE_ALL_STRINGS;
+ osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS;
for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
osi = &osi_setup_entries[i];
osi->enable = false;
@@ -1508,10 +1508,10 @@ void __init acpi_osi_setup(char *str)

static void __init set_osi_linux(unsigned int enable)
{
- if (osi_linux.enable != enable)
- osi_linux.enable = enable;
+ if (osi_config.linux_enable != enable)
+ osi_config.linux_enable = enable;

- if (osi_linux.enable)
+ if (osi_config.linux_enable)
acpi_osi_setup("Linux");
else
acpi_osi_setup("!Linux");
@@ -1521,8 +1521,9 @@ static void __init set_osi_linux(unsigned int enable)

static void __init acpi_cmdline_osi_linux(unsigned int enable)
{
- osi_linux.cmdline = 1; /* cmdline set the default and override DMI */
- osi_linux.dmi = 0;
+ /* cmdline set the default and override DMI */
+ osi_config.linux_cmdline = 1;
+ osi_config.linux_dmi = 0;
set_osi_linux(enable);

return;
@@ -1535,7 +1536,8 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
if (enable == -1)
return;

- osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
+ /* DMI knows that this box asks OSI(Linux) */
+ osi_config.linux_dmi = 1;
set_osi_linux(enable);

return;
@@ -1555,12 +1557,12 @@ static void __init acpi_osi_setup_late(void)
int i;
acpi_status status;

- if (osi_linux.default_disabling) {
- status = acpi_update_interfaces(osi_linux.default_disabling);
+ if (osi_config.default_disabling) {
+ status = acpi_update_interfaces(osi_config.default_disabling);

if (ACPI_SUCCESS(status))
printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n",
- osi_linux.default_disabling ==
+ osi_config.default_disabling ==
ACPI_DISABLE_ALL_STRINGS ?
" and feature groups" : "");
}
--
1.7.10

2016-04-27 08:54:59

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support

From: Chen Yu <[email protected]>

The following commit always reports positive value when Apple hardware
queries _OSI("Darwin"):
Commit: 7bc5a2bad0b8d9d1ac9f7b8b33150e4ddf197334
Subject: ACPI: Support _OSI("Darwin") correctly
However since this implementation places the judgement in runtime, it
breaks acpi_osi=!Darwin and cannot return unsupported for _OSI("WinXXX")
invoked before invoking _OSI("Darwin").

This patch fixes the issues by reverting the wrong support and implementing
the default behavior of _OSI("Darwin")/_OSI("WinXXX") on Apple hardware via
DMI matching.

Fixes: 7bc5a2bad0b8 ("ACPI: Support _OSI("Darwin") correctly")
Cc: <[email protected]> # 3.18+
Link: https://bugzilla.kernel.org/show_bug.cgi?id=92111
Reported-by: Lukas Wunner <[email protected]>
Signed-off-by: Chen Yu <[email protected]>
Signed-off-by: Lv Zheng <[email protected]>
---
drivers/acpi/blacklist.c | 23 ++++++++++++++++++
drivers/acpi/osl.c | 58 ++++++++++++++++++++++++++++++++++++++++------
include/linux/acpi.h | 1 +
3 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index 96809cd..e947d3e 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -133,6 +133,11 @@ int __init acpi_blacklisted(void)
return blacklisted;
}
#ifdef CONFIG_DMI
+static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d)
+{
+ acpi_dmi_osi_darwin(1, d); /* enable */
+ return 0;
+}
static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
{
acpi_dmi_osi_linux(1, d); /* enable */
@@ -331,6 +336,24 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
},
},

+ /*
+ * Enable _OSI("Darwin") for all apple platforms.
+ */
+ {
+ .callback = dmi_enable_osi_darwin,
+ .ident = "Apple hardware",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple INC."),
+ },
+ },
+ {
+ .callback = dmi_enable_osi_darwin,
+ .ident = "Apple hardware",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, INC."),
+ },
+ },
+
#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
/*
* DELL XPS 13 (2015) switches sound between HDA and I2S
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index fbedea7..5dd2a79 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -135,6 +135,9 @@ static struct acpi_osi_config {
unsigned int linux_enable:1;
unsigned int linux_dmi:1;
unsigned int linux_cmdline:1;
+ unsigned int darwin_enable:1;
+ unsigned int darwin_dmi:1;
+ unsigned int darwin_cmdline:1;
u8 default_disabling;
} osi_config = {0, 0, 0, 0};

@@ -150,13 +153,12 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported)
}

if (!strcmp("Darwin", interface)) {
- /*
- * Apple firmware will behave poorly if it receives positive
- * answers to "Darwin" and any other OS. Respond positively
- * to Darwin and then disable all other vendor strings.
- */
- acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
- supported = ACPI_UINT32_MAX;
+
+ printk_once(KERN_NOTICE PREFIX
+ "BIOS _OSI(Darwin) query %s%s\n",
+ osi_config.darwin_enable ? "honored" : "ignored",
+ osi_config.darwin_cmdline ? " via cmdline" :
+ osi_config.darwin_dmi ? " via DMI" : "");
}

return supported;
@@ -1509,6 +1511,44 @@ void __init acpi_osi_setup(char *str)
}
}

+static void __init set_osi_darwin(unsigned int enable)
+{
+ if (osi_config.darwin_enable != enable)
+ osi_config.darwin_enable = enable;
+
+ if (enable) {
+ acpi_osi_setup("!");
+ acpi_osi_setup("Darwin");
+ } else {
+ acpi_osi_setup("!!");
+ acpi_osi_setup("!Darwin");
+ }
+}
+
+static void __init acpi_cmdline_osi_darwin(unsigned int enable)
+{
+ /* cmdline set the default and override DMI */
+ osi_config.darwin_cmdline = 1;
+ osi_config.darwin_dmi = 0;
+ set_osi_darwin(enable);
+
+ return;
+}
+
+void __init acpi_dmi_osi_darwin(int enable, const struct dmi_system_id *d)
+{
+ printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
+
+ if (enable == -1)
+ return;
+
+ /* DMI knows that this box asks OSI(Darwin) */
+ osi_config.darwin_dmi = 1;
+ set_osi_darwin(enable);
+
+ return;
+}
+
static void __init set_osi_linux(unsigned int enable)
{
if (osi_config.linux_enable != enable)
@@ -1596,6 +1636,10 @@ static int __init osi_setup(char *str)
acpi_cmdline_osi_linux(1);
else if (str && !strcmp("!Linux", str))
acpi_cmdline_osi_linux(0);
+ else if (str && !strcmp("Darwin", str))
+ acpi_cmdline_osi_darwin(1);
+ else if (str && !strcmp("!Darwin", str))
+ acpi_cmdline_osi_darwin(0);
else
acpi_osi_setup(str);

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index be5d206..8fd3a82 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -354,6 +354,7 @@ extern char acpi_video_backlight_string[];
extern long acpi_is_video_device(acpi_handle handle);
extern int acpi_blacklisted(void);
extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
+extern void acpi_dmi_osi_darwin(int enable, const struct dmi_system_id *d);
extern void acpi_osi_setup(char *str);
extern bool acpi_osi_is_win8(void);

--
1.7.10

2016-04-27 08:55:08

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH v2 6/6] ACPI / osi: Collect _OSI handling into one single file

_OSI handling code grows giant and it's time to move them into one file.

This patch collects all _OSI handling code into one single file.
So that we only have the following functions to be used externally:
early_acpi_osi_init(): Used by DMI detections;
acpi_osi_init(): Used to initialize OSI command line settings and install
Linux specific _OSI handler;
acpi_osi_setup(): The API that should be used by the external quirks.
acpi_osi_is_win8(): The API is used by the external drivers to determine
if BIOS supports Win8.

CONFIG_DMI is not useful as stub dmi_check_system() can make everything
stub because of strip.

No functional changes.

Signed-off-by: Lv Zheng <[email protected]>
---
drivers/acpi/Makefile | 2 +-
drivers/acpi/blacklist.c | 219 +-------------------
drivers/acpi/internal.h | 2 +
drivers/acpi/osi.c | 518 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/acpi/osl.c | 254 +----------------------
include/linux/acpi.h | 2 -
6 files changed, 527 insertions(+), 470 deletions(-)
create mode 100644 drivers/acpi/osi.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 5a65f85..251ce85 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -18,7 +18,7 @@ obj-$(CONFIG_ACPI) += acpi.o \
acpica/

# All the builtin files are in the "acpi." module_param namespace.
-acpi-y += osl.o utils.o reboot.o
+acpi-y += osi.o osl.o utils.o reboot.o
acpi-y += nvs.o

# Power management related files
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index 45199dc..bdc67ba 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -3,7 +3,7 @@
*
* Check to see if the given machine has a known bad ACPI BIOS
* or if the BIOS is too old.
- * Check given machine against acpi_osi_dmi_table[].
+ * Check given machine against acpi_rev_dmi_table[].
*
* Copyright (C) 2004 Len Brown <[email protected]>
* Copyright (C) 2002 Andy Grover <[email protected]>
@@ -47,7 +47,7 @@ struct acpi_blacklist_item {
u32 is_critical_error;
};

-static struct dmi_system_id acpi_osi_dmi_table[] __initdata;
+static struct dmi_system_id acpi_rev_dmi_table[] __initdata;

/*
* POLICY: If *anything* doesn't work, put it on the blacklist.
@@ -128,41 +128,12 @@ int __init acpi_blacklisted(void)
}
}

- dmi_check_system(acpi_osi_dmi_table);
+ (void)early_acpi_osi_init();
+ dmi_check_system(acpi_rev_dmi_table);

return blacklisted;
}
#ifdef CONFIG_DMI
-static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d)
-{
- acpi_osi_dmi_darwin(true, d);
- return 0;
-}
-static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
-{
- acpi_osi_dmi_linux(true, d);
- return 0;
-}
-static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
-{
- pr_notice("DMI detected: %s\n", d->ident);
- acpi_osi_setup("!Windows 2006");
- acpi_osi_setup("!Windows 2006 SP1");
- acpi_osi_setup("!Windows 2006 SP2");
- return 0;
-}
-static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
-{
- pr_notice("DMI detected: %s\n", d->ident);
- acpi_osi_setup("!Windows 2009");
- return 0;
-}
-static int __init dmi_disable_osi_win8(const struct dmi_system_id *d)
-{
- pr_notice("DMI detected: %s\n", d->ident);
- acpi_osi_setup("!Windows 2012");
- return 0;
-}
#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
static int __init dmi_enable_rev_override(const struct dmi_system_id *d)
{
@@ -173,187 +144,7 @@ static int __init dmi_enable_rev_override(const struct dmi_system_id *d)
}
#endif

-static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Fujitsu Siemens",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
- DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
- },
- },
- {
- /*
- * There have a NVIF method in MSI GX723 DSDT need call by Nvidia
- * driver (e.g. nouveau) when user press brightness hotkey.
- * Currently, nouveau driver didn't do the job and it causes there
- * have a infinite while loop in DSDT when user press hotkey.
- * We add MSI GX723's dmi information to this table for workaround
- * this issue.
- * Will remove MSI GX723 from the table after nouveau grows support.
- */
- .callback = dmi_disable_osi_vista,
- .ident = "MSI GX723",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
- DMI_MATCH(DMI_PRODUCT_NAME, "GX723"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Sony VGN-NS10J_S",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Sony VGN-SR290J",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "VGN-NS50B_L",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "VGN-SR19XN",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Toshiba Satellite L355",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"),
- },
- },
- {
- .callback = dmi_disable_osi_win7,
- .ident = "ASUS K50IJ",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Toshiba P305D",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"),
- },
- },
- {
- .callback = dmi_disable_osi_vista,
- .ident = "Toshiba NB100",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
- DMI_MATCH(DMI_PRODUCT_NAME, "NB100"),
- },
- },
-
- /*
- * The wireless hotkey does not work on those machines when
- * returning true for _OSI("Windows 2012")
- */
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Inspiron 7737",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Inspiron 7537",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Inspiron 5437",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Inspiron 3437",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Vostro 3446",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Dell Vostro 3546",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"),
- },
- },
-
- /*
- * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
- * Linux ignores it, except for the machines enumerated below.
- */
-
- /*
- * Without this this EEEpc exports a non working WMI interface, with
- * this it exports a working "good old" eeepc_laptop interface, fixing
- * both brightness control, and rfkill not working.
- */
- {
- .callback = dmi_enable_osi_linux,
- .ident = "Asus EEE PC 1015PX",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
- DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"),
- },
- },
-
- /*
- * Enable _OSI("Darwin") for all apple platforms.
- */
- {
- .callback = dmi_enable_osi_darwin,
- .ident = "Apple hardware",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Apple INC."),
- },
- },
- {
- .callback = dmi_enable_osi_darwin,
- .ident = "Apple hardware",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, INC."),
- },
- },
-
+static struct dmi_system_id acpi_rev_dmi_table[] __initdata = {
#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
/*
* DELL XPS 13 (2015) switches sound between HDA and I2S
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 1b0e6fd..9bb0773 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -20,6 +20,8 @@

#define PREFIX "ACPI: "

+int early_acpi_osi_init(void);
+int acpi_osi_init(void);
acpi_status acpi_os_initialize1(void);
void init_acpi_device_notify(void);
int acpi_scan_init(void);
diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c
new file mode 100644
index 0000000..b147907
--- /dev/null
+++ b/drivers/acpi/osi.c
@@ -0,0 +1,518 @@
+/*
+ * osi.c - _OSI implementation
+ *
+ * Copyright (C) 2016 Intel Corporation
+ * Author: Lv Zheng <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+
+#include "internal.h"
+
+
+#define OSI_STRING_LENGTH_MAX 64
+#define OSI_STRING_ENTRIES_MAX 16
+
+struct acpi_osi_entry {
+ char string[OSI_STRING_LENGTH_MAX];
+ bool enable;
+};
+
+static struct acpi_osi_config {
+ u8 default_disabling;
+ unsigned int linux_enable:1;
+ unsigned int linux_dmi:1;
+ unsigned int linux_cmdline:1;
+ unsigned int darwin_enable:1;
+ unsigned int darwin_dmi:1;
+ unsigned int darwin_cmdline:1;
+} osi_config;
+
+static struct acpi_osi_config osi_config;
+static struct acpi_osi_entry
+osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {
+ {"Module Device", true},
+ {"Processor Device", true},
+ {"3.0 _SCP Extensions", true},
+ {"Processor Aggregator Device", true},
+};
+
+static u32 acpi_osi_handler(acpi_string interface, u32 supported)
+{
+ if (!strcmp("Linux", interface)) {
+ pr_notice_once(FW_BUG
+ "BIOS _OSI(Linux) query %s%s\n",
+ osi_config.linux_enable ? "honored" : "ignored",
+ osi_config.linux_cmdline ? " via cmdline" :
+ osi_config.linux_dmi ? " via DMI" : "");
+ }
+ if (!strcmp("Darwin", interface)) {
+ pr_notice_once(
+ "BIOS _OSI(Darwin) query %s%s\n",
+ osi_config.darwin_enable ? "honored" : "ignored",
+ osi_config.darwin_cmdline ? " via cmdline" :
+ osi_config.darwin_dmi ? " via DMI" : "");
+ }
+
+ return supported;
+}
+
+void __init acpi_osi_setup(char *str)
+{
+ struct acpi_osi_entry *osi;
+ bool enable = true;
+ int i;
+
+ if (!acpi_gbl_create_osi_method)
+ return;
+
+ if (str == NULL || *str == '\0') {
+ pr_info("_OSI method disabled\n");
+ acpi_gbl_create_osi_method = FALSE;
+ return;
+ }
+
+ if (*str == '!') {
+ str++;
+ if (*str == '\0') {
+ /* Do not override acpi_osi=!* */
+ if (!osi_config.default_disabling)
+ osi_config.default_disabling =
+ ACPI_DISABLE_ALL_VENDOR_STRINGS;
+ return;
+ } else if (*str == '*') {
+ osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS;
+ for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+ osi = &osi_setup_entries[i];
+ osi->enable = false;
+ }
+ return;
+ } else if (*str == '!') {
+ osi_config.default_disabling = 0;
+ return;
+ }
+ enable = false;
+ }
+
+ 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;
+ }
+ }
+}
+
+static void __init __acpi_osi_setup_darwin(bool enable)
+{
+ osi_config.darwin_enable = !!enable;
+ if (enable) {
+ acpi_osi_setup("!");
+ acpi_osi_setup("Darwin");
+ } else {
+ acpi_osi_setup("!!");
+ acpi_osi_setup("!Darwin");
+ }
+}
+
+static void __init acpi_osi_setup_darwin(bool enable)
+{
+ /* Override acpi_osi_dmi_blacklisted() */
+ osi_config.darwin_dmi = 0;
+ osi_config.darwin_cmdline = 1;
+ __acpi_osi_setup_darwin(enable);
+}
+
+/*
+ * The story of _OSI(Linux)
+ *
+ * From pre-history through Linux-2.6.22, Linux responded TRUE upon a BIOS
+ * OSI(Linux) query.
+ *
+ * Unfortunately, reference BIOS writers got wind of this and put
+ * OSI(Linux) in their example code, quickly exposing this string as
+ * ill-conceived and opening the door to an un-bounded number of BIOS
+ * incompatibilities.
+ *
+ * For example, OSI(Linux) was used on resume to re-POST a video card on
+ * one system, because Linux at that time could not do a speedy restore in
+ * its native driver. But then upon gaining quick native restore
+ * capability, Linux has no way to tell the BIOS to skip the time-consuming
+ * POST -- putting Linux at a permanent performance disadvantage. On
+ * another system, the BIOS writer used OSI(Linux) to infer native OS
+ * support for IPMI! On other systems, OSI(Linux) simply got in the way of
+ * Linux claiming to be compatible with other operating systems, exposing
+ * BIOS issues such as skipped device initialization.
+ *
+ * So "Linux" turned out to be a really poor chose of OSI string, and from
+ * Linux-2.6.23 onward we respond FALSE.
+ *
+ * BIOS writers should NOT query _OSI(Linux) on future systems. Linux will
+ * complain on the console when it sees it, and return FALSE. To get Linux
+ * to return TRUE for your system will require a kernel source update to
+ * add a DMI entry, or boot with "acpi_osi=Linux"
+ */
+static void __init __acpi_osi_setup_linux(bool enable)
+{
+ osi_config.linux_enable = !!enable;
+ if (enable)
+ acpi_osi_setup("Linux");
+ else
+ acpi_osi_setup("!Linux");
+}
+
+static void __init acpi_osi_setup_linux(bool enable)
+{
+ /* Override acpi_osi_dmi_blacklisted() */
+ osi_config.linux_dmi = 0;
+ osi_config.linux_cmdline = 1;
+ __acpi_osi_setup_linux(enable);
+}
+
+/*
+ * Modify the list of "OS Interfaces" reported to BIOS via _OSI
+ *
+ * empty string disables _OSI
+ * string starting with '!' disables that string
+ * otherwise string is added to list, augmenting built-in strings
+ */
+static void __init acpi_osi_setup_late(void)
+{
+ struct acpi_osi_entry *osi;
+ char *str;
+ int i;
+ acpi_status status;
+
+ if (osi_config.default_disabling) {
+ status = acpi_update_interfaces(osi_config.default_disabling);
+ if (ACPI_SUCCESS(status))
+ pr_info("Disabled all _OSI OS vendors%s\n",
+ osi_config.default_disabling ==
+ ACPI_DISABLE_ALL_STRINGS ?
+ " and feature groups" : "");
+ }
+
+ 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))
+ pr_info("Added _OSI(%s)\n", str);
+ } else {
+ status = acpi_remove_interface(str);
+ if (ACPI_SUCCESS(status))
+ pr_info("Deleted _OSI(%s)\n", str);
+ }
+ }
+}
+
+static int __init osi_setup(char *str)
+{
+ if (str && !strcmp("Linux", str))
+ acpi_osi_setup_linux(true);
+ else if (str && !strcmp("!Linux", str))
+ acpi_osi_setup_linux(false);
+ else if (str && !strcmp("Darwin", str))
+ acpi_osi_setup_darwin(true);
+ else if (str && !strcmp("!Darwin", str))
+ acpi_osi_setup_darwin(false);
+ else
+ acpi_osi_setup(str);
+
+ return 1;
+}
+__setup("acpi_osi=", osi_setup);
+
+bool acpi_osi_is_win8(void)
+{
+ return acpi_gbl_osi_data >= ACPI_OSI_WIN_8;
+}
+EXPORT_SYMBOL(acpi_osi_is_win8);
+
+static void __init acpi_osi_dmi_darwin(bool enable,
+ const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected to setup _OSI(\"Darwin\"): %s\n", d->ident);
+ osi_config.darwin_dmi = 1;
+ __acpi_osi_setup_darwin(enable);
+}
+
+void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected to setup _OSI(\"Linux\"): %s\n", d->ident);
+ osi_config.linux_dmi = 1;
+ __acpi_osi_setup_linux(enable);
+}
+
+static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d)
+{
+ acpi_osi_dmi_darwin(true, d);
+
+ return 0;
+}
+
+static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
+{
+ acpi_osi_dmi_linux(true, d);
+
+ return 0;
+}
+
+static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected: %s\n", d->ident);
+ acpi_osi_setup("!Windows 2006");
+ acpi_osi_setup("!Windows 2006 SP1");
+ acpi_osi_setup("!Windows 2006 SP2");
+
+ return 0;
+}
+
+static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected: %s\n", d->ident);
+ acpi_osi_setup("!Windows 2009");
+
+ return 0;
+}
+
+static int __init dmi_disable_osi_win8(const struct dmi_system_id *d)
+{
+ pr_notice("DMI detected: %s\n", d->ident);
+ acpi_osi_setup("!Windows 2012");
+
+ return 0;
+}
+
+/*
+ * Linux default _OSI response behavior is determined by this DMI table.
+ *
+ * Note that _OSI("Linux")/_OSI("Darwin") determined here can be overridden
+ * by acpi_osi=!Linux/acpi_osi=!Darwin command line options.
+ */
+static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Fujitsu Siemens",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
+ },
+ },
+ {
+ /*
+ * There have a NVIF method in MSI GX723 DSDT need call by Nvidia
+ * driver (e.g. nouveau) when user press brightness hotkey.
+ * Currently, nouveau driver didn't do the job and it causes there
+ * have a infinite while loop in DSDT when user press hotkey.
+ * We add MSI GX723's dmi information to this table for workaround
+ * this issue.
+ * Will remove MSI GX723 from the table after nouveau grows support.
+ */
+ .callback = dmi_disable_osi_vista,
+ .ident = "MSI GX723",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GX723"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Sony VGN-NS10J_S",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Sony VGN-SR290J",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "VGN-NS50B_L",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "VGN-SR19XN",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Toshiba Satellite L355",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win7,
+ .ident = "ASUS K50IJ",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Toshiba P305D",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_vista,
+ .ident = "Toshiba NB100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "NB100"),
+ },
+ },
+
+ /*
+ * The wireless hotkey does not work on those machines when
+ * returning true for _OSI("Windows 2012")
+ */
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Inspiron 7737",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Inspiron 7537",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Inspiron 5437",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Inspiron 3437",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Vostro 3446",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"),
+ },
+ },
+ {
+ .callback = dmi_disable_osi_win8,
+ .ident = "Dell Vostro 3546",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"),
+ },
+ },
+
+ /*
+ * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
+ * Linux ignores it, except for the machines enumerated below.
+ */
+
+ /*
+ * Without this this EEEpc exports a non working WMI interface, with
+ * this it exports a working "good old" eeepc_laptop interface, fixing
+ * both brightness control, and rfkill not working.
+ */
+ {
+ .callback = dmi_enable_osi_linux,
+ .ident = "Asus EEE PC 1015PX",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"),
+ },
+ },
+
+ /*
+ * Enable _OSI("Darwin") for all apple platforms.
+ */
+ {
+ .callback = dmi_enable_osi_darwin,
+ .ident = "Apple hardware",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple INC."),
+ },
+ },
+ {
+ .callback = dmi_enable_osi_darwin,
+ .ident = "Apple hardware",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, INC."),
+ },
+ },
+ {}
+};
+
+static __init void acpi_osi_dmi_blacklisted(void)
+{
+ dmi_check_system(acpi_osi_dmi_table);
+}
+
+int __init early_acpi_osi_init(void)
+{
+ acpi_osi_dmi_blacklisted();
+
+ return 0;
+}
+
+int __init acpi_osi_init(void)
+{
+ acpi_install_interface_handler(acpi_osi_handler);
+ acpi_osi_setup_late();
+
+ return 0;
+}
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index d9eef7e..45cab33 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -96,74 +96,6 @@ struct acpi_ioremap {
static LIST_HEAD(acpi_ioremaps);
static DEFINE_MUTEX(acpi_ioremap_lock);

-static void __init acpi_osi_setup_late(void);
-
-/*
- * The story of _OSI(Linux)
- *
- * From pre-history through Linux-2.6.22,
- * Linux responded TRUE upon a BIOS OSI(Linux) query.
- *
- * Unfortunately, reference BIOS writers got wind of this
- * and put OSI(Linux) in their example code, quickly exposing
- * this string as ill-conceived and opening the door to
- * an un-bounded number of BIOS incompatibilities.
- *
- * For example, OSI(Linux) was used on resume to re-POST a
- * video card on one system, because Linux at that time
- * could not do a speedy restore in its native driver.
- * But then upon gaining quick native restore capability,
- * Linux has no way to tell the BIOS to skip the time-consuming
- * POST -- putting Linux at a permanent performance disadvantage.
- * On another system, the BIOS writer used OSI(Linux)
- * to infer native OS support for IPMI! On other systems,
- * OSI(Linux) simply got in the way of Linux claiming to
- * be compatible with other operating systems, exposing
- * BIOS issues such as skipped device initialization.
- *
- * So "Linux" turned out to be a really poor chose of
- * OSI string, and from Linux-2.6.23 onward we respond FALSE.
- *
- * BIOS writers should NOT query _OSI(Linux) on future systems.
- * Linux will complain on the console when it sees it, and return FALSE.
- * To get Linux to return TRUE for your system will require
- * a kernel source update to add a DMI entry,
- * or boot with "acpi_osi=Linux"
- */
-
-static struct acpi_osi_config {
- unsigned int linux_enable:1;
- unsigned int linux_dmi:1;
- unsigned int linux_cmdline:1;
- unsigned int darwin_enable:1;
- unsigned int darwin_dmi:1;
- unsigned int darwin_cmdline:1;
- u8 default_disabling;
-} osi_config;
-
-static u32 acpi_osi_handler(acpi_string interface, u32 supported)
-{
- if (!strcmp("Linux", interface)) {
-
- pr_notice_once(FW_BUG
- "BIOS _OSI(Linux) query %s%s\n",
- osi_config.linux_enable ? "honored" : "ignored",
- osi_config.linux_cmdline ? " via cmdline" :
- osi_config.linux_dmi ? " via DMI" : "");
- }
-
- if (!strcmp("Darwin", interface)) {
-
- pr_notice_once(
- "BIOS _OSI(Darwin) query %s%s\n",
- osi_config.darwin_enable ? "honored" : "ignored",
- osi_config.darwin_cmdline ? " via cmdline" :
- osi_config.darwin_dmi ? " via DMI" : "");
- }
-
- return supported;
-}
-
static void __init acpi_request_region (struct acpi_generic_address *gas,
unsigned int length, char *desc)
{
@@ -1444,183 +1376,6 @@ static int __init acpi_os_name_setup(char *str)

__setup("acpi_os_name=", acpi_os_name_setup);

-#define OSI_STRING_LENGTH_MAX 64
-#define OSI_STRING_ENTRIES_MAX 16
-
-struct acpi_osi_entry {
- char string[OSI_STRING_LENGTH_MAX];
- bool enable;
-};
-
-static struct acpi_osi_entry
- osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {
- {"Module Device", true},
- {"Processor Device", true},
- {"3.0 _SCP Extensions", true},
- {"Processor Aggregator Device", true},
-};
-
-void __init acpi_osi_setup(char *str)
-{
- struct acpi_osi_entry *osi;
- bool enable = true;
- int i;
-
- if (!acpi_gbl_create_osi_method)
- return;
-
- if (str == NULL || *str == '\0') {
- pr_info("_OSI method disabled\n");
- acpi_gbl_create_osi_method = FALSE;
- return;
- }
-
- if (*str == '!') {
- str++;
- if (*str == '\0') {
- /* Do not override acpi_osi=!* */
- if (!osi_config.default_disabling)
- osi_config.default_disabling =
- ACPI_DISABLE_ALL_VENDOR_STRINGS;
- return;
- } else if (*str == '*') {
- osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS;
- for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
- osi = &osi_setup_entries[i];
- osi->enable = false;
- }
- return;
- } else if (*str == '!') {
- osi_config.default_disabling = 0;
- return;
- }
- enable = false;
- }
-
- 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;
- }
- }
-}
-
-static void __init __acpi_osi_setup_darwin(bool enable)
-{
- osi_config.darwin_enable = !!enable;
- if (enable) {
- acpi_osi_setup("!");
- acpi_osi_setup("Darwin");
- } else {
- acpi_osi_setup("!!");
- acpi_osi_setup("!Darwin");
- }
-}
-
-static void __init acpi_osi_setup_darwin(bool enable)
-{
- osi_config.darwin_cmdline = 1;
- osi_config.darwin_dmi = 0;
- __acpi_osi_setup_darwin(enable);
-}
-
-void __init acpi_osi_dmi_darwin(bool enable, const struct dmi_system_id *d)
-{
- pr_notice("DMI detected to setup _OSI(\"Darwin\"): %s\n", d->ident);
- osi_config.darwin_dmi = 1;
- __acpi_osi_setup_darwin(enable);
-}
-
-static void __init __acpi_osi_setup_linux(bool enable)
-{
- osi_config.linux_enable = !!enable;
- if (enable)
- acpi_osi_setup("Linux");
- else
- acpi_osi_setup("!Linux");
-}
-
-static void __init acpi_osi_setup_linux(bool enable)
-{
- osi_config.linux_cmdline = 1;
- osi_config.linux_dmi = 0;
- __acpi_osi_setup_linux(enable);
-}
-
-void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d)
-{
- pr_notice("DMI detected to setup _OSI(\"Linux\"): %s\n", d->ident);
- osi_config.linux_dmi = 1;
- __acpi_osi_setup_linux(enable);
-}
-
-/*
- * Modify the list of "OS Interfaces" reported to BIOS via _OSI
- *
- * empty string disables _OSI
- * string starting with '!' disables that string
- * otherwise string is added to list, augmenting built-in strings
- */
-static void __init acpi_osi_setup_late(void)
-{
- struct acpi_osi_entry *osi;
- char *str;
- int i;
- acpi_status status;
-
- if (osi_config.default_disabling) {
- status = acpi_update_interfaces(osi_config.default_disabling);
-
- if (ACPI_SUCCESS(status))
- pr_info("Disabled all _OSI OS vendors%s\n",
- osi_config.default_disabling ==
- ACPI_DISABLE_ALL_STRINGS ?
- " and feature groups" : "");
- }
-
- 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))
- pr_info("Added _OSI(%s)\n", str);
- } else {
- status = acpi_remove_interface(str);
-
- if (ACPI_SUCCESS(status))
- pr_info("Deleted _OSI(%s)\n", str);
- }
- }
-}
-
-static int __init osi_setup(char *str)
-{
- if (str && !strcmp("Linux", str))
- acpi_osi_setup_linux(true);
- else if (str && !strcmp("!Linux", str))
- acpi_osi_setup_linux(false);
- else if (str && !strcmp("Darwin", str))
- acpi_osi_setup_darwin(true);
- else if (str && !strcmp("!Darwin", str))
- acpi_osi_setup_darwin(false);
- else
- acpi_osi_setup(str);
-
- return 1;
-}
-
-__setup("acpi_osi=", osi_setup);
-
/*
* Disable the auto-serialization of named objects creation methods.
*
@@ -1740,12 +1495,6 @@ int acpi_resources_are_enforced(void)
}
EXPORT_SYMBOL(acpi_resources_are_enforced);

-bool acpi_osi_is_win8(void)
-{
- return acpi_gbl_osi_data >= ACPI_OSI_WIN_8;
-}
-EXPORT_SYMBOL(acpi_osi_is_win8);
-
/*
* Deallocate the memory for a spinlock.
*/
@@ -1911,8 +1660,7 @@ acpi_status __init acpi_os_initialize1(void)
BUG_ON(!kacpid_wq);
BUG_ON(!kacpi_notify_wq);
BUG_ON(!kacpi_hotplug_wq);
- acpi_install_interface_handler(acpi_osi_handler);
- acpi_osi_setup_late();
+ acpi_osi_init();
return AE_OK;
}

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index f0137bf..b25690b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -353,8 +353,6 @@ extern bool wmi_has_guid(const char *guid);
extern char acpi_video_backlight_string[];
extern long acpi_is_video_device(acpi_handle handle);
extern int acpi_blacklisted(void);
-extern void acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d);
-extern void acpi_osi_dmi_darwin(bool enable, const struct dmi_system_id *d);
extern void acpi_osi_setup(char *str);
extern bool acpi_osi_is_win8(void);

--
1.7.10

2016-04-27 08:54:58

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH v2 5/6] ACPI / osi: Cleanup coding style issues before creating a separate OSI source file

This patch performs necessary cleanups before moving OSI support to
another file.
1. Change int/unsigned int to bool
2. Change printk into pr_xxx
3. Do not initialize values to 0
4. Do not append additional "return" at the end of the function
5. Remove useless comments which may easily break line breaking rule
6. Rename functions to make them looking like acpi_osi_xxx
No functional changes.

Signed-off-by: Lv Zheng <[email protected]>
---
drivers/acpi/blacklist.c | 10 ++---
drivers/acpi/osl.c | 93 ++++++++++++++++------------------------------
include/linux/acpi.h | 4 +-
3 files changed, 40 insertions(+), 67 deletions(-)

diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index e947d3e..45199dc 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -135,17 +135,17 @@ int __init acpi_blacklisted(void)
#ifdef CONFIG_DMI
static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d)
{
- acpi_dmi_osi_darwin(1, d); /* enable */
+ acpi_osi_dmi_darwin(true, d);
return 0;
}
static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
{
- acpi_dmi_osi_linux(1, d); /* enable */
+ acpi_osi_dmi_linux(true, d);
return 0;
}
static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
{
- printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
+ pr_notice("DMI detected: %s\n", d->ident);
acpi_osi_setup("!Windows 2006");
acpi_osi_setup("!Windows 2006 SP1");
acpi_osi_setup("!Windows 2006 SP2");
@@ -153,13 +153,13 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
}
static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
{
- printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
+ pr_notice("DMI detected: %s\n", d->ident);
acpi_osi_setup("!Windows 2009");
return 0;
}
static int __init dmi_disable_osi_win8(const struct dmi_system_id *d)
{
- printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
+ pr_notice("DMI detected: %s\n", d->ident);
acpi_osi_setup("!Windows 2012");
return 0;
}
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 5dd2a79..d9eef7e 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -139,13 +139,13 @@ static struct acpi_osi_config {
unsigned int darwin_dmi:1;
unsigned int darwin_cmdline:1;
u8 default_disabling;
-} osi_config = {0, 0, 0, 0};
+} osi_config;

static u32 acpi_osi_handler(acpi_string interface, u32 supported)
{
if (!strcmp("Linux", interface)) {

- printk_once(KERN_NOTICE FW_BUG PREFIX
+ pr_notice_once(FW_BUG
"BIOS _OSI(Linux) query %s%s\n",
osi_config.linux_enable ? "honored" : "ignored",
osi_config.linux_cmdline ? " via cmdline" :
@@ -154,7 +154,7 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported)

if (!strcmp("Darwin", interface)) {

- printk_once(KERN_NOTICE PREFIX
+ pr_notice_once(
"BIOS _OSI(Darwin) query %s%s\n",
osi_config.darwin_enable ? "honored" : "ignored",
osi_config.darwin_cmdline ? " via cmdline" :
@@ -266,8 +266,7 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
return efi.acpi;
else {
- printk(KERN_ERR PREFIX
- "System description tables not found\n");
+ pr_err("System description tables not found\n");
return 0;
}
} else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
@@ -1445,15 +1444,15 @@ static int __init acpi_os_name_setup(char *str)

__setup("acpi_os_name=", acpi_os_name_setup);

-#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
-#define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */
+#define OSI_STRING_LENGTH_MAX 64
+#define OSI_STRING_ENTRIES_MAX 16

-struct osi_setup_entry {
+struct acpi_osi_entry {
char string[OSI_STRING_LENGTH_MAX];
bool enable;
};

-static struct osi_setup_entry
+static struct acpi_osi_entry
osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {
{"Module Device", true},
{"Processor Device", true},
@@ -1463,7 +1462,7 @@ static struct osi_setup_entry

void __init acpi_osi_setup(char *str)
{
- struct osi_setup_entry *osi;
+ struct acpi_osi_entry *osi;
bool enable = true;
int i;

@@ -1471,7 +1470,7 @@ void __init acpi_osi_setup(char *str)
return;

if (str == NULL || *str == '\0') {
- printk(KERN_INFO PREFIX "_OSI method disabled\n");
+ pr_info("_OSI method disabled\n");
acpi_gbl_create_osi_method = FALSE;
return;
}
@@ -1511,11 +1510,9 @@ void __init acpi_osi_setup(char *str)
}
}

-static void __init set_osi_darwin(unsigned int enable)
+static void __init __acpi_osi_setup_darwin(bool enable)
{
- if (osi_config.darwin_enable != enable)
- osi_config.darwin_enable = enable;
-
+ osi_config.darwin_enable = !!enable;
if (enable) {
acpi_osi_setup("!");
acpi_osi_setup("Darwin");
@@ -1525,65 +1522,41 @@ static void __init set_osi_darwin(unsigned int enable)
}
}

-static void __init acpi_cmdline_osi_darwin(unsigned int enable)
+static void __init acpi_osi_setup_darwin(bool enable)
{
- /* cmdline set the default and override DMI */
osi_config.darwin_cmdline = 1;
osi_config.darwin_dmi = 0;
- set_osi_darwin(enable);
-
- return;
+ __acpi_osi_setup_darwin(enable);
}

-void __init acpi_dmi_osi_darwin(int enable, const struct dmi_system_id *d)
+void __init acpi_osi_dmi_darwin(bool enable, const struct dmi_system_id *d)
{
- printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
-
- if (enable == -1)
- return;
-
- /* DMI knows that this box asks OSI(Darwin) */
+ pr_notice("DMI detected to setup _OSI(\"Darwin\"): %s\n", d->ident);
osi_config.darwin_dmi = 1;
- set_osi_darwin(enable);
-
- return;
+ __acpi_osi_setup_darwin(enable);
}

-static void __init set_osi_linux(unsigned int enable)
+static void __init __acpi_osi_setup_linux(bool enable)
{
- if (osi_config.linux_enable != enable)
- osi_config.linux_enable = enable;
-
- if (osi_config.linux_enable)
+ osi_config.linux_enable = !!enable;
+ if (enable)
acpi_osi_setup("Linux");
else
acpi_osi_setup("!Linux");
-
- return;
}

-static void __init acpi_cmdline_osi_linux(unsigned int enable)
+static void __init acpi_osi_setup_linux(bool enable)
{
- /* cmdline set the default and override DMI */
osi_config.linux_cmdline = 1;
osi_config.linux_dmi = 0;
- set_osi_linux(enable);
-
- return;
+ __acpi_osi_setup_linux(enable);
}

-void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
+void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d)
{
- printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
-
- if (enable == -1)
- return;
-
- /* DMI knows that this box asks OSI(Linux) */
+ pr_notice("DMI detected to setup _OSI(\"Linux\"): %s\n", d->ident);
osi_config.linux_dmi = 1;
- set_osi_linux(enable);
-
- return;
+ __acpi_osi_setup_linux(enable);
}

/*
@@ -1595,7 +1568,7 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
*/
static void __init acpi_osi_setup_late(void)
{
- struct osi_setup_entry *osi;
+ struct acpi_osi_entry *osi;
char *str;
int i;
acpi_status status;
@@ -1604,7 +1577,7 @@ static void __init acpi_osi_setup_late(void)
status = acpi_update_interfaces(osi_config.default_disabling);

if (ACPI_SUCCESS(status))
- printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n",
+ pr_info("Disabled all _OSI OS vendors%s\n",
osi_config.default_disabling ==
ACPI_DISABLE_ALL_STRINGS ?
" and feature groups" : "");
@@ -1620,12 +1593,12 @@ static void __init acpi_osi_setup_late(void)
status = acpi_install_interface(str);

if (ACPI_SUCCESS(status))
- printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+ pr_info("Added _OSI(%s)\n", str);
} else {
status = acpi_remove_interface(str);

if (ACPI_SUCCESS(status))
- printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+ pr_info("Deleted _OSI(%s)\n", str);
}
}
}
@@ -1633,13 +1606,13 @@ static void __init acpi_osi_setup_late(void)
static int __init osi_setup(char *str)
{
if (str && !strcmp("Linux", str))
- acpi_cmdline_osi_linux(1);
+ acpi_osi_setup_linux(true);
else if (str && !strcmp("!Linux", str))
- acpi_cmdline_osi_linux(0);
+ acpi_osi_setup_linux(false);
else if (str && !strcmp("Darwin", str))
- acpi_cmdline_osi_darwin(1);
+ acpi_osi_setup_darwin(true);
else if (str && !strcmp("!Darwin", str))
- acpi_cmdline_osi_darwin(0);
+ acpi_osi_setup_darwin(false);
else
acpi_osi_setup(str);

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 8fd3a82..f0137bf 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -353,8 +353,8 @@ extern bool wmi_has_guid(const char *guid);
extern char acpi_video_backlight_string[];
extern long acpi_is_video_device(acpi_handle handle);
extern int acpi_blacklisted(void);
-extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
-extern void acpi_dmi_osi_darwin(int enable, const struct dmi_system_id *d);
+extern void acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d);
+extern void acpi_osi_dmi_darwin(bool enable, const struct dmi_system_id *d);
extern void acpi_osi_setup(char *str);
extern bool acpi_osi_is_win8(void);

--
1.7.10

2016-04-27 08:54:45

by Zheng, Lv

[permalink] [raw]
Subject: [PATCH v2 3/6] ACPI / osi: Add acpi_osi=!! to allow reverting acpi_osi=!

This patch introduces acpi_osi=!! so that quirks may use it to revert
acpi_osi=!.

Signed-off-by: Lv Zheng <[email protected]>
---
Documentation/kernel-parameters.txt | 2 ++
drivers/acpi/osl.c | 3 +++
2 files changed, 5 insertions(+)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 0b3de80..c48f387 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -312,6 +312,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
acpi_osi=!* # remove all strings
acpi_osi=! # disable all built-in OS vendor
strings
+ acpi_osi=!! # enable all built-in OS vendor
+ strings
acpi_osi= # disable all strings

'acpi_osi=!' can be used in combination with single or
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index cd9667f..fbedea7 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1489,6 +1489,9 @@ void __init acpi_osi_setup(char *str)
osi->enable = false;
}
return;
+ } else if (*str == '!') {
+ osi_config.default_disabling = 0;
+ return;
}
enable = false;
}
--
1.7.10

2016-04-27 09:45:31

by Chen Yu

[permalink] [raw]
Subject: RE: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support

Hi Lv,

> -----Original Message-----
> From: Zheng, Lv
> Sent: Wednesday, April 27, 2016 4:55 PM
> To: Wysocki, Rafael J; Rafael J. Wysocki; Brown, Len
> Cc: Zheng, Lv; Lv Zheng; [email protected]; linux-
> [email protected]; Chen, Yu C
> Subject: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support
>
> From: Chen Yu <[email protected]>
>
> The following commit always reports positive value when Apple hardware
> queries _OSI("Darwin"):
> Commit: 7bc5a2bad0b8d9d1ac9f7b8b33150e4ddf197334
> Subject: ACPI: Support _OSI("Darwin") correctly However since this
> implementation places the judgement in runtime, it breaks acpi_osi=!Darwin
> and cannot return unsupported for _OSI("WinXXX") invoked before invoking
> _OSI("Darwin").
>
> This patch fixes the issues by reverting the wrong support and implementing
> the default behavior of _OSI("Darwin")/_OSI("WinXXX") on Apple hardware via
> DMI matching.
>
> Fixes: 7bc5a2bad0b8 ("ACPI: Support _OSI("Darwin") correctly")
> Cc: <[email protected]> # 3.18+
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=92111
> Reported-by: Lukas Wunner <[email protected]>
> Signed-off-by: Chen Yu <[email protected]>
> Signed-off-by: Lv Zheng <[email protected]>
> ---
> drivers/acpi/blacklist.c | 23 ++++++++++++++++++
> drivers/acpi/osl.c | 58 ++++++++++++++++++++++++++++++++++++++++---
> ---
> include/linux/acpi.h | 1 +
> 3 files changed, 75 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index
> 96809cd..e947d3e 100644
> --- a/drivers/acpi/blacklist.c
> +++ b/drivers/acpi/blacklist.c
> @@ -133,6 +133,11 @@ int __init acpi_blacklisted(void)
> return blacklisted;
> }
> #ifdef CONFIG_DMI
> +static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d)
> +{
> + acpi_dmi_osi_darwin(1, d); /* enable */
> + return 0;
> +}
> static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) {
> acpi_dmi_osi_linux(1, d); /* enable */
> @@ -331,6 +336,24 @@ static struct dmi_system_id acpi_osi_dmi_table[]
> __initdata = {
> },
> },
>
> + /*
> + * Enable _OSI("Darwin") for all apple platforms.
> + */
> + {
> + .callback = dmi_enable_osi_darwin,
> + .ident = "Apple hardware",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "Apple INC."),
> + },
> + },
> + {
> + .callback = dmi_enable_osi_darwin,
> + .ident = "Apple hardware",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, INC."),
> + },
> + },
> +
The vendor id should be 'Apple Inc.' and 'Apple Computer, Inc.' instead.

thanks,
yu

2016-04-27 21:21:47

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support

On Wednesday, April 27, 2016 09:45:21 AM Chen, Yu C wrote:
> Hi Lv,
>
> > -----Original Message-----
> > From: Zheng, Lv
> > Sent: Wednesday, April 27, 2016 4:55 PM
> > To: Wysocki, Rafael J; Rafael J. Wysocki; Brown, Len
> > Cc: Zheng, Lv; Lv Zheng; [email protected]; linux-
> > [email protected]; Chen, Yu C
> > Subject: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support
> >
> > From: Chen Yu <[email protected]>
> >
> > The following commit always reports positive value when Apple hardware
> > queries _OSI("Darwin"):
> > Commit: 7bc5a2bad0b8d9d1ac9f7b8b33150e4ddf197334
> > Subject: ACPI: Support _OSI("Darwin") correctly However since this
> > implementation places the judgement in runtime, it breaks acpi_osi=!Darwin
> > and cannot return unsupported for _OSI("WinXXX") invoked before invoking
> > _OSI("Darwin").
> >
> > This patch fixes the issues by reverting the wrong support and implementing
> > the default behavior of _OSI("Darwin")/_OSI("WinXXX") on Apple hardware via
> > DMI matching.
> >
> > Fixes: 7bc5a2bad0b8 ("ACPI: Support _OSI("Darwin") correctly")
> > Cc: <[email protected]> # 3.18+
> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=92111
> > Reported-by: Lukas Wunner <[email protected]>
> > Signed-off-by: Chen Yu <[email protected]>
> > Signed-off-by: Lv Zheng <[email protected]>
> > ---
> > drivers/acpi/blacklist.c | 23 ++++++++++++++++++
> > drivers/acpi/osl.c | 58 ++++++++++++++++++++++++++++++++++++++++---
> > ---
> > include/linux/acpi.h | 1 +
> > 3 files changed, 75 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index
> > 96809cd..e947d3e 100644
> > --- a/drivers/acpi/blacklist.c
> > +++ b/drivers/acpi/blacklist.c
> > @@ -133,6 +133,11 @@ int __init acpi_blacklisted(void)
> > return blacklisted;
> > }
> > #ifdef CONFIG_DMI
> > +static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d)
> > +{
> > + acpi_dmi_osi_darwin(1, d); /* enable */
> > + return 0;
> > +}
> > static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) {
> > acpi_dmi_osi_linux(1, d); /* enable */
> > @@ -331,6 +336,24 @@ static struct dmi_system_id acpi_osi_dmi_table[]
> > __initdata = {
> > },
> > },
> >
> > + /*
> > + * Enable _OSI("Darwin") for all apple platforms.
> > + */
> > + {
> > + .callback = dmi_enable_osi_darwin,
> > + .ident = "Apple hardware",
> > + .matches = {
> > + DMI_MATCH(DMI_SYS_VENDOR, "Apple INC."),
> > + },
> > + },
> > + {
> > + .callback = dmi_enable_osi_darwin,
> > + .ident = "Apple hardware",
> > + .matches = {
> > + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, INC."),
> > + },
> > + },
> > +
> The vendor id should be 'Apple Inc.' and 'Apple Computer, Inc.' instead.

If this is the only problem with this patch, I can fix it up. No need to resend.

Thanks,
Rafael

2016-04-28 02:30:33

by Zheng, Lv

[permalink] [raw]
Subject: RE: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support

Hi,

> From: [email protected] [mailto:linux-acpi-
> [email protected]] On Behalf Of Rafael J. Wysocki
> Subject: Re: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support
>
> On Wednesday, April 27, 2016 09:45:21 AM Chen, Yu C wrote:
> > Hi Lv,
> >
> > > From: Zheng, Lv
> > > Subject: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support
> > >
> > > From: Chen Yu <[email protected]>
> > >
> > > The following commit always reports positive value when Apple hardware
> > > queries _OSI("Darwin"):
> > > Commit: 7bc5a2bad0b8d9d1ac9f7b8b33150e4ddf197334
> > > Subject: ACPI: Support _OSI("Darwin") correctly However since this
> > > implementation places the judgement in runtime, it breaks
> acpi_osi=!Darwin
> > > and cannot return unsupported for _OSI("WinXXX") invoked before invoking
> > > _OSI("Darwin").
> > >
> > > This patch fixes the issues by reverting the wrong support and implementing
> > > the default behavior of _OSI("Darwin")/_OSI("WinXXX") on Apple hardware
> via
> > > DMI matching.
> > >
> > > Fixes: 7bc5a2bad0b8 ("ACPI: Support _OSI("Darwin") correctly")
> > > Cc: <[email protected]> # 3.18+
> > > Link: https://bugzilla.kernel.org/show_bug.cgi?id=92111
> > > Reported-by: Lukas Wunner <[email protected]>
> > > Signed-off-by: Chen Yu <[email protected]>
> > > Signed-off-by: Lv Zheng <[email protected]>
> > > ---
> > > drivers/acpi/blacklist.c | 23 ++++++++++++++++++
> > > drivers/acpi/osl.c | 58
> ++++++++++++++++++++++++++++++++++++++++---
> > > ---
> > > include/linux/acpi.h | 1 +
> > > 3 files changed, 75 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index
> > > 96809cd..e947d3e 100644
> > > --- a/drivers/acpi/blacklist.c
> > > +++ b/drivers/acpi/blacklist.c
> > > @@ -133,6 +133,11 @@ int __init acpi_blacklisted(void)
> > > return blacklisted;
> > > }
> > > #ifdef CONFIG_DMI
> > > +static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d)
> > > +{
> > > + acpi_dmi_osi_darwin(1, d); /* enable */
> > > + return 0;
> > > +}
> > > static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) {
> > > acpi_dmi_osi_linux(1, d); /* enable */
> > > @@ -331,6 +336,24 @@ static struct dmi_system_id acpi_osi_dmi_table[]
> > > __initdata = {
> > > },
> > > },
> > >
> > > + /*
> > > + * Enable _OSI("Darwin") for all apple platforms.
> > > + */
> > > + {
> > > + .callback = dmi_enable_osi_darwin,
> > > + .ident = "Apple hardware",
> > > + .matches = {
> > > + DMI_MATCH(DMI_SYS_VENDOR, "Apple INC."),
> > > + },
> > > + },
> > > + {
> > > + .callback = dmi_enable_osi_darwin,
> > > + .ident = "Apple hardware",
> > > + .matches = {
> > > + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, INC."),
> > > + },
> > > + },
> > > +
> > The vendor id should be 'Apple Inc.' and 'Apple Computer, Inc.' instead.
>
> If this is the only problem with this patch, I can fix it up. No need to resend.
[Lv Zheng]
This is the only problem.
Thanks for the help.

Best regards
-Lv

>
> Thanks,
> Rafael
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2016-04-28 07:54:32

by Chen Yu

[permalink] [raw]
Subject: RE: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support

Hi


> -----Original Message-----
> From: Rafael J. Wysocki [mailto:[email protected]]
> Sent: Thursday, April 28, 2016 5:25 AM
> To: Chen, Yu C; Zheng, Lv
> Cc: Lv Zheng; [email protected]; [email protected];
> Wysocki, Rafael J; Brown, Len
> Subject: Re: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support
>
> On Wednesday, April 27, 2016 09:45:21 AM Chen, Yu C wrote:
> > Hi Lv,
> >
> > > -----Original Message-----
> > > From: Zheng, Lv
> > > Sent: Wednesday, April 27, 2016 4:55 PM
> > > To: Wysocki, Rafael J; Rafael J. Wysocki; Brown, Len
> > > Cc: Zheng, Lv; Lv Zheng; [email protected]; linux-
> > > [email protected]; Chen, Yu C
> > > Subject: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support
> > >
> > > From: Chen Yu <[email protected]>
> > >
> > > The following commit always reports positive value when Apple
> > > hardware queries _OSI("Darwin"):
> > > Commit: 7bc5a2bad0b8d9d1ac9f7b8b33150e4ddf197334
> > > Subject: ACPI: Support _OSI("Darwin") correctly However since this
> > > implementation places the judgement in runtime, it breaks
> > > acpi_osi=!Darwin and cannot return unsupported for _OSI("WinXXX")
> > > invoked before invoking _OSI("Darwin").
> > >
> > > This patch fixes the issues by reverting the wrong support and
> > > implementing the default behavior of _OSI("Darwin")/_OSI("WinXXX")
> > > on Apple hardware via DMI matching.
> > >
> > > Fixes: 7bc5a2bad0b8 ("ACPI: Support _OSI("Darwin") correctly")
> > > Cc: <[email protected]> # 3.18+
> > > Link: https://bugzilla.kernel.org/show_bug.cgi?id=92111
> > > Reported-by: Lukas Wunner <[email protected]>
> > > Signed-off-by: Chen Yu <[email protected]>
> > > Signed-off-by: Lv Zheng <[email protected]>
> > The vendor id should be 'Apple Inc.' and 'Apple Computer, Inc.' instead.
>
> If this is the only problem with this patch, I can fix it up. No need to resend.
Yes, this is the only problem, please help fix it, thanks!
>
> Thanks,
> Rafael


2016-04-29 02:08:00

by Zheng, Lv

[permalink] [raw]
Subject: RE: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support

Hi, Rafael

> From: [email protected] [mailto:linux-acpi-
> [email protected]] On Behalf Of Zheng, Lv
> Subject: RE: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support
>

[Lv Zheng]
Skip.

> > > > @@ -331,6 +336,24 @@ static struct dmi_system_id acpi_osi_dmi_table[]
> > > > __initdata = {
> > > > },
> > > > },
> > > >
> > > > + /*
> > > > + * Enable _OSI("Darwin") for all apple platforms.
> > > > + */
> > > > + {
> > > > + .callback = dmi_enable_osi_darwin,
> > > > + .ident = "Apple hardware",
> > > > + .matches = {
> > > > + DMI_MATCH(DMI_SYS_VENDOR, "Apple INC."),
> > > > + },
> > > > + },
> > > > + {
> > > > + .callback = dmi_enable_osi_darwin,
> > > > + .ident = "Apple hardware",
> > > > + .matches = {
> > > > + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, INC."),
> > > > + },
> > > > + },
> > > > +
> > > The vendor id should be 'Apple Inc.' and 'Apple Computer, Inc.' instead.
> >
> > If this is the only problem with this patch, I can fix it up. No need to resend.
> [Lv Zheng]
> This is the only problem.
> Thanks for the help.
>

[Lv Zheng]
I just sent UPDATE of PATCH 4/6 and PATCH 6/6 to the mailing list with this corrected.
I was hoping they could update patchwork content so that the Bugzilla reporters might use the updated patches for confirmation.
The Message-Id(s) of the 2 patches were kept as same as the old ones.

Thanks and best regards
-Lv

2016-04-29 12:58:45

by Lukas Wunner

[permalink] [raw]
Subject: Re: [PATCH v2 4/6] ACPI / osi: Fix default _OSI(Darwin) support

Hi Lv Zheng,

On Fri, Apr 29, 2016 at 02:07:53AM +0000, Zheng, Lv wrote:
> I just sent UPDATE of PATCH 4/6 and PATCH 6/6 to the mailing list with this
> corrected.
> I was hoping they could update patchwork content so that the Bugzilla
> reporters might use the updated patches for confirmation.
> The Message-Id(s) of the 2 patches were kept as same as the old ones.

As promised on Bugzilla I've tested v2 of this series (with the "INC"
manually fixed up) on a MacBookPro9,1.

I only reviewed the patches in a superficial fashion, but one issue I've
noticed is that

#define pr_fmt(fmt) "ACPI: " fmt

is missing in osi.c (patch [6/6]).

Without command line arguments, Linux responds yay to _OSI("Darwin")
and nothing else and the Thunderbolt controller is powered up.

With "acpi_osi=!Darwin", Linux responds nay to everything and the
Thunderbolt controller is powered down.

So it seems to work as intended. If you want me to test anything else
please let me know.

Thanks,

Lukas