2005-04-17 02:20:36 +04:00
/*
* blacklist . c
*
* Check to see if the given machine has a known bad ACPI BIOS
* or if the BIOS is too old .
2008-01-24 04:50:56 +03:00
* Check given machine against acpi_osi_dmi_table [ ] .
2005-04-17 02:20:36 +04:00
*
* Copyright ( C ) 2004 Len Brown < len . brown @ intel . com >
* Copyright ( C ) 2002 Andy Grover < andrew . grover @ intel . com >
*
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* 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/kernel.h>
# include <linux/init.h>
# include <linux/acpi.h>
# include <linux/dmi.h>
2009-07-29 00:45:54 +04:00
# include "internal.h"
2005-08-05 08:44:28 +04:00
enum acpi_blacklist_predicates {
all_versions ,
less_than_or_equal ,
equal ,
greater_than_or_equal ,
2005-04-17 02:20:36 +04:00
} ;
2005-08-05 08:44:28 +04:00
struct acpi_blacklist_item {
char oem_id [ 7 ] ;
char oem_table_id [ 9 ] ;
u32 oem_revision ;
2007-02-02 19:48:19 +03:00
char * table ;
2005-08-05 08:44:28 +04:00
enum acpi_blacklist_predicates oem_revision_predicate ;
char * reason ;
u32 is_critical_error ;
2005-04-17 02:20:36 +04:00
} ;
2008-01-24 04:50:56 +03:00
static struct dmi_system_id acpi_osi_dmi_table [ ] __initdata ;
2005-04-17 02:20:36 +04:00
/*
* POLICY : If * anything * doesn ' t work , put it on the blacklist .
* If they are critical errors , mark it critical , and abort driver load .
*/
2005-08-05 08:44:28 +04:00
static struct acpi_blacklist_item acpi_blacklist [ ] __initdata = {
2005-04-17 02:20:36 +04:00
/* Compaq Presario 1700 */
2007-02-02 19:48:19 +03:00
{ " PTLTD " , " DSDT " , 0x06040000 , ACPI_SIG_DSDT , less_than_or_equal ,
2005-08-05 08:44:28 +04:00
" Multiple problems " , 1 } ,
2005-04-17 02:20:36 +04:00
/* Sony FX120, FX140, FX150? */
2007-02-02 19:48:19 +03:00
{ " SONY " , " U0 " , 0x20010313 , ACPI_SIG_DSDT , less_than_or_equal ,
2005-08-05 08:44:28 +04:00
" ACPI driver problem " , 1 } ,
2005-04-17 02:20:36 +04:00
/* Compaq Presario 800, Insyde BIOS */
2007-02-02 19:48:19 +03:00
{ " INT440 " , " SYSFexxx " , 0x00001001 , ACPI_SIG_DSDT , less_than_or_equal ,
2005-08-05 08:44:28 +04:00
" Does not use _REG to protect EC OpRegions " , 1 } ,
2005-04-17 02:20:36 +04:00
/* IBM 600E - _ADR should return 7, but it returns 1 */
2007-02-02 19:48:19 +03:00
{ " IBM " , " TP600E " , 0x00000105 , ACPI_SIG_DSDT , less_than_or_equal ,
2005-08-05 08:44:28 +04:00
" Incorrect _ADR " , 1 } ,
2005-04-17 02:20:36 +04:00
{ " " }
} ;
2005-08-05 08:44:28 +04:00
int __init acpi_blacklisted ( void )
2005-04-17 02:20:36 +04:00
{
int i = 0 ;
int blacklisted = 0 ;
2007-02-02 19:48:22 +03:00
struct acpi_table_header table_header ;
2005-04-17 02:20:36 +04:00
2005-08-05 08:44:28 +04:00
while ( acpi_blacklist [ i ] . oem_id [ 0 ] ! = ' \0 ' ) {
2007-02-02 19:48:19 +03:00
if ( acpi_get_table_header ( acpi_blacklist [ i ] . table , 0 , & table_header ) ) {
2005-04-17 02:20:36 +04:00
i + + ;
continue ;
}
2007-02-02 19:48:22 +03:00
if ( strncmp ( acpi_blacklist [ i ] . oem_id , table_header . oem_id , 6 ) ) {
2005-04-17 02:20:36 +04:00
i + + ;
continue ;
}
2005-08-05 08:44:28 +04:00
if ( strncmp
2007-02-02 19:48:22 +03:00
( acpi_blacklist [ i ] . oem_table_id , table_header . oem_table_id ,
2005-08-05 08:44:28 +04:00
8 ) ) {
2005-04-17 02:20:36 +04:00
i + + ;
continue ;
}
if ( ( acpi_blacklist [ i ] . oem_revision_predicate = = all_versions )
2005-08-05 08:44:28 +04:00
| | ( acpi_blacklist [ i ] . oem_revision_predicate = =
less_than_or_equal
2007-02-02 19:48:22 +03:00
& & table_header . oem_revision < =
2005-08-05 08:44:28 +04:00
acpi_blacklist [ i ] . oem_revision )
| | ( acpi_blacklist [ i ] . oem_revision_predicate = =
greater_than_or_equal
2007-02-02 19:48:22 +03:00
& & table_header . oem_revision > =
2005-08-05 08:44:28 +04:00
acpi_blacklist [ i ] . oem_revision )
2005-04-17 02:20:36 +04:00
| | ( acpi_blacklist [ i ] . oem_revision_predicate = = equal
2007-02-02 19:48:22 +03:00
& & table_header . oem_revision = =
2005-08-05 08:44:28 +04:00
acpi_blacklist [ i ] . oem_revision ) ) {
printk ( KERN_ERR PREFIX
" Vendor \" %6.6s \" System \" %8.8s \" "
" Revision 0x%x has a known ACPI BIOS problem. \n " ,
acpi_blacklist [ i ] . oem_id ,
acpi_blacklist [ i ] . oem_table_id ,
acpi_blacklist [ i ] . oem_revision ) ;
printk ( KERN_ERR PREFIX
" Reason: %s. This is a %s error \n " ,
acpi_blacklist [ i ] . reason ,
( acpi_blacklist [ i ] .
is_critical_error ? " non-recoverable " :
" recoverable " ) ) ;
2005-04-17 02:20:36 +04:00
blacklisted = acpi_blacklist [ i ] . is_critical_error ;
break ;
2005-08-05 08:44:28 +04:00
} else {
2005-04-17 02:20:36 +04:00
i + + ;
}
}
2008-01-24 04:50:56 +03:00
dmi_check_system ( acpi_osi_dmi_table ) ;
2005-04-17 02:20:36 +04:00
return blacklisted ;
}
2008-01-24 04:50:56 +03:00
# ifdef CONFIG_DMI
2008-01-24 04:56:18 +03:00
static int __init dmi_enable_osi_linux ( const struct dmi_system_id * d )
{
acpi_dmi_osi_linux ( 1 , d ) ; /* enable */
return 0 ;
}
2008-02-14 07:13:25 +03:00
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 " ) ;
2010-09-29 01:48:49 +04:00
acpi_osi_setup ( " !Windows 2006 SP1 " ) ;
acpi_osi_setup ( " !Windows 2006 SP2 " ) ;
2008-02-14 07:13:25 +03:00
return 0 ;
}
ACPI: disable _OSI(Windows 2009) on Asus K50IJ
Fix a win7 compability issue on Asus K50IJ.
Here is the _BCM method of this laptop:
Method (_BCM, 1, NotSerialized)
{
If (LGreaterEqual (OSFG, OSVT))
{
If (LNotEqual (OSFG, OSW7))
{
Store (One, BCMD)
Store (GCBL (Arg0), Local0)
Subtract (0x0F, Local0, LBTN)
^^^SBRG.EC0.STBR ()
...
}
Else
{
DBGR (0x0B, Zero, Zero, Arg0)
Store (Arg0, LBTN)
^^^SBRG.EC0.STBR ()
...
}
}
}
LBTN is used to store the index of the brightness level in the _BCL.
GCBL is a method that convert the percentage value to the index value.
If _OSI(Windows 2009) is not disabled, LBTN is stored a percentage
value which is surely beyond the end of _BCL package.
http://bugzilla.kernel.org/show_bug.cgi?id=14753
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
2009-12-21 11:13:15 +03:00
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 ;
}
2013-07-29 23:20:58 +04:00
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 ;
}
2015-07-03 02:06:00 +03:00
# ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
static int __init dmi_enable_rev_override ( const struct dmi_system_id * d )
{
printk ( KERN_NOTICE PREFIX " DMI detected: %s (force ACPI _REV to 5) \n " ,
d - > ident ) ;
acpi_rev_override_setup ( NULL ) ;
return 0 ;
}
# endif
2008-01-24 05:19:27 +03:00
2008-01-24 04:50:56 +03:00
static struct dmi_system_id acpi_osi_dmi_table [ ] __initdata = {
2008-02-14 07:13:25 +03:00
{
. callback = dmi_disable_osi_vista ,
. ident = " Fujitsu Siemens " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " FUJITSU SIEMENS " ) ,
2008-11-08 09:21:10 +03:00
DMI_MATCH ( DMI_PRODUCT_NAME , " ESPRIMO Mobile V5505 " ) ,
2008-02-14 07:13:25 +03:00
} ,
} ,
2009-06-22 07:31:17 +04:00
{
2010-10-01 12:28:29 +04:00
/*
* 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 " ) ,
} ,
} ,
{
2009-06-22 07:31:17 +04:00
. 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 " ) ,
2010-06-21 08:47:05 +04:00
DMI_MATCH ( DMI_PRODUCT_NAME , " VGN-SR290J " ) ,
2009-06-22 07:31:17 +04:00
} ,
} ,
ACPI: disable _OSI(Windows 2009) on Asus K50IJ
Fix a win7 compability issue on Asus K50IJ.
Here is the _BCM method of this laptop:
Method (_BCM, 1, NotSerialized)
{
If (LGreaterEqual (OSFG, OSVT))
{
If (LNotEqual (OSFG, OSW7))
{
Store (One, BCMD)
Store (GCBL (Arg0), Local0)
Subtract (0x0F, Local0, LBTN)
^^^SBRG.EC0.STBR ()
...
}
Else
{
DBGR (0x0B, Zero, Zero, Arg0)
Store (Arg0, LBTN)
^^^SBRG.EC0.STBR ()
...
}
}
}
LBTN is used to store the index of the brightness level in the _BCL.
GCBL is a method that convert the percentage value to the index value.
If _OSI(Windows 2009) is not disabled, LBTN is stored a percentage
value which is surely beyond the end of _BCL package.
http://bugzilla.kernel.org/show_bug.cgi?id=14753
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
2009-12-21 11:13:15 +03:00
{
2010-06-08 11:28:40 +04:00
. 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 " ) ,
} ,
} ,
{
2010-09-29 01:51:51 +04:00
. callback = dmi_disable_osi_vista ,
2015-03-16 12:35:18 +03:00
. ident = " VGN-SR19XN " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " Sony Corporation " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " VGN-SR19XN " ) ,
} ,
} ,
{
. callback = dmi_disable_osi_vista ,
2010-09-29 01:51:51 +04:00
. ident = " Toshiba Satellite L355 " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " TOSHIBA " ) ,
DMI_MATCH ( DMI_PRODUCT_VERSION , " Satellite L355 " ) ,
} ,
} ,
{
ACPI: disable _OSI(Windows 2009) on Asus K50IJ
Fix a win7 compability issue on Asus K50IJ.
Here is the _BCM method of this laptop:
Method (_BCM, 1, NotSerialized)
{
If (LGreaterEqual (OSFG, OSVT))
{
If (LNotEqual (OSFG, OSW7))
{
Store (One, BCMD)
Store (GCBL (Arg0), Local0)
Subtract (0x0F, Local0, LBTN)
^^^SBRG.EC0.STBR ()
...
}
Else
{
DBGR (0x0B, Zero, Zero, Arg0)
Store (Arg0, LBTN)
^^^SBRG.EC0.STBR ()
...
}
}
}
LBTN is used to store the index of the brightness level in the _BCL.
GCBL is a method that convert the percentage value to the index value.
If _OSI(Windows 2009) is not disabled, LBTN is stored a percentage
value which is surely beyond the end of _BCL package.
http://bugzilla.kernel.org/show_bug.cgi?id=14753
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
2009-12-21 11:13:15 +03:00
. callback = dmi_disable_osi_win7 ,
. ident = " ASUS K50IJ " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " ASUSTeK Computer Inc. " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " K50IJ " ) ,
} ,
} ,
2010-09-29 06:48:55 +04:00
{
. callback = dmi_disable_osi_vista ,
. ident = " Toshiba P305D " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " TOSHIBA " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " Satellite P305D " ) ,
} ,
} ,
2013-10-22 18:53:35 +04:00
{
. callback = dmi_disable_osi_vista ,
. ident = " Toshiba NB100 " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " TOSHIBA " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " NB100 " ) ,
} ,
} ,
2013-10-07 05:59:55 +04:00
/*
2014-09-15 07:56:12 +04:00
* The wireless hotkey does not work on those machines when
* returning true for _OSI ( " Windows 2012 " )
2013-10-07 05:59:55 +04:00
*/
2013-07-29 23:20:58 +04:00
{
. callback = dmi_disable_osi_win8 ,
2014-05-07 06:47:24 +04:00
. ident = " Dell Inspiron 7737 " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " Dell Inc. " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " Inspiron 7737 " ) ,
} ,
} ,
2014-09-15 07:56:12 +04:00
{
. 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 " ) ,
} ,
} ,
2014-10-27 08:55:45 +03:00
{
. callback = dmi_disable_osi_win8 ,
. ident = " Dell Vostro 3546 " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " Dell Inc. " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " Vostro 3546 " ) ,
} ,
} ,
2008-11-08 09:21:10 +03:00
2008-01-24 05:19:27 +03:00
/*
2008-11-08 09:21:10 +03:00
* BIOS invocation of _OSI ( Linux ) is almost always a BIOS bug .
* Linux ignores it , except for the machines enumerated below .
2008-01-24 05:19:27 +03:00
*/
2008-11-08 09:21:10 +03:00
2014-05-05 13:38:09 +04:00
/*
* 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 " ) ,
} ,
} ,
2015-07-03 02:06:00 +03:00
# ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
/*
* DELL XPS 13 ( 2015 ) switches sound between HDA and I2S
* depending on the ACPI _REV callback . If userspace supports
* I2S sufficiently ( or if you do not care about sound ) , you
* can safely disable this quirk .
*/
{
. callback = dmi_enable_rev_override ,
. ident = " DELL XPS 13 (2015) " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " Dell Inc. " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " XPS 13 9343 " ) ,
} ,
} ,
# endif
2008-01-24 04:50:56 +03:00
{ }
} ;
# endif /* CONFIG_DMI */