1*e5f660ebSLv Zheng /* 2*e5f660ebSLv Zheng * osi.c - _OSI implementation 3*e5f660ebSLv Zheng * 4*e5f660ebSLv Zheng * Copyright (C) 2016 Intel Corporation 5*e5f660ebSLv Zheng * Author: Lv Zheng <lv.zheng@intel.com> 6*e5f660ebSLv Zheng * 7*e5f660ebSLv Zheng * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8*e5f660ebSLv Zheng * 9*e5f660ebSLv Zheng * This program is free software; you can redistribute it and/or modify 10*e5f660ebSLv Zheng * it under the terms of the GNU General Public License as published by 11*e5f660ebSLv Zheng * the Free Software Foundation; either version 2 of the License, or (at 12*e5f660ebSLv Zheng * your option) any later version. 13*e5f660ebSLv Zheng * 14*e5f660ebSLv Zheng * This program is distributed in the hope that it will be useful, but 15*e5f660ebSLv Zheng * WITHOUT ANY WARRANTY; without even the implied warranty of 16*e5f660ebSLv Zheng * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17*e5f660ebSLv Zheng * General Public License for more details. 18*e5f660ebSLv Zheng * 19*e5f660ebSLv Zheng * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20*e5f660ebSLv Zheng */ 21*e5f660ebSLv Zheng 22*e5f660ebSLv Zheng /* Uncomment next line to get verbose printout */ 23*e5f660ebSLv Zheng /* #define DEBUG */ 24*e5f660ebSLv Zheng #define pr_fmt(fmt) "ACPI: " fmt 25*e5f660ebSLv Zheng 26*e5f660ebSLv Zheng #include <linux/module.h> 27*e5f660ebSLv Zheng #include <linux/kernel.h> 28*e5f660ebSLv Zheng #include <linux/acpi.h> 29*e5f660ebSLv Zheng #include <linux/dmi.h> 30*e5f660ebSLv Zheng 31*e5f660ebSLv Zheng #include "internal.h" 32*e5f660ebSLv Zheng 33*e5f660ebSLv Zheng 34*e5f660ebSLv Zheng #define OSI_STRING_LENGTH_MAX 64 35*e5f660ebSLv Zheng #define OSI_STRING_ENTRIES_MAX 16 36*e5f660ebSLv Zheng 37*e5f660ebSLv Zheng struct acpi_osi_entry { 38*e5f660ebSLv Zheng char string[OSI_STRING_LENGTH_MAX]; 39*e5f660ebSLv Zheng bool enable; 40*e5f660ebSLv Zheng }; 41*e5f660ebSLv Zheng 42*e5f660ebSLv Zheng static struct acpi_osi_config { 43*e5f660ebSLv Zheng u8 default_disabling; 44*e5f660ebSLv Zheng unsigned int linux_enable:1; 45*e5f660ebSLv Zheng unsigned int linux_dmi:1; 46*e5f660ebSLv Zheng unsigned int linux_cmdline:1; 47*e5f660ebSLv Zheng unsigned int darwin_enable:1; 48*e5f660ebSLv Zheng unsigned int darwin_dmi:1; 49*e5f660ebSLv Zheng unsigned int darwin_cmdline:1; 50*e5f660ebSLv Zheng } osi_config; 51*e5f660ebSLv Zheng 52*e5f660ebSLv Zheng static struct acpi_osi_config osi_config; 53*e5f660ebSLv Zheng static struct acpi_osi_entry 54*e5f660ebSLv Zheng osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { 55*e5f660ebSLv Zheng {"Module Device", true}, 56*e5f660ebSLv Zheng {"Processor Device", true}, 57*e5f660ebSLv Zheng {"3.0 _SCP Extensions", true}, 58*e5f660ebSLv Zheng {"Processor Aggregator Device", true}, 59*e5f660ebSLv Zheng }; 60*e5f660ebSLv Zheng 61*e5f660ebSLv Zheng static u32 acpi_osi_handler(acpi_string interface, u32 supported) 62*e5f660ebSLv Zheng { 63*e5f660ebSLv Zheng if (!strcmp("Linux", interface)) { 64*e5f660ebSLv Zheng pr_notice_once(FW_BUG 65*e5f660ebSLv Zheng "BIOS _OSI(Linux) query %s%s\n", 66*e5f660ebSLv Zheng osi_config.linux_enable ? "honored" : "ignored", 67*e5f660ebSLv Zheng osi_config.linux_cmdline ? " via cmdline" : 68*e5f660ebSLv Zheng osi_config.linux_dmi ? " via DMI" : ""); 69*e5f660ebSLv Zheng } 70*e5f660ebSLv Zheng if (!strcmp("Darwin", interface)) { 71*e5f660ebSLv Zheng pr_notice_once( 72*e5f660ebSLv Zheng "BIOS _OSI(Darwin) query %s%s\n", 73*e5f660ebSLv Zheng osi_config.darwin_enable ? "honored" : "ignored", 74*e5f660ebSLv Zheng osi_config.darwin_cmdline ? " via cmdline" : 75*e5f660ebSLv Zheng osi_config.darwin_dmi ? " via DMI" : ""); 76*e5f660ebSLv Zheng } 77*e5f660ebSLv Zheng 78*e5f660ebSLv Zheng return supported; 79*e5f660ebSLv Zheng } 80*e5f660ebSLv Zheng 81*e5f660ebSLv Zheng void __init acpi_osi_setup(char *str) 82*e5f660ebSLv Zheng { 83*e5f660ebSLv Zheng struct acpi_osi_entry *osi; 84*e5f660ebSLv Zheng bool enable = true; 85*e5f660ebSLv Zheng int i; 86*e5f660ebSLv Zheng 87*e5f660ebSLv Zheng if (!acpi_gbl_create_osi_method) 88*e5f660ebSLv Zheng return; 89*e5f660ebSLv Zheng 90*e5f660ebSLv Zheng if (str == NULL || *str == '\0') { 91*e5f660ebSLv Zheng pr_info("_OSI method disabled\n"); 92*e5f660ebSLv Zheng acpi_gbl_create_osi_method = FALSE; 93*e5f660ebSLv Zheng return; 94*e5f660ebSLv Zheng } 95*e5f660ebSLv Zheng 96*e5f660ebSLv Zheng if (*str == '!') { 97*e5f660ebSLv Zheng str++; 98*e5f660ebSLv Zheng if (*str == '\0') { 99*e5f660ebSLv Zheng /* Do not override acpi_osi=!* */ 100*e5f660ebSLv Zheng if (!osi_config.default_disabling) 101*e5f660ebSLv Zheng osi_config.default_disabling = 102*e5f660ebSLv Zheng ACPI_DISABLE_ALL_VENDOR_STRINGS; 103*e5f660ebSLv Zheng return; 104*e5f660ebSLv Zheng } else if (*str == '*') { 105*e5f660ebSLv Zheng osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS; 106*e5f660ebSLv Zheng for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { 107*e5f660ebSLv Zheng osi = &osi_setup_entries[i]; 108*e5f660ebSLv Zheng osi->enable = false; 109*e5f660ebSLv Zheng } 110*e5f660ebSLv Zheng return; 111*e5f660ebSLv Zheng } else if (*str == '!') { 112*e5f660ebSLv Zheng osi_config.default_disabling = 0; 113*e5f660ebSLv Zheng return; 114*e5f660ebSLv Zheng } 115*e5f660ebSLv Zheng enable = false; 116*e5f660ebSLv Zheng } 117*e5f660ebSLv Zheng 118*e5f660ebSLv Zheng for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { 119*e5f660ebSLv Zheng osi = &osi_setup_entries[i]; 120*e5f660ebSLv Zheng if (!strcmp(osi->string, str)) { 121*e5f660ebSLv Zheng osi->enable = enable; 122*e5f660ebSLv Zheng break; 123*e5f660ebSLv Zheng } else if (osi->string[0] == '\0') { 124*e5f660ebSLv Zheng osi->enable = enable; 125*e5f660ebSLv Zheng strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); 126*e5f660ebSLv Zheng break; 127*e5f660ebSLv Zheng } 128*e5f660ebSLv Zheng } 129*e5f660ebSLv Zheng } 130*e5f660ebSLv Zheng 131*e5f660ebSLv Zheng static void __init __acpi_osi_setup_darwin(bool enable) 132*e5f660ebSLv Zheng { 133*e5f660ebSLv Zheng osi_config.darwin_enable = !!enable; 134*e5f660ebSLv Zheng if (enable) { 135*e5f660ebSLv Zheng acpi_osi_setup("!"); 136*e5f660ebSLv Zheng acpi_osi_setup("Darwin"); 137*e5f660ebSLv Zheng } else { 138*e5f660ebSLv Zheng acpi_osi_setup("!!"); 139*e5f660ebSLv Zheng acpi_osi_setup("!Darwin"); 140*e5f660ebSLv Zheng } 141*e5f660ebSLv Zheng } 142*e5f660ebSLv Zheng 143*e5f660ebSLv Zheng static void __init acpi_osi_setup_darwin(bool enable) 144*e5f660ebSLv Zheng { 145*e5f660ebSLv Zheng /* Override acpi_osi_dmi_blacklisted() */ 146*e5f660ebSLv Zheng osi_config.darwin_dmi = 0; 147*e5f660ebSLv Zheng osi_config.darwin_cmdline = 1; 148*e5f660ebSLv Zheng __acpi_osi_setup_darwin(enable); 149*e5f660ebSLv Zheng } 150*e5f660ebSLv Zheng 151*e5f660ebSLv Zheng /* 152*e5f660ebSLv Zheng * The story of _OSI(Linux) 153*e5f660ebSLv Zheng * 154*e5f660ebSLv Zheng * From pre-history through Linux-2.6.22, Linux responded TRUE upon a BIOS 155*e5f660ebSLv Zheng * OSI(Linux) query. 156*e5f660ebSLv Zheng * 157*e5f660ebSLv Zheng * Unfortunately, reference BIOS writers got wind of this and put 158*e5f660ebSLv Zheng * OSI(Linux) in their example code, quickly exposing this string as 159*e5f660ebSLv Zheng * ill-conceived and opening the door to an un-bounded number of BIOS 160*e5f660ebSLv Zheng * incompatibilities. 161*e5f660ebSLv Zheng * 162*e5f660ebSLv Zheng * For example, OSI(Linux) was used on resume to re-POST a video card on 163*e5f660ebSLv Zheng * one system, because Linux at that time could not do a speedy restore in 164*e5f660ebSLv Zheng * its native driver. But then upon gaining quick native restore 165*e5f660ebSLv Zheng * capability, Linux has no way to tell the BIOS to skip the time-consuming 166*e5f660ebSLv Zheng * POST -- putting Linux at a permanent performance disadvantage. On 167*e5f660ebSLv Zheng * another system, the BIOS writer used OSI(Linux) to infer native OS 168*e5f660ebSLv Zheng * support for IPMI! On other systems, OSI(Linux) simply got in the way of 169*e5f660ebSLv Zheng * Linux claiming to be compatible with other operating systems, exposing 170*e5f660ebSLv Zheng * BIOS issues such as skipped device initialization. 171*e5f660ebSLv Zheng * 172*e5f660ebSLv Zheng * So "Linux" turned out to be a really poor chose of OSI string, and from 173*e5f660ebSLv Zheng * Linux-2.6.23 onward we respond FALSE. 174*e5f660ebSLv Zheng * 175*e5f660ebSLv Zheng * BIOS writers should NOT query _OSI(Linux) on future systems. Linux will 176*e5f660ebSLv Zheng * complain on the console when it sees it, and return FALSE. To get Linux 177*e5f660ebSLv Zheng * to return TRUE for your system will require a kernel source update to 178*e5f660ebSLv Zheng * add a DMI entry, or boot with "acpi_osi=Linux" 179*e5f660ebSLv Zheng */ 180*e5f660ebSLv Zheng static void __init __acpi_osi_setup_linux(bool enable) 181*e5f660ebSLv Zheng { 182*e5f660ebSLv Zheng osi_config.linux_enable = !!enable; 183*e5f660ebSLv Zheng if (enable) 184*e5f660ebSLv Zheng acpi_osi_setup("Linux"); 185*e5f660ebSLv Zheng else 186*e5f660ebSLv Zheng acpi_osi_setup("!Linux"); 187*e5f660ebSLv Zheng } 188*e5f660ebSLv Zheng 189*e5f660ebSLv Zheng static void __init acpi_osi_setup_linux(bool enable) 190*e5f660ebSLv Zheng { 191*e5f660ebSLv Zheng /* Override acpi_osi_dmi_blacklisted() */ 192*e5f660ebSLv Zheng osi_config.linux_dmi = 0; 193*e5f660ebSLv Zheng osi_config.linux_cmdline = 1; 194*e5f660ebSLv Zheng __acpi_osi_setup_linux(enable); 195*e5f660ebSLv Zheng } 196*e5f660ebSLv Zheng 197*e5f660ebSLv Zheng /* 198*e5f660ebSLv Zheng * Modify the list of "OS Interfaces" reported to BIOS via _OSI 199*e5f660ebSLv Zheng * 200*e5f660ebSLv Zheng * empty string disables _OSI 201*e5f660ebSLv Zheng * string starting with '!' disables that string 202*e5f660ebSLv Zheng * otherwise string is added to list, augmenting built-in strings 203*e5f660ebSLv Zheng */ 204*e5f660ebSLv Zheng static void __init acpi_osi_setup_late(void) 205*e5f660ebSLv Zheng { 206*e5f660ebSLv Zheng struct acpi_osi_entry *osi; 207*e5f660ebSLv Zheng char *str; 208*e5f660ebSLv Zheng int i; 209*e5f660ebSLv Zheng acpi_status status; 210*e5f660ebSLv Zheng 211*e5f660ebSLv Zheng if (osi_config.default_disabling) { 212*e5f660ebSLv Zheng status = acpi_update_interfaces(osi_config.default_disabling); 213*e5f660ebSLv Zheng if (ACPI_SUCCESS(status)) 214*e5f660ebSLv Zheng pr_info("Disabled all _OSI OS vendors%s\n", 215*e5f660ebSLv Zheng osi_config.default_disabling == 216*e5f660ebSLv Zheng ACPI_DISABLE_ALL_STRINGS ? 217*e5f660ebSLv Zheng " and feature groups" : ""); 218*e5f660ebSLv Zheng } 219*e5f660ebSLv Zheng 220*e5f660ebSLv Zheng for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { 221*e5f660ebSLv Zheng osi = &osi_setup_entries[i]; 222*e5f660ebSLv Zheng str = osi->string; 223*e5f660ebSLv Zheng if (*str == '\0') 224*e5f660ebSLv Zheng break; 225*e5f660ebSLv Zheng if (osi->enable) { 226*e5f660ebSLv Zheng status = acpi_install_interface(str); 227*e5f660ebSLv Zheng if (ACPI_SUCCESS(status)) 228*e5f660ebSLv Zheng pr_info("Added _OSI(%s)\n", str); 229*e5f660ebSLv Zheng } else { 230*e5f660ebSLv Zheng status = acpi_remove_interface(str); 231*e5f660ebSLv Zheng if (ACPI_SUCCESS(status)) 232*e5f660ebSLv Zheng pr_info("Deleted _OSI(%s)\n", str); 233*e5f660ebSLv Zheng } 234*e5f660ebSLv Zheng } 235*e5f660ebSLv Zheng } 236*e5f660ebSLv Zheng 237*e5f660ebSLv Zheng static int __init osi_setup(char *str) 238*e5f660ebSLv Zheng { 239*e5f660ebSLv Zheng if (str && !strcmp("Linux", str)) 240*e5f660ebSLv Zheng acpi_osi_setup_linux(true); 241*e5f660ebSLv Zheng else if (str && !strcmp("!Linux", str)) 242*e5f660ebSLv Zheng acpi_osi_setup_linux(false); 243*e5f660ebSLv Zheng else if (str && !strcmp("Darwin", str)) 244*e5f660ebSLv Zheng acpi_osi_setup_darwin(true); 245*e5f660ebSLv Zheng else if (str && !strcmp("!Darwin", str)) 246*e5f660ebSLv Zheng acpi_osi_setup_darwin(false); 247*e5f660ebSLv Zheng else 248*e5f660ebSLv Zheng acpi_osi_setup(str); 249*e5f660ebSLv Zheng 250*e5f660ebSLv Zheng return 1; 251*e5f660ebSLv Zheng } 252*e5f660ebSLv Zheng __setup("acpi_osi=", osi_setup); 253*e5f660ebSLv Zheng 254*e5f660ebSLv Zheng bool acpi_osi_is_win8(void) 255*e5f660ebSLv Zheng { 256*e5f660ebSLv Zheng return acpi_gbl_osi_data >= ACPI_OSI_WIN_8; 257*e5f660ebSLv Zheng } 258*e5f660ebSLv Zheng EXPORT_SYMBOL(acpi_osi_is_win8); 259*e5f660ebSLv Zheng 260*e5f660ebSLv Zheng static void __init acpi_osi_dmi_darwin(bool enable, 261*e5f660ebSLv Zheng const struct dmi_system_id *d) 262*e5f660ebSLv Zheng { 263*e5f660ebSLv Zheng pr_notice("DMI detected to setup _OSI(\"Darwin\"): %s\n", d->ident); 264*e5f660ebSLv Zheng osi_config.darwin_dmi = 1; 265*e5f660ebSLv Zheng __acpi_osi_setup_darwin(enable); 266*e5f660ebSLv Zheng } 267*e5f660ebSLv Zheng 268*e5f660ebSLv Zheng void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d) 269*e5f660ebSLv Zheng { 270*e5f660ebSLv Zheng pr_notice("DMI detected to setup _OSI(\"Linux\"): %s\n", d->ident); 271*e5f660ebSLv Zheng osi_config.linux_dmi = 1; 272*e5f660ebSLv Zheng __acpi_osi_setup_linux(enable); 273*e5f660ebSLv Zheng } 274*e5f660ebSLv Zheng 275*e5f660ebSLv Zheng static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d) 276*e5f660ebSLv Zheng { 277*e5f660ebSLv Zheng acpi_osi_dmi_darwin(true, d); 278*e5f660ebSLv Zheng 279*e5f660ebSLv Zheng return 0; 280*e5f660ebSLv Zheng } 281*e5f660ebSLv Zheng 282*e5f660ebSLv Zheng static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) 283*e5f660ebSLv Zheng { 284*e5f660ebSLv Zheng acpi_osi_dmi_linux(true, d); 285*e5f660ebSLv Zheng 286*e5f660ebSLv Zheng return 0; 287*e5f660ebSLv Zheng } 288*e5f660ebSLv Zheng 289*e5f660ebSLv Zheng static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) 290*e5f660ebSLv Zheng { 291*e5f660ebSLv Zheng pr_notice("DMI detected: %s\n", d->ident); 292*e5f660ebSLv Zheng acpi_osi_setup("!Windows 2006"); 293*e5f660ebSLv Zheng acpi_osi_setup("!Windows 2006 SP1"); 294*e5f660ebSLv Zheng acpi_osi_setup("!Windows 2006 SP2"); 295*e5f660ebSLv Zheng 296*e5f660ebSLv Zheng return 0; 297*e5f660ebSLv Zheng } 298*e5f660ebSLv Zheng 299*e5f660ebSLv Zheng static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) 300*e5f660ebSLv Zheng { 301*e5f660ebSLv Zheng pr_notice("DMI detected: %s\n", d->ident); 302*e5f660ebSLv Zheng acpi_osi_setup("!Windows 2009"); 303*e5f660ebSLv Zheng 304*e5f660ebSLv Zheng return 0; 305*e5f660ebSLv Zheng } 306*e5f660ebSLv Zheng 307*e5f660ebSLv Zheng static int __init dmi_disable_osi_win8(const struct dmi_system_id *d) 308*e5f660ebSLv Zheng { 309*e5f660ebSLv Zheng pr_notice("DMI detected: %s\n", d->ident); 310*e5f660ebSLv Zheng acpi_osi_setup("!Windows 2012"); 311*e5f660ebSLv Zheng 312*e5f660ebSLv Zheng return 0; 313*e5f660ebSLv Zheng } 314*e5f660ebSLv Zheng 315*e5f660ebSLv Zheng /* 316*e5f660ebSLv Zheng * Linux default _OSI response behavior is determined by this DMI table. 317*e5f660ebSLv Zheng * 318*e5f660ebSLv Zheng * Note that _OSI("Linux")/_OSI("Darwin") determined here can be overridden 319*e5f660ebSLv Zheng * by acpi_osi=!Linux/acpi_osi=!Darwin command line options. 320*e5f660ebSLv Zheng */ 321*e5f660ebSLv Zheng static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { 322*e5f660ebSLv Zheng { 323*e5f660ebSLv Zheng .callback = dmi_disable_osi_vista, 324*e5f660ebSLv Zheng .ident = "Fujitsu Siemens", 325*e5f660ebSLv Zheng .matches = { 326*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 327*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), 328*e5f660ebSLv Zheng }, 329*e5f660ebSLv Zheng }, 330*e5f660ebSLv Zheng { 331*e5f660ebSLv Zheng /* 332*e5f660ebSLv Zheng * There have a NVIF method in MSI GX723 DSDT need call by Nvidia 333*e5f660ebSLv Zheng * driver (e.g. nouveau) when user press brightness hotkey. 334*e5f660ebSLv Zheng * Currently, nouveau driver didn't do the job and it causes there 335*e5f660ebSLv Zheng * have a infinite while loop in DSDT when user press hotkey. 336*e5f660ebSLv Zheng * We add MSI GX723's dmi information to this table for workaround 337*e5f660ebSLv Zheng * this issue. 338*e5f660ebSLv Zheng * Will remove MSI GX723 from the table after nouveau grows support. 339*e5f660ebSLv Zheng */ 340*e5f660ebSLv Zheng .callback = dmi_disable_osi_vista, 341*e5f660ebSLv Zheng .ident = "MSI GX723", 342*e5f660ebSLv Zheng .matches = { 343*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), 344*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "GX723"), 345*e5f660ebSLv Zheng }, 346*e5f660ebSLv Zheng }, 347*e5f660ebSLv Zheng { 348*e5f660ebSLv Zheng .callback = dmi_disable_osi_vista, 349*e5f660ebSLv Zheng .ident = "Sony VGN-NS10J_S", 350*e5f660ebSLv Zheng .matches = { 351*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 352*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"), 353*e5f660ebSLv Zheng }, 354*e5f660ebSLv Zheng }, 355*e5f660ebSLv Zheng { 356*e5f660ebSLv Zheng .callback = dmi_disable_osi_vista, 357*e5f660ebSLv Zheng .ident = "Sony VGN-SR290J", 358*e5f660ebSLv Zheng .matches = { 359*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 360*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"), 361*e5f660ebSLv Zheng }, 362*e5f660ebSLv Zheng }, 363*e5f660ebSLv Zheng { 364*e5f660ebSLv Zheng .callback = dmi_disable_osi_vista, 365*e5f660ebSLv Zheng .ident = "VGN-NS50B_L", 366*e5f660ebSLv Zheng .matches = { 367*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 368*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"), 369*e5f660ebSLv Zheng }, 370*e5f660ebSLv Zheng }, 371*e5f660ebSLv Zheng { 372*e5f660ebSLv Zheng .callback = dmi_disable_osi_vista, 373*e5f660ebSLv Zheng .ident = "VGN-SR19XN", 374*e5f660ebSLv Zheng .matches = { 375*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 376*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"), 377*e5f660ebSLv Zheng }, 378*e5f660ebSLv Zheng }, 379*e5f660ebSLv Zheng { 380*e5f660ebSLv Zheng .callback = dmi_disable_osi_vista, 381*e5f660ebSLv Zheng .ident = "Toshiba Satellite L355", 382*e5f660ebSLv Zheng .matches = { 383*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 384*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), 385*e5f660ebSLv Zheng }, 386*e5f660ebSLv Zheng }, 387*e5f660ebSLv Zheng { 388*e5f660ebSLv Zheng .callback = dmi_disable_osi_win7, 389*e5f660ebSLv Zheng .ident = "ASUS K50IJ", 390*e5f660ebSLv Zheng .matches = { 391*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 392*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), 393*e5f660ebSLv Zheng }, 394*e5f660ebSLv Zheng }, 395*e5f660ebSLv Zheng { 396*e5f660ebSLv Zheng .callback = dmi_disable_osi_vista, 397*e5f660ebSLv Zheng .ident = "Toshiba P305D", 398*e5f660ebSLv Zheng .matches = { 399*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 400*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), 401*e5f660ebSLv Zheng }, 402*e5f660ebSLv Zheng }, 403*e5f660ebSLv Zheng { 404*e5f660ebSLv Zheng .callback = dmi_disable_osi_vista, 405*e5f660ebSLv Zheng .ident = "Toshiba NB100", 406*e5f660ebSLv Zheng .matches = { 407*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 408*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "NB100"), 409*e5f660ebSLv Zheng }, 410*e5f660ebSLv Zheng }, 411*e5f660ebSLv Zheng 412*e5f660ebSLv Zheng /* 413*e5f660ebSLv Zheng * The wireless hotkey does not work on those machines when 414*e5f660ebSLv Zheng * returning true for _OSI("Windows 2012") 415*e5f660ebSLv Zheng */ 416*e5f660ebSLv Zheng { 417*e5f660ebSLv Zheng .callback = dmi_disable_osi_win8, 418*e5f660ebSLv Zheng .ident = "Dell Inspiron 7737", 419*e5f660ebSLv Zheng .matches = { 420*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 421*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"), 422*e5f660ebSLv Zheng }, 423*e5f660ebSLv Zheng }, 424*e5f660ebSLv Zheng { 425*e5f660ebSLv Zheng .callback = dmi_disable_osi_win8, 426*e5f660ebSLv Zheng .ident = "Dell Inspiron 7537", 427*e5f660ebSLv Zheng .matches = { 428*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 429*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"), 430*e5f660ebSLv Zheng }, 431*e5f660ebSLv Zheng }, 432*e5f660ebSLv Zheng { 433*e5f660ebSLv Zheng .callback = dmi_disable_osi_win8, 434*e5f660ebSLv Zheng .ident = "Dell Inspiron 5437", 435*e5f660ebSLv Zheng .matches = { 436*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 437*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"), 438*e5f660ebSLv Zheng }, 439*e5f660ebSLv Zheng }, 440*e5f660ebSLv Zheng { 441*e5f660ebSLv Zheng .callback = dmi_disable_osi_win8, 442*e5f660ebSLv Zheng .ident = "Dell Inspiron 3437", 443*e5f660ebSLv Zheng .matches = { 444*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 445*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"), 446*e5f660ebSLv Zheng }, 447*e5f660ebSLv Zheng }, 448*e5f660ebSLv Zheng { 449*e5f660ebSLv Zheng .callback = dmi_disable_osi_win8, 450*e5f660ebSLv Zheng .ident = "Dell Vostro 3446", 451*e5f660ebSLv Zheng .matches = { 452*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 453*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"), 454*e5f660ebSLv Zheng }, 455*e5f660ebSLv Zheng }, 456*e5f660ebSLv Zheng { 457*e5f660ebSLv Zheng .callback = dmi_disable_osi_win8, 458*e5f660ebSLv Zheng .ident = "Dell Vostro 3546", 459*e5f660ebSLv Zheng .matches = { 460*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 461*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"), 462*e5f660ebSLv Zheng }, 463*e5f660ebSLv Zheng }, 464*e5f660ebSLv Zheng 465*e5f660ebSLv Zheng /* 466*e5f660ebSLv Zheng * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. 467*e5f660ebSLv Zheng * Linux ignores it, except for the machines enumerated below. 468*e5f660ebSLv Zheng */ 469*e5f660ebSLv Zheng 470*e5f660ebSLv Zheng /* 471*e5f660ebSLv Zheng * Without this this EEEpc exports a non working WMI interface, with 472*e5f660ebSLv Zheng * this it exports a working "good old" eeepc_laptop interface, fixing 473*e5f660ebSLv Zheng * both brightness control, and rfkill not working. 474*e5f660ebSLv Zheng */ 475*e5f660ebSLv Zheng { 476*e5f660ebSLv Zheng .callback = dmi_enable_osi_linux, 477*e5f660ebSLv Zheng .ident = "Asus EEE PC 1015PX", 478*e5f660ebSLv Zheng .matches = { 479*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), 480*e5f660ebSLv Zheng DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"), 481*e5f660ebSLv Zheng }, 482*e5f660ebSLv Zheng }, 483*e5f660ebSLv Zheng 484*e5f660ebSLv Zheng /* 485*e5f660ebSLv Zheng * Enable _OSI("Darwin") for all apple platforms. 486*e5f660ebSLv Zheng */ 487*e5f660ebSLv Zheng { 488*e5f660ebSLv Zheng .callback = dmi_enable_osi_darwin, 489*e5f660ebSLv Zheng .ident = "Apple hardware", 490*e5f660ebSLv Zheng .matches = { 491*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 492*e5f660ebSLv Zheng }, 493*e5f660ebSLv Zheng }, 494*e5f660ebSLv Zheng { 495*e5f660ebSLv Zheng .callback = dmi_enable_osi_darwin, 496*e5f660ebSLv Zheng .ident = "Apple hardware", 497*e5f660ebSLv Zheng .matches = { 498*e5f660ebSLv Zheng DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), 499*e5f660ebSLv Zheng }, 500*e5f660ebSLv Zheng }, 501*e5f660ebSLv Zheng {} 502*e5f660ebSLv Zheng }; 503*e5f660ebSLv Zheng 504*e5f660ebSLv Zheng static __init void acpi_osi_dmi_blacklisted(void) 505*e5f660ebSLv Zheng { 506*e5f660ebSLv Zheng dmi_check_system(acpi_osi_dmi_table); 507*e5f660ebSLv Zheng } 508*e5f660ebSLv Zheng 509*e5f660ebSLv Zheng int __init early_acpi_osi_init(void) 510*e5f660ebSLv Zheng { 511*e5f660ebSLv Zheng acpi_osi_dmi_blacklisted(); 512*e5f660ebSLv Zheng 513*e5f660ebSLv Zheng return 0; 514*e5f660ebSLv Zheng } 515*e5f660ebSLv Zheng 516*e5f660ebSLv Zheng int __init acpi_osi_init(void) 517*e5f660ebSLv Zheng { 518*e5f660ebSLv Zheng acpi_install_interface_handler(acpi_osi_handler); 519*e5f660ebSLv Zheng acpi_osi_setup_late(); 520*e5f660ebSLv Zheng 521*e5f660ebSLv Zheng return 0; 522*e5f660ebSLv Zheng } 523