History

ACPI: make _OSI(Linux) console messages smarter

If BIOS invokes _OSI(Linux), the kernel response depends on what the ACPI DMI list knows about the system, and that is reflectd in dmesg: 1) System unknown to DMI: ACPI: BIOS _OSI(Linux) query ignored ACPI: DMI System Vendor: LENOVO ACPI: DMI Product Name: 7661W1P ACPI: DMI Product Version: ThinkPad T61 ACPI: DMI Board Name: 7661W1P ACPI: DMI BIOS Vendor: LENOVO ACPI: DMI BIOS Date: 10/18/2007 ACPI: Please send DMI info above to linux-acpi@vger.kernel.org ACPI: If "acpi_osi=Linux" works better, please notify linux-acpi@vger.kernel.org 2) System known to DMI, but effect of OSI(Linux) unknown: ACPI: DMI detected: Lenovo ThinkPad T61 ... ACPI: BIOS _OSI(Linux) query ignored via DMI ACPI: If "acpi_osi=Linux" works better, please notify linux-acpi@vger.kernel.org 3) System known to DMI, which disables _OSI(Linux): ACPI: DMI detected: Lenovo ThinkPad T61 ... ACPI: BIOS _OSI(Linux) query ignored via DMI 4) System known to DMI, which enable _OSI(Linux): ACPI: DMI detected: Lenovo ThinkPad T61 ACPI: Added _OSI(Linux) ... ACPI: BIOS _OSI(Linux) query honored via DMI cmdline overrides take precidence over the built-in default and the DMI prescribed default. cmdline "acpi_osi=Linux" results in: ACPI: BIOS _OSI(Linux) query honored via cmdline

Len Brown committed 18 years ago

Commit d4b7dc41 parent 7ce95ce3 files · +118 −22Browse files

Unified · Split

3 files
  1. drivers/acpi/blacklist.c +11 −0
  2. drivers/acpi/osl.c +102 −20
  3. include/linux/acpi.h +5 −2
