DMI, move ACPI boot quirk
PATCH 2/3 DMI, remove central blacklist
In reply to Andrey PaninSince last dmi quirk looks useless (it just prints 404 compliant url) we can finally remove central dmi blacklist.
Signed-off-by Andrey Panin <[email protected]>
arch/i386/kernel/dmi_scan.c | 45 -------------------------------------------- 1 files changed, 1 insertion(+), 44 deletions(-)
arch/i386/kernel/dmi_scan.c +1 -44
@@ -160,50 +160,10 @@ static void __init dmi_save_ident(struct }/* -* Ugly compatibility crap. -*/ -#define dmi_blacklist dmi_system_id -#define NO_MATCH { DMI_NONE, NULL} -#define MATCH DMI_MATCH - -/* -* Toshiba keyboard likes to repeat keys when they are not repeated. -*/ - -static __init int broken_toshiba_keyboard (struct dmi_blacklist *d) -{ -printk (KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, see http://davyd.ucc.asn.au/projects/toshiba/README\n" ); -return 0 ; -} - - - -/* -* Process the DMI blacklists -*/ - - -/* -* This will be expanded over time to force things like the APM -* interrupt mask settings according to the laptop -*/ - -static __initdata struct dmi_blacklist dmi_blacklist[]={ - - { broken_toshiba_keyboard,"Toshiba Satellite 4030cdt" , {/* Keyboard generates spurious repeats */ -MATCH (DMI_PRODUCT_NAME ,"S4030CDT/4.3" ), -NO_MATCH ,NO_MATCH ,NO_MATCH - } }, - - {NULL , } -}; - -/* * Process a DMI table entry. Right now all we care about are the BIOS * and machine entries. For 2.5 we should pull the smbus controller info * out of here. */ -static void __init dmi_decode (struct dmi_header *dm) {#ifdef DMI_DEBUG
@@ -253,10 +213,7 @@ static void __init dmi_decode(struct dmivoid __init dmi_scan_machine (void ) { -int err =dmi_iterate (dmi_decode); -if (err ==0 ) -dmi_check_system (dmi_blacklist); -else +if (dmi_iterate (dmi_decode))printk (KERN_INFO "DMI not present.\n" ); }
cover DMI, move ACPI boot quirk
This patch moves ACPI boot quirks out of dmi_scan.c
Signed-off-by Andrey Panin <[email protected]>
arch/i386/kernel/acpi/boot.c | 219 ++++++++++++++++++++++++++++++++++++++++++- arch/i386/kernel/dmi_scan.c | 163 -------------------------------- 2 files changed, 217 insertions(+), 165 deletions(-)
arch/i386/kernel/acpi/boot.c +217 -2
@@ -29,6 +29,7 @@#include <linux/efi.h> #include <linux/irq.h> #include <linux/module.h> +#include <linux/dmi.h> #include <asm/pgtable.h> #include <asm/io_apic.h>
@@ -831,6 +832,218 @@ acpi_process_madt(void)return ; } +extern int acpi_force; + +#ifdef __i386__ + +#ifdef CONFIG_ACPI_PCI +static int __init disable_acpi_irq (struct dmi_system_id *d) +{ +if (!acpi_force) { +printk (KERN_NOTICE "%s detected: force use of acpi=noirq\n" , + d->ident); +acpi_noirq_set (); + } +return 0 ; +} + +static int __init disable_acpi_pci (struct dmi_system_id *d) +{ +if (!acpi_force) { +printk (KERN_NOTICE "%s detected: force use of pci=noacpi\n" , + d->ident); +acpi_disable_pci (); + } +return 0 ; +} +#endif + +static int __init dmi_disable_acpi (struct dmi_system_id *d) +{ +if (!acpi_force) { +printk (KERN_NOTICE "%s detected: acpi off\n" ,d->ident); +disable_acpi (); + }else { +printk (KERN_NOTICE +"Warning: DMI blacklist says broken, but acpi forced\n" ); + } +return 0 ; +} + +/* +* Limit ACPI to CPU enumeration for HT +*/ +static int __init force_acpi_ht (struct dmi_system_id *d) +{ +if (!acpi_force) { +printk (KERN_NOTICE "%s detected: force use of acpi=ht\n" , d->ident); +disable_acpi (); + acpi_ht =1 ; + }else { +printk (KERN_NOTICE +"Warning: acpi=force overrules DMI blacklist: acpi=ht\n" ); + } +return 0 ; +} + +/* +* If your system is blacklisted here, but you find that acpi=force +* works for you, please contact [email protected] +*/ +static struct dmi_system_id __initdata acpi_dmi_table[] = { +/* +* Boxes that need ACPI disabled +*/ + { + .callback = dmi_disable_acpi, + .ident ="IBM Thinkpad" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"IBM" ), +DMI_MATCH (DMI_BOARD_NAME ,"2629H1G" ), + }, + }, + +/* +* Boxes that need acpi=ht +*/ + { + .callback = force_acpi_ht, + .ident ="FSC Primergy T850" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"FUJITSU SIEMENS" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"PRIMERGY T850" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="DELL GX240" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"Dell Computer Corporation" ), +DMI_MATCH (DMI_BOARD_NAME ,"OptiPlex GX240" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="HP VISUALIZE NT Workstation" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"Hewlett-Packard" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"HP VISUALIZE NT Workstation" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="Compaq Workstation W8000" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Compaq" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"Workstation W8000" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="ASUS P4B266" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"ASUSTeK Computer INC." ), +DMI_MATCH (DMI_BOARD_NAME ,"P4B266" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="ASUS P2B-DS" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"ASUSTeK Computer INC." ), +DMI_MATCH (DMI_BOARD_NAME ,"P2B-DS" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="ASUS CUR-DLS" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"ASUSTeK Computer INC." ), +DMI_MATCH (DMI_BOARD_NAME ,"CUR-DLS" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="ABIT i440BX-W83977" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"ABIT <http://www.abit.com>" ), +DMI_MATCH (DMI_BOARD_NAME ,"i440BX-W83977 (BP6)" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="IBM Bladecenter" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"IBM" ), +DMI_MATCH (DMI_BOARD_NAME ,"IBM eServer BladeCenter HS20" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="IBM eServer xSeries 360" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"IBM" ), +DMI_MATCH (DMI_BOARD_NAME ,"eServer xSeries 360" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="IBM eserver xSeries 330" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"IBM" ), +DMI_MATCH (DMI_BOARD_NAME ,"eserver xSeries 330" ), + }, + }, + { + .callback = force_acpi_ht, + .ident ="IBM eserver xSeries 440" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"IBM" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"eserver xSeries 440" ), + }, + }, + +#ifdef CONFIG_ACPI_PCI +/* +* Boxes that need ACPI PCI IRQ routing disabled +*/ + { + .callback = disable_acpi_irq, + .ident ="ASUS A7V" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"ASUSTeK Computer INC" ), +DMI_MATCH (DMI_BOARD_NAME ,"<A7V>" ), +/* newer BIOS, Revision 1011, does work */ +DMI_MATCH (DMI_BIOS_VERSION ,"ASUS A7V ACPI BIOS Revision 1007" ), + }, + }, + +/* +* Boxes that need ACPI PCI IRQ routing and PCI scan disabled +*/ + {/* _BBN 0 bug */ + .callback = disable_acpi_pci, + .ident ="ASUS PR-DLS" , + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"ASUSTeK Computer INC." ), +DMI_MATCH (DMI_BOARD_NAME ,"PR-DLS" ), +DMI_MATCH (DMI_BIOS_VERSION ,"ASUS PR-DLS ACPI BIOS Revision 1010" ), +DMI_MATCH (DMI_BIOS_DATE ,"03/21/2003" ) + }, + }, + { + .callback = disable_acpi_pci, + .ident ="Acer TravelMate 36x Laptop" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Acer" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"TravelMate 360" ), + }, + }, +#endif +}; + +#endif /* __i386__ */ +/* * acpi_boot_table_init() and acpi_boot_init() * called from setup_arch(), always.
@@ -859,6 +1072,10 @@ acpi_boot_table_init(void) {int error; +#ifdef __i386__ +dmi_check_system (acpi_dmi_table); +#endif +/* * If acpi_disabled, bail out * One exception: acpi=ht continues far enough to enumerate LAPICs
@@ -886,8 +1103,6 @@ acpi_boot_table_init(void)*/ error =acpi_blacklisted ();if (error) { -extern int acpi_force; -if (acpi_force) { printk(KERN_WARNING PREFIX "acpi=force override\n"); }else {
arch/i386/kernel/dmi_scan.c +0 -163
175 lines not on this page · raw message
PATCH 1/3 DMI, move ACPI sleep quirk
This patch moves ACPI sleep quirk out of dmi_scan.c
Signed-off-by Andrey Panin <[email protected]>
arch/i386/kernel/acpi/sleep.c | 26 ++++++++++++++++++++++++++ arch/i386/kernel/dmi_scan.c | 16 ---------------- 2 files changed, 26 insertions(+), 16 deletions(-)
arch/i386/kernel/acpi/sleep.c +26 -0
@@ -7,6 +7,7 @@#include <linux/acpi.h> #include <linux/bootmem.h> +#include <linux/dmi.h> #include <asm/smp.h> #include <asm/tlbflush.h>
@@ -91,3 +92,28 @@ static int __init acpi_sleep_setup(char__setup ("acpi_sleep=" , acpi_sleep_setup); + + +static __init int reset_videomode_after_s3 (struct dmi_system_id *d) +{ + acpi_video_flags |=2 ; +return 0 ; +} + +static __initdata struct dmi_system_id acpisleep_dmi_table[] = { + {/* Reset video mode after returning from ACPI S3 sleep */ + .callback = reset_videomode_after_s3, + .ident ="Toshiba Satellite 4030cdt" , + .matches = { +DMI_MATCH (DMI_PRODUCT_NAME ,"S4030CDT/4.3" ), + }, + }, +}; + +static int __init acpisleep_dmi_init (void ) +{ +dmi_check_system (acpisleep_dmi_table); +return 0 ; +} + +core_initcall (acpisleep_dmi_init);
arch/i386/kernel/dmi_scan.c +0 -16
@@ -177,16 +177,6 @@ static __init int broken_toshiba_keyboar } -#ifdef CONFIG_ACPI_SLEEP -static __init int reset_videomode_after_s3 (struct dmi_blacklist *d) -{ -/* See acpi_wakeup.S */ -extern long acpi_video_flags; - acpi_video_flags |=2 ; -return 0 ; -} -#endif -/* * Process the DMI blacklists
@@ -204,12 +194,6 @@ static __initdata struct dmi_blacklist dMATCH (DMI_PRODUCT_NAME ,"S4030CDT/4.3" ), NO_MATCH, NO_MATCH, NO_MATCH } }, -#ifdef CONFIG_ACPI_SLEEP - { reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */ - MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), - NO_MATCH, NO_MATCH, NO_MATCH - } }, -#endif { NULL, } };
PATCH 3/3 DMI code spring cleanup
In reply to Andrey PaninWhitespace and CodingStyle cleanup. No functionality changes.
Signed-off-by Andrey Panin <[email protected]>
arch/i386/kernel/dmi_scan.c | 163 ++++++++++++++++++-------------------------- 1 files changed, 70 insertions(+), 93 deletions(-)
arch/i386/kernel/dmi_scan.c +70 -93
@@ -1,22 +1,15 @@#include <linux/types.h> -#include <linux/kernel.h> #include <linux/string.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/slab.h> -#include <linux/acpi.h> -#include <asm/io.h> -#include <linux/pm.h> -#include <asm/system.h> #include <linux/dmi.h> #include <linux/bootmem.h> -struct dmi_header -{ -u8 type; -u8 length; -u16 handle; +struct dmi_header { +u8 type; +u8 length; +u16 handle; };#undef DMI_DEBUG
@@ -29,15 +22,13 @@ struct dmi_headerstatic char *__init dmi_string (struct dmi_header *dm,u8 s) { -u8 *bp=(u8 *)dm; - bp+=dm->length; -if (!s) +u8 *bp = ((u8 *) dm) + dm->length; + +if (!s)return "" ; s--; -while (s>0 && *bp) - { - bp+=strlen (bp); - bp++; +while (s >0 && *bp) { + bp +=strlen (bp) +1 ; s--; }return bp;
@@ -47,16 +38,14 @@ static char * __init dmi_string(struct d* We have to be cautious here. We have seen BIOSes with DMI pointers * pointing to completely the wrong place for example */ - -static int __init dmi_table (u32 base,int len,int num,void (*decode)(struct dmi_header *)) +static int __init dmi_table (u32 base,int len,int num, +void (*decode)(struct dmi_header *)) { -u8 *buf; -struct dmi_header *dm; -u8 *data; -int i=0 ; +u8 *buf, *data; +int i =0 ; buf =bt_ioremap (base, len); -if (buf==NULL ) +if (buf ==NULL )return -1 ; data = buf;
@@ -65,36 +54,34 @@ static int __init dmi_table(u32 base, in* Stop when we see all the items the table claimed to have * OR we run off the end of the table (also happens) */ - -while (i<num && data-buf+sizeof (struct dmi_header )<=len) - { - dm=(struct dmi_header *)data; +while ((i < num) && (data - buf +sizeof (struct dmi_header )) <= len) { +struct dmi_header *dm = (struct dmi_header *)data;/* * We want to know the total length (formated area and strings) * before decoding to make sure we won't run off the table in * dmi_decode or dmi_string */ - data+=dm->length; -while (data-buf<len-1 && (data[0 ] || data[1 ])) + data += dm->length; +while ((data - buf < len -1 ) && (data[0 ] || data[1 ])) data++; -if (data-buf<len-1 ) +if (data - buf < len -1 )decode (dm); - data+=2 ; + data +=2 ; i++; }bt_iounmap (buf, len);return 0 ; } - -inline static int __init dmi_checksum (u8 *buf) +static int __init dmi_checksum (u8 *buf) { -u8 sum=0 ; +u8 sum =0 ;int a; -for (a=0 ; a<15 ; a++) - sum+=buf[a]; -return (sum==0 ); +for (a =0 ; a <15 ; a++) + sum += buf[a]; + +return sum ==0 ; }static int __init dmi_iterate (void (*decode)(struct dmi_header *))
@@ -110,28 +97,30 @@ static int __init dmi_iterate(void (*dec p =ioremap (0xF0000 ,0x10000 );if (p ==NULL )return -1 ; +for (q = p; q < p +0x10000 ; q +=16 ) {memcpy_fromio (buf, q,15 ); -if (memcmp (buf,"_DMI_" ,5 )==0 &&dmi_checksum (buf)) - { -u16 num=buf[13 ]<<8 |buf[12 ]; -u16 len=buf[7 ]<<8 |buf[6 ]; -u32 base=buf[11 ]<<24 |buf[10 ]<<16 |buf[9 ]<<8 |buf[8 ]; +if ((memcmp (buf,"_DMI_" ,5 ) ==0 ) &&dmi_checksum (buf)) { +u16 num = (buf[13 ] <<8 ) | buf[12 ]; +u16 len = (buf[7 ] <<8 ) | buf[6 ]; +u32 base = (buf[11 ] <<24 ) | (buf[10 ] <<16 ) | + (buf[9 ] <<8 ) | buf[8 ];/* * DMI version 0.0 means that the real version is taken from * the SMBIOS version, which we don't know at this point. */ -if (buf[14 ]!=0 ) +if (buf[14 ] !=0 )printk (KERN_INFO "DMI %d.%d present.\n" , - buf[14 ]>>4 , buf[14 ]&0x0F ); + buf[14 ] >>4 , buf[14 ] &0xF );else printk (KERN_INFO "DMI present.\n" ); +dmi_printk ((KERN_INFO "%d structures occupying %d bytes.\n" , num, len)); -dmi_printk ((KERN_INFO "DMI table at 0x%08X.\n" , - base)); -if (dmi_table (base,len, num, decode)==0 ) +dmi_printk ((KERN_INFO "DMI table at 0x%08X.\n" , base)); + +if (dmi_table (base,len, num, decode) ==0 )return 0 ; } }
@@ -143,16 +132,17 @@ static char *dmi_ident[DMI_STRING_MAX];/* * Save a DMI string */ -static void __init dmi_save_ident (struct dmi_header *dm,int slot,int string) {char *d = (char *)dm;char *p =dmi_string (dm, d[string]); -if (p==NULL || *p ==0 ) + +if (p ==NULL || *p ==0 )return ;if (dmi_ident[slot])return ; - dmi_ident[slot] =alloc_bootmem (strlen (p)+1 ); + + dmi_ident[slot] =alloc_bootmem (strlen (p) +1 );if (dmi_ident[slot])strcpy (dmi_ident[slot], p);else
@@ -166,48 +156,35 @@ static void __init dmi_save_ident(struct*/ static void __init dmi_decode (struct dmi_header *dm) { -#ifdef DMI_DEBUG -u8 *data = (u8 *)dm; -#endif + u8 *data __attribute__((__unused__)) = (u8 *)dm; -switch (dm->type) - { -case 0 : -dmi_printk (("BIOS Vendor: %s\n" , -dmi_string (dm, data[4 ]))); -dmi_save_ident (dm,DMI_BIOS_VENDOR ,4 ); -dmi_printk (("BIOS Version: %s\n" , -dmi_string (dm, data[5 ]))); -dmi_save_ident (dm,DMI_BIOS_VERSION ,5 ); -dmi_printk (("BIOS Release: %s\n" , -dmi_string (dm, data[8 ]))); -dmi_save_ident (dm,DMI_BIOS_DATE ,8 ); -break ; -case 1 : -dmi_printk (("System Vendor: %s\n" , -dmi_string (dm, data[4 ]))); -dmi_save_ident (dm,DMI_SYS_VENDOR ,4 ); -dmi_printk (("Product Name: %s\n" , -dmi_string (dm, data[5 ]))); -dmi_save_ident (dm,DMI_PRODUCT_NAME ,5 ); -dmi_printk (("Version: %s\n" , -dmi_string (dm, data[6 ]))); -dmi_save_ident (dm,DMI_PRODUCT_VERSION ,6 ); -dmi_printk (("Serial Number: %s\n" , -dmi_string (dm, data[7 ]))); -dmi_save_ident (dm,DMI_PRODUCT_SERIAL ,7 ); -break ; -case 2 : -dmi_printk (("Board Vendor: %s\n" , -dmi_string (dm, data[4 ]))); -dmi_save_ident (dm,DMI_BOARD_VENDOR ,4 ); -dmi_printk (("Board Name: %s\n" , -dmi_string (dm, data[5 ]))); -dmi_save_ident (dm,DMI_BOARD_NAME ,5 ); -dmi_printk (("Board Version: %s\n" , -dmi_string (dm, data[6 ]))); -dmi_save_ident (dm,DMI_BOARD_VERSION ,6 ); -break ; +switch (dm->type) { +case 0 : +dmi_printk (("BIOS Vendor: %s\n" ,dmi_string (dm, data[4 ]))); +dmi_save_ident (dm,DMI_BIOS_VENDOR ,4 ); +dmi_printk (("BIOS Version: %s\n" ,dmi_string (dm, data[5 ]))); +dmi_save_ident (dm,DMI_BIOS_VERSION ,5 ); +dmi_printk (("BIOS Release: %s\n" ,dmi_string (dm, data[8 ]))); +dmi_save_ident (dm,DMI_BIOS_DATE ,8 ); +break ; +case 1 : +dmi_printk (("System Vendor: %s\n" ,dmi_string (dm, data[4 ]))); +dmi_save_ident (dm,DMI_SYS_VENDOR ,4 ); +dmi_printk (("Product Name: %s\n" ,dmi_string (dm, data[5 ]))); +dmi_save_ident (dm,DMI_PRODUCT_NAME ,5 ); +dmi_printk (("Version: %s\n" ,dmi_string (dm, data[6 ]))); +dmi_save_ident (dm,DMI_PRODUCT_VERSION ,6 ); +dmi_printk (("Serial Number: %s\n" ,dmi_string (dm, data[7 ]))); +dmi_save_ident (dm,DMI_PRODUCT_SERIAL ,7 ); +break ; +case 2 : +dmi_printk (("Board Vendor: %s\n" ,dmi_string (dm, data[4 ]))); +dmi_save_ident (dm,DMI_BOARD_VENDOR ,4 ); +dmi_printk (("Board Name: %s\n" ,dmi_string (dm, data[5 ]))); +dmi_save_ident (dm,DMI_BOARD_NAME ,5 ); +dmi_printk (("Board Version: %s\n" ,dmi_string (dm, data[6 ]))); +dmi_save_ident (dm,DMI_BOARD_VERSION ,6 ); +break ; } }