1 #include <linux/config.h>
2 #include <linux/types.h>
3 #include <linux/kernel.h>
4 #include <linux/string.h>
5 #include <linux/init.h>
6 #include <linux/module.h>
7 #include <linux/apm_bios.h>
8 #include <linux/slab.h>
12 #include <asm/system.h>
13 #include <linux/bootmem.h>
15 unsigned long dmi_broken;
16 EXPORT_SYMBOL(dmi_broken);
18 int is_sony_vaio_laptop;
32 #define dmi_printk(x) printk x
37 static char * __init dmi_string(struct dmi_header *dm, u8 s)
54 * We have to be cautious here. We have seen BIOSes with DMI pointers
55 * pointing to completely the wrong place for example
58 static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dmi_header *))
61 struct dmi_header *dm;
65 buf = bt_ioremap(base, len);
72 * Stop when we see all the items the table claimed to have
73 * OR we run off the end of the table (also happens)
76 while(i<num && data-buf+sizeof(struct dmi_header)<=len)
78 dm=(struct dmi_header *)data;
80 * We want to know the total length (formated area and strings)
81 * before decoding to make sure we won't run off the table in
82 * dmi_decode or dmi_string
85 while(data-buf<len-1 && (data[0] || data[1]))
97 inline static int __init dmi_checksum(u8 *buf)
107 static int __init dmi_iterate(void (*decode)(struct dmi_header *))
114 isa_memcpy_fromio(buf, fp, 15);
115 if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf))
117 u16 num=buf[13]<<8|buf[12];
118 u16 len=buf[7]<<8|buf[6];
119 u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
122 * DMI version 0.0 means that the real version is taken from
123 * the SMBIOS version, which we don't know at this point.
126 printk(KERN_INFO "DMI %d.%d present.\n",
127 buf[14]>>4, buf[14]&0x0F);
129 printk(KERN_INFO "DMI present.\n");
130 dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
132 dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
134 if(dmi_table(base,len, num, decode)==0)
157 static char *dmi_ident[DMI_STRING_MAX];
163 static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
166 char *p = dmi_string(dm, d[string]);
167 if(p==NULL || *p == 0)
171 dmi_ident[slot] = alloc_bootmem(strlen(p)+1);
173 strcpy(dmi_ident[slot], p);
175 printk(KERN_ERR "dmi_save_ident: out of memory.\n");
179 * DMI callbacks for problem boards
192 int (*callback)(struct dmi_blacklist *);
194 struct dmi_strmatch matches[4];
197 #define NO_MATCH { NONE, NULL}
198 #define MATCH(a,b) { a, b }
201 * Reboot options and system auto-detection code provided by
202 * Dell Inc. so their systems "just work". :-)
206 * Some machines require the "reboot=b" commandline option, this quirk makes that automatic.
208 static __init int set_bios_reboot(struct dmi_blacklist *d)
210 extern int reboot_thru_bios;
211 if (reboot_thru_bios == 0)
213 reboot_thru_bios = 1;
214 printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident);
220 * Some machines require the "reboot=s" commandline option, this quirk makes that automatic.
222 static __init int set_smp_reboot(struct dmi_blacklist *d)
225 extern int reboot_smp;
229 printk(KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n", d->ident);
236 * Some machines require the "reboot=b,s" commandline option, this quirk makes that automatic.
238 static __init int set_smp_bios_reboot(struct dmi_blacklist *d)
246 * Some bioses have a broken protected mode poweroff and need to use realmode
249 static __init int set_realmode_power_off(struct dmi_blacklist *d)
251 if (apm_info.realmode_power_off == 0)
253 apm_info.realmode_power_off = 1;
254 printk(KERN_INFO "%s bios detected. Using realmode poweroff only.\n", d->ident);
261 * Some laptops require interrupts to be enabled during APM calls
264 static __init int set_apm_ints(struct dmi_blacklist *d)
266 if (apm_info.allow_ints == 0)
268 apm_info.allow_ints = 1;
269 printk(KERN_INFO "%s machine detected. Enabling interrupts during APM calls.\n", d->ident);
275 * Some APM bioses corrupt memory or just plain do not work
278 static __init int apm_is_horked(struct dmi_blacklist *d)
280 if (apm_info.disabled == 0)
282 apm_info.disabled = 1;
283 printk(KERN_INFO "%s machine detected. Disabling APM.\n", d->ident);
288 static __init int apm_is_horked_d850md(struct dmi_blacklist *d)
290 if (apm_info.disabled == 0) {
291 apm_info.disabled = 1;
292 printk(KERN_INFO "%s machine detected. Disabling APM.\n", d->ident);
293 printk(KERN_INFO "This bug is fixed in bios P15 which is available for \n");
294 printk(KERN_INFO "download from support.intel.com \n");
300 * Some APM bioses hang on APM idle calls
303 static __init int apm_likes_to_melt(struct dmi_blacklist *d)
305 if (apm_info.forbid_idle == 0) {
306 apm_info.forbid_idle = 1;
307 printk(KERN_INFO "%s machine detected. Disabling APM idle calls.\n", d->ident);
313 * Some machines, usually laptops, can't handle an enabled local APIC.
314 * The symptoms include hangs or reboots when suspending or resuming,
315 * attaching or detaching the power cord, or entering BIOS setup screens
316 * through magic key sequences.
318 static int __init local_apic_kills_bios(struct dmi_blacklist *d)
320 #ifdef CONFIG_X86_LOCAL_APIC
321 extern int enable_local_apic;
322 if (enable_local_apic == 0) {
323 enable_local_apic = -1;
324 printk(KERN_WARNING "%s with broken BIOS detected. "
325 "Refusing to enable the local APIC.\n",
333 * Don't access SMBus on IBM systems which get corrupted eeproms
336 static __init int disable_smbus(struct dmi_blacklist *d)
338 if (is_unsafe_smbus == 0) {
340 printk(KERN_INFO "%s machine detected. Disabling SMBus accesses.\n", d->ident);
346 * Work around broken HP Pavilion Notebooks which assign USB to
347 * IRQ 9 even though it is actually wired to IRQ 11
349 static __init int fix_broken_hp_bios_irq9(struct dmi_blacklist *d)
352 extern int broken_hp_bios_irq9;
353 if (broken_hp_bios_irq9 == 0)
355 broken_hp_bios_irq9 = 1;
356 printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident);
363 * Check for clue free BIOS implementations who use
364 * the following QA technique
366 * [ Write BIOS Code ]<------
368 * < Does it Compile >----N--
370 * < Does it Boot Win98 >-N--
374 * Phoenix A04 08/24/2000 is known bad (Dell Inspiron 5000e)
375 * Phoenix A07 09/29/2000 is known good (Dell Inspiron 5000)
378 static __init int broken_apm_power(struct dmi_blacklist *d)
380 apm_info.get_power_status_broken = 1;
381 printk(KERN_WARNING "BIOS strings suggest APM bugs, disabling power status reporting.\n");
386 * Check for a Sony Vaio system
388 * On a Sony system we want to enable the use of the sonypi
389 * driver for Sony-specific goodies like the camera and jogdial.
390 * We also want to avoid using certain functions of the PnP BIOS.
393 static __init int sony_vaio_laptop(struct dmi_blacklist *d)
395 if (is_sony_vaio_laptop == 0)
397 is_sony_vaio_laptop = 1;
398 printk(KERN_INFO "%s laptop detected.\n", d->ident);
404 * This bios swaps the APM minute reporting bytes over (Many sony laptops
405 * have this problem).
408 static __init int swab_apm_power_in_minutes(struct dmi_blacklist *d)
410 apm_info.get_power_status_swabinminutes = 1;
411 printk(KERN_WARNING "BIOS strings suggest APM reports battery life in minutes and wrong byte order.\n");
416 * ASUS K7V-RM has broken ACPI table defining sleep modes
419 static __init int broken_acpi_Sx(struct dmi_blacklist *d)
421 printk(KERN_WARNING "Detected ASUS mainboard with broken ACPI sleep table\n");
422 dmi_broken |= BROKEN_ACPI_Sx;
427 * Toshiba keyboard likes to repeat keys when they are not repeated.
430 static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
432 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");
437 * Toshiba fails to preserve interrupts over S1
440 static __init int init_ints_after_s1(struct dmi_blacklist *d)
442 printk(KERN_WARNING "Toshiba with broken S1 detected.\n");
443 dmi_broken |= BROKEN_INIT_AFTER_S1;
447 #ifdef CONFIG_ACPI_SLEEP
448 static __init int reset_videomode_after_s3(struct dmi_blacklist *d)
450 /* See acpi_wakeup.S */
451 extern long acpi_video_flags;
452 acpi_video_flags |= 2;
458 * Some Bioses enable the PS/2 mouse (touchpad) at resume, even if it was
459 * disabled before the suspend. Linux used to get terribly confused by that.
462 static __init int broken_ps2_resume(struct dmi_blacklist *d)
464 printk(KERN_INFO "%s machine detected. Mousepad Resume Bug workaround hopefully not needed.\n", d->ident);
469 * Exploding PnPBIOS. Don't yet know if its the BIOS or us for
473 static __init int exploding_pnp_bios(struct dmi_blacklist *d)
475 printk(KERN_WARNING "%s detected. Disabling PnPBIOS\n", d->ident);
476 dmi_broken |= BROKEN_PNP_BIOS;
480 static __init int acer_cpufreq_pst(struct dmi_blacklist *d)
482 printk(KERN_WARNING "%s laptop with broken PST tables in BIOS detected.\n", d->ident);
483 printk(KERN_WARNING "You need to downgrade to 3A21 (09/09/2002), or try a newer BIOS than 3A71 (01/20/2003)\n");
484 printk(KERN_WARNING "cpufreq scaling has been disabled as a result of this.\n");
485 dmi_broken |= BROKEN_CPUFREQ;
491 * Simple "print if true" callback
494 static __init int print_if_true(struct dmi_blacklist *d)
496 printk("%s\n", d->ident);
501 #ifdef CONFIG_ACPI_BOOT
502 extern int acpi_force;
504 static __init __attribute__((unused)) int dmi_disable_acpi(struct dmi_blacklist *d)
507 printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
511 "Warning: DMI blacklist says broken, but acpi forced\n");
517 * Limit ACPI to CPU enumeration for HT
519 static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d)
522 printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
527 "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
533 * early nForce2 reference BIOS shipped with a
534 * bogus ACPI IRQ0 -> pin2 interrupt override -- ignore it
536 static __init int ignore_timer_override(struct dmi_blacklist *d)
538 extern int acpi_skip_timer_override;
539 printk(KERN_NOTICE "%s detected: BIOS IRQ0 pin2 override"
540 " will be ignored\n", d->ident);
542 acpi_skip_timer_override = 1;
547 #ifdef CONFIG_ACPI_PCI
548 static __init int disable_acpi_irq(struct dmi_blacklist *d)
550 printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", d->ident);
554 static __init int disable_acpi_pci(struct dmi_blacklist *d)
556 printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident);
563 * Process the DMI blacklists
568 * This will be expanded over time to force things like the APM
569 * interrupt mask settings according to the laptop
572 static __initdata struct dmi_blacklist dmi_blacklist[]={
573 { broken_ps2_resume, "Dell Latitude C600", { /* Handle problems with APM on the C600 */
574 MATCH(DMI_SYS_VENDOR, "Dell"),
575 MATCH(DMI_PRODUCT_NAME, "Latitude C600"),
578 { set_apm_ints, "Dell Latitude", { /* Allow interrupts during suspend on Dell Latitude laptops*/
579 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
580 MATCH(DMI_PRODUCT_NAME, "Latitude C510"),
583 { apm_is_horked, "Dell Inspiron 2500", { /* APM crashes */
584 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
585 MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
586 MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
587 MATCH(DMI_BIOS_VERSION,"A11")
589 { set_apm_ints, "Dell Inspiron", { /* Allow interrupts during suspend on Dell Inspiron laptops*/
590 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
591 MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"),
594 { broken_apm_power, "Dell Inspiron 5000e", { /* Handle problems with APM on Inspiron 5000e */
595 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
596 MATCH(DMI_BIOS_VERSION, "A04"),
597 MATCH(DMI_BIOS_DATE, "08/24/2000"), NO_MATCH
599 { broken_apm_power, "Dell Inspiron 2500", { /* Handle problems with APM on Inspiron 2500 */
600 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
601 MATCH(DMI_BIOS_VERSION, "A12"),
602 MATCH(DMI_BIOS_DATE, "02/04/2002"), NO_MATCH
604 { apm_is_horked, "Dell Dimension 4100", { /* APM crashes */
605 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
606 MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
607 MATCH(DMI_BIOS_VENDOR,"Intel Corp."),
608 MATCH(DMI_BIOS_VERSION,"A11")
610 { set_realmode_power_off, "Award Software v4.60 PGMA", { /* broken PM poweroff bios */
611 MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
612 MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
613 MATCH(DMI_BIOS_DATE, "134526184"), NO_MATCH
615 { set_smp_bios_reboot, "Dell PowerEdge 1300", { /* Handle problems with rebooting on Dell 1300's */
616 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
617 MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"),
620 { set_bios_reboot, "Dell PowerEdge 300", { /* Handle problems with rebooting on Dell 300's */
621 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
622 MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
625 { set_bios_reboot, "Dell PowerEdge 2400", { /* Handle problems with rebooting on Dell 2400's */
626 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
627 MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
630 { set_apm_ints, "Compaq 12XL125", { /* Allow interrupts during suspend on Compaq Laptops*/
631 MATCH(DMI_SYS_VENDOR, "Compaq"),
632 MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
633 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
634 MATCH(DMI_BIOS_VERSION,"4.06")
636 { set_apm_ints, "ASUSTeK", { /* Allow interrupts during APM or the clock goes slow */
637 MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
638 MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"),
641 { apm_is_horked, "ABIT KX7-333[R]", { /* APM blows on shutdown */
642 MATCH(DMI_BOARD_VENDOR, "ABIT"),
643 MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"),
646 { apm_is_horked, "Trigem Delhi3", { /* APM crashes */
647 MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
648 MATCH(DMI_PRODUCT_NAME, "Delhi3"),
651 { apm_is_horked, "Fujitsu-Siemens", { /* APM crashes */
652 MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"),
653 MATCH(DMI_BIOS_VERSION, "Version1.01"),
656 { apm_is_horked_d850md, "Intel D850MD", { /* APM crashes */
657 MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
658 MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"),
661 { apm_is_horked, "Intel D810EMO", { /* APM crashes */
662 MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
663 MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"),
666 { apm_is_horked, "Dell XPS-Z", { /* APM crashes */
667 MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
668 MATCH(DMI_BIOS_VERSION, "A11"),
669 MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
672 { apm_is_horked, "Sharp PC-PJ/AX", { /* APM crashes */
673 MATCH(DMI_SYS_VENDOR, "SHARP"),
674 MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
675 MATCH(DMI_BIOS_VENDOR,"SystemSoft"),
676 MATCH(DMI_BIOS_VERSION,"Version R2.08")
678 { apm_is_horked, "Dell Inspiron 2500", { /* APM crashes */
679 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
680 MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
681 MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
682 MATCH(DMI_BIOS_VERSION,"A11")
684 { apm_likes_to_melt, "Jabil AMD", { /* APM idle hangs */
685 MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
686 MATCH(DMI_BIOS_VERSION, "0AASNP06"),
689 { apm_likes_to_melt, "AMI Bios", { /* APM idle hangs */
690 MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
691 MATCH(DMI_BIOS_VERSION, "0AASNP05"),
694 { sony_vaio_laptop, "Sony Vaio", { /* This is a Sony Vaio laptop */
695 MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
696 MATCH(DMI_PRODUCT_NAME, "PCG-"),
699 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
700 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
701 MATCH(DMI_BIOS_VERSION, "R0206H"),
702 MATCH(DMI_BIOS_DATE, "08/23/99"), NO_MATCH
705 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-N505VX */
706 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
707 MATCH(DMI_BIOS_VERSION, "W2K06H0"),
708 MATCH(DMI_BIOS_DATE, "02/03/00"), NO_MATCH
711 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-XG29 */
712 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
713 MATCH(DMI_BIOS_VERSION, "R0117A0"),
714 MATCH(DMI_BIOS_DATE, "04/25/00"), NO_MATCH
717 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
718 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
719 MATCH(DMI_BIOS_VERSION, "R0121Z1"),
720 MATCH(DMI_BIOS_DATE, "05/11/00"), NO_MATCH
723 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
724 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
725 MATCH(DMI_BIOS_VERSION, "WME01Z1"),
726 MATCH(DMI_BIOS_DATE, "08/11/00"), NO_MATCH
729 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
730 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
731 MATCH(DMI_BIOS_VERSION, "R0206Z3"),
732 MATCH(DMI_BIOS_DATE, "12/25/00"), NO_MATCH
735 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
736 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
737 MATCH(DMI_BIOS_VERSION, "R0203D0"),
738 MATCH(DMI_BIOS_DATE, "05/12/00"), NO_MATCH
741 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
742 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
743 MATCH(DMI_BIOS_VERSION, "R0203Z3"),
744 MATCH(DMI_BIOS_DATE, "08/25/00"), NO_MATCH
747 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
748 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
749 MATCH(DMI_BIOS_VERSION, "R0209Z3"),
750 MATCH(DMI_BIOS_DATE, "05/12/01"), NO_MATCH
753 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-F104K */
754 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
755 MATCH(DMI_BIOS_VERSION, "R0204K2"),
756 MATCH(DMI_BIOS_DATE, "08/28/00"), NO_MATCH
759 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */
760 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
761 MATCH(DMI_BIOS_VERSION, "R0208P1"),
762 MATCH(DMI_BIOS_DATE, "11/09/00"), NO_MATCH
765 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-C1VE */
766 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
767 MATCH(DMI_BIOS_VERSION, "R0204P1"),
768 MATCH(DMI_BIOS_DATE, "09/12/00"), NO_MATCH
771 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-C1VE */
772 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
773 MATCH(DMI_BIOS_VERSION, "WXPO1Z3"),
774 MATCH(DMI_BIOS_DATE, "10/26/01"), NO_MATCH
777 { exploding_pnp_bios, "Higraded P14H", { /* PnPBIOS GPF on boot */
778 MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
779 MATCH(DMI_BIOS_VERSION, "07.00T"),
780 MATCH(DMI_SYS_VENDOR, "Higraded"),
781 MATCH(DMI_PRODUCT_NAME, "P14H")
783 { exploding_pnp_bios, "ASUS P4P800", { /* PnPBIOS GPF on boot */
784 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
785 MATCH(DMI_BOARD_NAME, "P4P800"),
789 /* Machines which have problems handling enabled local APICs */
791 { local_apic_kills_bios, "Dell Inspiron", {
792 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
793 MATCH(DMI_PRODUCT_NAME, "Inspiron"),
797 { local_apic_kills_bios, "Dell Latitude", {
798 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
799 MATCH(DMI_PRODUCT_NAME, "Latitude"),
803 { local_apic_kills_bios, "IBM Thinkpad T20", {
804 MATCH(DMI_BOARD_VENDOR, "IBM"),
805 MATCH(DMI_BOARD_NAME, "264741U"),
809 { local_apic_kills_bios, "ASUS L3C", {
810 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
811 MATCH(DMI_BOARD_NAME, "P4_L3C"),
815 { broken_acpi_Sx, "ASUS K7V-RM", { /* Bad ACPI Sx table */
816 MATCH(DMI_BIOS_VERSION,"ASUS K7V-RM ACPI BIOS Revision 1003A"),
817 MATCH(DMI_BOARD_NAME, "<K7V-RM>"),
821 { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */
822 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
823 NO_MATCH, NO_MATCH, NO_MATCH
825 { init_ints_after_s1, "Toshiba Satellite 4030cdt", { /* Reinitialization of 8259 is needed after S1 resume */
826 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
827 NO_MATCH, NO_MATCH, NO_MATCH
829 #ifdef CONFIG_ACPI_SLEEP
830 { reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */
831 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
832 NO_MATCH, NO_MATCH, NO_MATCH
836 { print_if_true, KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.", {
837 MATCH(DMI_SYS_VENDOR, "IBM"),
838 MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"),
842 { fix_broken_hp_bios_irq9, "HP Pavilion N5400 Series Laptop", {
843 MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
844 MATCH(DMI_BIOS_VERSION, "GE.M1.03"),
845 MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"),
846 MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736")
851 * Generic per vendor APM settings
854 { set_apm_ints, "IBM", { /* Allow interrupts during suspend on IBM laptops */
855 MATCH(DMI_SYS_VENDOR, "IBM"),
856 NO_MATCH, NO_MATCH, NO_MATCH
860 * SMBus / sensors settings
863 { disable_smbus, "IBM", {
864 MATCH(DMI_SYS_VENDOR, "IBM"),
865 NO_MATCH, NO_MATCH, NO_MATCH
869 * Some Athlon laptops have really fucked PST tables.
870 * A BIOS update is all that can save them.
871 * Mention this, and disable cpufreq.
873 { acer_cpufreq_pst, "Acer Aspire", {
874 MATCH(DMI_SYS_VENDOR, "Insyde Software"),
875 MATCH(DMI_BIOS_VERSION, "3A71"),
879 #ifdef CONFIG_ACPI_BOOT
881 * If your system is blacklisted here, but you find that acpi=force
882 * works for you, please contact acpi-devel@sourceforge.net
886 * Boxes that need ACPI disabled
889 { dmi_disable_acpi, "IBM Thinkpad", {
890 MATCH(DMI_BOARD_VENDOR, "IBM"),
891 MATCH(DMI_BOARD_NAME, "2629H1G"),
892 NO_MATCH, NO_MATCH }},
895 * Boxes that need acpi=ht
898 { force_acpi_ht, "FSC Primergy T850", {
899 MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
900 MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
901 NO_MATCH, NO_MATCH }},
903 { force_acpi_ht, "DELL GX240", {
904 MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
905 MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
906 NO_MATCH, NO_MATCH }},
908 { force_acpi_ht, "HP VISUALIZE NT Workstation", {
909 MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
910 MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
911 NO_MATCH, NO_MATCH }},
913 { force_acpi_ht, "Compaq ProLiant DL380 G2", {
914 MATCH(DMI_SYS_VENDOR, "Compaq"),
915 MATCH(DMI_PRODUCT_NAME, "ProLiant DL380 G2"),
916 NO_MATCH, NO_MATCH }},
918 { force_acpi_ht, "Compaq ProLiant ML530 G2", {
919 MATCH(DMI_SYS_VENDOR, "Compaq"),
920 MATCH(DMI_PRODUCT_NAME, "ProLiant ML530 G2"),
921 NO_MATCH, NO_MATCH }},
923 { force_acpi_ht, "Compaq ProLiant ML350 G3", {
924 MATCH(DMI_SYS_VENDOR, "Compaq"),
925 MATCH(DMI_PRODUCT_NAME, "ProLiant ML350 G3"),
926 NO_MATCH, NO_MATCH }},
928 { force_acpi_ht, "Compaq Workstation W8000", {
929 MATCH(DMI_SYS_VENDOR, "Compaq"),
930 MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
931 NO_MATCH, NO_MATCH }},
933 { force_acpi_ht, "ASUS P4B266", {
934 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
935 MATCH(DMI_BOARD_NAME, "P4B266"),
936 NO_MATCH, NO_MATCH }},
938 { force_acpi_ht, "ASUS P2B-DS", {
939 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
940 MATCH(DMI_BOARD_NAME, "P2B-DS"),
941 NO_MATCH, NO_MATCH }},
943 { force_acpi_ht, "ASUS CUR-DLS", {
944 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
945 MATCH(DMI_BOARD_NAME, "CUR-DLS"),
946 NO_MATCH, NO_MATCH }},
948 { force_acpi_ht, "ABIT i440BX-W83977", {
949 MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
950 MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
951 NO_MATCH, NO_MATCH }},
953 { force_acpi_ht, "IBM Bladecenter", {
954 MATCH(DMI_BOARD_VENDOR, "IBM"),
955 MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
956 NO_MATCH, NO_MATCH }},
958 { force_acpi_ht, "IBM eServer xSeries 360", {
959 MATCH(DMI_BOARD_VENDOR, "IBM"),
960 MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
961 NO_MATCH, NO_MATCH }},
963 { force_acpi_ht, "IBM eserver xSeries 330", {
964 MATCH(DMI_BOARD_VENDOR, "IBM"),
965 MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
966 NO_MATCH, NO_MATCH }},
968 { force_acpi_ht, "IBM eserver xSeries 440", {
969 MATCH(DMI_BOARD_VENDOR, "IBM"),
970 MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
971 NO_MATCH, NO_MATCH }},
974 * Systems with nForce2 BIOS timer override bug
975 * nVidia claims all nForce have timer on pin0,
976 * and applying this workaround is a NOP on fixed BIOS,
977 * so prospects are good for replacing these entries
978 * with something to key of chipset PCI-ID.
980 { ignore_timer_override, "Abit NF7-S v2", {
981 MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),
982 MATCH(DMI_BOARD_NAME, "NF7-S/NF7,NF7-V (nVidia-nForce2)"),
983 MATCH(DMI_BIOS_VERSION, "6.00 PG"),
984 MATCH(DMI_BIOS_DATE, "03/24/2004") }},
986 { ignore_timer_override, "Asus A7N8X v2", {
987 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
988 MATCH(DMI_BOARD_NAME, "A7N8X2.0"),
989 MATCH(DMI_BIOS_VERSION, "ASUS A7N8X2.0 Deluxe ACPI BIOS Rev 1007"),
990 MATCH(DMI_BIOS_DATE, "10/06/2003") }},
992 { ignore_timer_override, "Asus A7N8X-X", {
993 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
994 MATCH(DMI_BOARD_NAME, "A7N8X-X"),
995 MATCH(DMI_BIOS_VERSION, "ASUS A7N8X-X ACPI BIOS Rev 1009"),
996 MATCH(DMI_BIOS_DATE, "2/3/2004") }},
998 { ignore_timer_override, "MSI K7N2-Delta", {
999 MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
1000 MATCH(DMI_BOARD_NAME, "MS-6570"),
1001 MATCH(DMI_BIOS_VERSION, "6.00 PG"),
1002 MATCH(DMI_BIOS_DATE, "03/29/2004") }},
1004 { ignore_timer_override, "Shuttle SN41G2", {
1005 MATCH(DMI_BOARD_VENDOR, "Shuttle Inc"),
1006 MATCH(DMI_BOARD_NAME, "FN41"),
1007 MATCH(DMI_BIOS_VERSION, "6.00 PG"),
1008 MATCH(DMI_BIOS_DATE, "01/14/2004") }},
1010 { ignore_timer_override, "Shuttle AN35N", {
1011 MATCH(DMI_BOARD_VENDOR, "Shuttle Inc"),
1012 MATCH(DMI_BOARD_NAME, "AN35"),
1013 MATCH(DMI_BIOS_VERSION, "6.00 PG"),
1014 MATCH(DMI_BIOS_DATE, "12/05/2003") }},
1015 #endif // CONFIG_ACPI_BOOT
1017 #ifdef CONFIG_ACPI_PCI
1019 * Boxes that need ACPI PCI IRQ routing disabled
1022 { disable_acpi_irq, "ASUS A7V", {
1023 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
1024 MATCH(DMI_BOARD_NAME, "<A7V>"),
1025 /* newer BIOS, Revision 1011, does work */
1026 MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
1030 * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
1032 { disable_acpi_pci, "ASUS PR-DLS", { /* _BBN 0 bug */
1033 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1034 MATCH(DMI_BOARD_NAME, "PR-DLS"),
1035 MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
1036 MATCH(DMI_BIOS_DATE, "03/21/2003") }},
1044 * Walk the blacklist table running matching functions until someone
1045 * returns 1 or we hit the end.
1049 static __init void dmi_check_blacklist(void)
1051 struct dmi_blacklist *d;
1054 #ifdef CONFIG_ACPI_BOOT
1055 #define ACPI_BLACKLIST_CUTOFF_YEAR 2001
1057 if (dmi_ident[DMI_BIOS_DATE]) {
1058 char *s = strrchr(dmi_ident[DMI_BIOS_DATE], '/');
1060 int year, disable = 0;
1062 year = simple_strtoul(s,NULL,0);
1064 disable = year < ACPI_BLACKLIST_CUTOFF_YEAR;
1065 else if (year < 1 || (year > 90 && year <= 99))
1067 if (disable && !acpi_force) {
1068 printk(KERN_NOTICE "ACPI disabled because your bios is from %s and too old\n", s);
1069 printk(KERN_NOTICE "You can enable it with acpi=force\n");
1076 d=&dmi_blacklist[0];
1081 int s = d->matches[i].slot;
1084 if(dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
1099 * Process a DMI table entry. Right now all we care about are the BIOS
1100 * and machine entries. For 2.5 we should pull the smbus controller info
1104 static void __init dmi_decode(struct dmi_header *dm)
1107 u8 *data = (u8 *)dm;
1113 dmi_printk(("BIOS Vendor: %s\n",
1114 dmi_string(dm, data[4])));
1115 dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
1116 dmi_printk(("BIOS Version: %s\n",
1117 dmi_string(dm, data[5])));
1118 dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
1119 dmi_printk(("BIOS Release: %s\n",
1120 dmi_string(dm, data[8])));
1121 dmi_save_ident(dm, DMI_BIOS_DATE, 8);
1124 dmi_printk(("System Vendor: %s\n",
1125 dmi_string(dm, data[4])));
1126 dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
1127 dmi_printk(("Product Name: %s\n",
1128 dmi_string(dm, data[5])));
1129 dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
1130 dmi_printk(("Version: %s\n",
1131 dmi_string(dm, data[6])));
1132 dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
1133 dmi_printk(("Serial Number: %s\n",
1134 dmi_string(dm, data[7])));
1137 dmi_printk(("Board Vendor: %s\n",
1138 dmi_string(dm, data[4])));
1139 dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
1140 dmi_printk(("Board Name: %s\n",
1141 dmi_string(dm, data[5])));
1142 dmi_save_ident(dm, DMI_BOARD_NAME, 5);
1143 dmi_printk(("Board Version: %s\n",
1144 dmi_string(dm, data[6])));
1145 dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
1150 void __init dmi_scan_machine(void)
1152 int err = dmi_iterate(dmi_decode);
1154 dmi_check_blacklist();
1156 printk(KERN_INFO "DMI not present.\n");
1159 EXPORT_SYMBOL(is_unsafe_smbus);