drivers/acpi/blacklist.c+11−0
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 *
44 * Check to see if the given machine has a known bad ACPI BIOS
55 * or if the BIOS is too old.
6+ * Check given machine against acpi_osi_dmi_table[].
67 *
78 * Copyright (C) 2004 Len Brown <len.brown@intel.com>
89 * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com>
@@ -50,6 +51,8 @@ struct acpi_blacklist_item { · 41 unmodified lines
5051 u32 is_critical_error;
5152 };
5253
54+static struct dmi_system_id acpi_osi_dmi_table[] __initdata;
55+
5356 /*
5457 * POLICY: If *anything* doesn't work, put it on the blacklist.
5558 * If they are critical errors, mark it critical, and abort driver load.
@@ -165,5 +168,13 @@ int __init acpi_blacklisted(void) · 109 unmodified lines
165168
166169 blacklisted += blacklist_by_year();
167170
171+ dmi_check_system(acpi_osi_dmi_table);
172+
168173 return blacklisted;
169174 }
175+#ifdef CONFIG_DMI
176+static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
177+ {}
178+};
179+
180+#endif /* CONFIG_DMI */
drivers/acpi/osl.c+102−20
@@ -77,7 +77,55 @@ static struct workqueue_struct *kacpi_notify_wq; · 76 unmodified lines
7777 #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
7878 static char osi_additional_string[OSI_STRING_LENGTH_MAX];
7979
80−static int osi_linux; /* disable _OSI(Linux) by default */
80+/*
81+ * "Ode to _OSI(Linux)"
82+ *
83+ * osi_linux -- Control response to BIOS _OSI(Linux) query.
84+ *
85+ * As Linux evolves, the features that it supports change.
86+ * So an OSI string such as "Linux" is not specific enough
87+ * to be useful across multiple versions of Linux. It
88+ * doesn't identify any particular feature, interface,
89+ * or even any particular version of Linux...
90+ *
91+ * Unfortunately, Linux-2.6.22 and earlier responded "yes"
92+ * to a BIOS _OSI(Linux) query. When
93+ * a reference mobile BIOS started using it, its use
94+ * started to spread to many vendor platforms.
95+ * As it is not supportable, we need to halt that spread.
96+ *
97+ * Today, most BIOS references to _OSI(Linux) are noise --
98+ * they have no functional effect and are just dead code
99+ * carried over from the reference BIOS.
100+ *
101+ * The next most common case is that _OSI(Linux) harms Linux,
102+ * usually by causing the BIOS to follow paths that are
103+ * not tested during Windows validation.
104+ *
105+ * Finally, there is a short list of platforms
106+ * where OSI(Linux) benefits Linux.
107+ *
108+ * In Linux-2.6.23, OSI(Linux) is first disabled by default.
109+ * DMI is used to disable the dmesg warning about OSI(Linux)
110+ * on platforms where it is known to have no effect.
111+ * But a dmesg warning remains for systems where
112+ * we do not know if OSI(Linux) is good or bad for the system.
113+ * DMI is also used to enable OSI(Linux) for the machines
114+ * that are known to need it.
115+ *
116+ * BIOS writers should NOT query _OSI(Linux) on future systems.
117+ * It will be ignored by default, and to get Linux to
118+ * not ignore it will require a kernel source update to
119+ * add a DMI entry, or a boot-time "acpi_osi=Linux" invocation.
120+ */
121+#define OSI_LINUX_ENABLE 0
122+
123+struct osi_linux {
124+ unsigned int enable:1;
125+ unsigned int dmi:1;
126+ unsigned int cmdline:1;
127+ unsigned int known:1;
128+} osi_linux = { OSI_LINUX_ENABLE, 0, 0, 0};
81129
82130 static void __init acpi_request_region (struct acpi_generic_address *addr,
83131 unsigned int length, char *desc)
@@ -959,13 +1007,37 @@ static int __init acpi_os_name_setup(char *str) · 875 unmodified lines
9591007
9601008 __setup("acpi_os_name=", acpi_os_name_setup);
9611009
962−static void enable_osi_linux(int enable) {
1010+static void __init set_osi_linux(unsigned int enable)
1011+{
1012+ if (osi_linux.enable != enable) {
1013+ osi_linux.enable = enable;
1014+ printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
1015+ enable ? "Add": "Delet");
1016+ }
1017+ return;
1018+}
1019+
1020+static void __init acpi_cmdline_osi_linux(unsigned int enable)
1021+{
1022+ osi_linux.cmdline = 1; /* cmdline set the default */
1023+ set_osi_linux(enable);
1024+
1025+ return;
1026+}
1027+
1028+void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
1029+{
1030+ osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
1031+
1032+ printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
1033+
1034+ if (enable == -1)
1035+ return;
1036+
1037+ osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */
9631038
964− if (osi_linux != enable)
965− printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n",
966− enable ? "En": "Dis");
1039+ set_osi_linux(enable);
9671040
968− osi_linux = enable;
9691041 return;
9701042 }
9711043
@@ -982,12 +1054,12 @@ static int __init acpi_osi_setup(char *str) · 10 unmodified lines
9821054 printk(KERN_INFO PREFIX "_OSI method disabled\n");
9831055 acpi_gbl_create_osi_method = FALSE;
9841056 } else if (!strcmp("!Linux", str)) {
985− enable_osi_linux(0);
1057+ acpi_cmdline_osi_linux(0); /* !enable */
9861058 } else if (*str == '!') {
9871059 if (acpi_osi_invalidate(++str) == AE_OK)
9881060 printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
9891061 } else if (!strcmp("Linux", str)) {
990− enable_osi_linux(1);
1062+ acpi_cmdline_osi_linux(1); /* enable */
9911063 } else if (*osi_additional_string == '\0') {
9921064 strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
9931065 printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
@@ -1183,19 +1255,29 @@ acpi_os_validate_interface (char *interface) · 189 unmodified lines
11831255 if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
11841256 return AE_OK;
11851257 if (!strcmp("Linux", interface)) {
1186− printk(KERN_WARNING PREFIX
1187− "System BIOS is requesting _OSI(Linux)\n");
1188− if (acpi_dmi_dump())
1189− printk(KERN_NOTICE PREFIX
1190− "[please extract dmidecode output]\n");
1191− printk(KERN_NOTICE PREFIX
1192− "Please send DMI info above to "
1193− "linux-acpi@vger.kernel.org\n");
1258+
11941259 printk(KERN_NOTICE PREFIX
1195− "If \"acpi_osi=%sLinux\" works better, "
1196− "please notify linux-acpi@vger.kernel.org\n",
1197− osi_linux ? "!" : "");
1198− if(osi_linux)
1260+ "BIOS _OSI(Linux) query %s%s\n",
1261+ osi_linux.enable ? "honored" : "ignored",
1262+ osi_linux.cmdline ? " via cmdline" :
1263+ osi_linux.dmi ? " via DMI" : "");
1264+
1265+ if (!osi_linux.dmi) {
1266+ if (acpi_dmi_dump())
1267+ printk(KERN_NOTICE PREFIX
1268+ "[please extract dmidecode output]\n");
1269+ printk(KERN_NOTICE PREFIX
1270+ "Please send DMI info above to "
1271+ "linux-acpi@vger.kernel.org\n");
1272+ }
1273+ if (!osi_linux.known && !osi_linux.cmdline) {
1274+ printk(KERN_NOTICE PREFIX
1275+ "If \"acpi_osi=%sLinux\" works better, "
1276+ "please notify linux-acpi@vger.kernel.org\n",
1277+ osi_linux.enable ? "!" : "");
1278+ }
1279+
1280+ if (osi_linux.enable)
11991281 return AE_OK;
12001282 }
12011283 return AE_SUPPORT;
include/linux/acpi.h+5−2
@@ -40,6 +40,7 @@ · 39 unmodified lines
4040 #include <acpi/acpi_drivers.h>
4141 #include <acpi/acpi_numa.h>
4242 #include <asm/acpi.h>
43+#include <linux/dmi.h>
4344
4445
4546 #ifdef CONFIG_ACPI
@@ -192,7 +193,9 @@ extern int ec_transaction(u8 command, · 146 unmodified lines
192193 #endif /*CONFIG_ACPI_EC*/
193194
194195 extern int acpi_blacklisted(void);
195−extern void acpi_bios_year(char *s);
196+#ifdef CONFIG_DMI
197+extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
198+#endif
196199
197200 #ifdef CONFIG_ACPI_NUMA
198201 int acpi_get_pxm(acpi_handle handle);
@@ -226,5 +229,5 @@ static inline int acpi_boot_table_init(void) · 27 unmodified lines
226229 return 0;
227230 }
228231
229−#endif /* CONFIG_ACPI */
232+#endif /* !CONFIG_ACPI */
230233 #endif /*_LINUX_ACPI_H*/

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t