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>
11 #include <asm/system.h>
12 #include <linux/bootmem.h>
14 unsigned long dmi_broken;
15 EXPORT_SYMBOL(dmi_broken);
17 int is_sony_vaio_laptop;
30 #define dmi_printk(x) printk x
35 static char * __init dmi_string(struct dmi_header *dm, u8 s)
52 * We have to be cautious here. We have seen BIOSes with DMI pointers
53 * pointing to completely the wrong place for example
56 static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dmi_header *))
59 struct dmi_header *dm;
63 buf = bt_ioremap(base, len);
70 * Stop when we see all the items the table claimed to have
71 * OR we run off the end of the table (also happens)
74 while(i<num && data-buf+sizeof(struct dmi_header)<=len)
76 dm=(struct dmi_header *)data;
78 * We want to know the total length (formated area and strings)
79 * before decoding to make sure we won't run off the table in
80 * dmi_decode or dmi_string
83 while(data-buf<len-1 && (data[0] || data[1]))
95 inline static int __init dmi_checksum(u8 *buf)
105 static int __init dmi_iterate(void (*decode)(struct dmi_header *))
112 * Skip on x86/64 with simnow. Will eventually go away
113 * If you see this ifdef in 2.6pre mail me !
120 isa_memcpy_fromio(buf, fp, 15);
121 if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf))
123 u16 num=buf[13]<<8|buf[12];
124 u16 len=buf[7]<<8|buf[6];
125 u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
128 * DMI version 0.0 means that the real version is taken from
129 * the SMBIOS version, which we don't know at this point.
132 dmi_printk((KERN_INFO "DMI %d.%d present.\n",
133 buf[14]>>4, buf[14]&0x0F));
135 dmi_printk((KERN_INFO "DMI present.\n"));
136 dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
138 dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
140 if(dmi_table(base,len, num, decode)==0)
163 static char *dmi_ident[DMI_STRING_MAX];
169 static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
172 char *p = dmi_string(dm, d[string]);
173 if(p==NULL || *p == 0)
177 dmi_ident[slot] = alloc_bootmem(strlen(p)+1);
179 strcpy(dmi_ident[slot], p);
181 printk(KERN_ERR "dmi_save_ident: out of memory.\n");
185 * DMI callbacks for problem boards
198 int (*callback)(struct dmi_blacklist *);
200 struct dmi_strmatch matches[4];
203 #define NO_MATCH { NONE, NULL}
204 #define MATCH(a,b) { a, b }
207 * Reboot options and system auto-detection code provided by
208 * Dell Computer Corporation so their systems "just work". :-)
212 * Some machines require the "reboot=b" commandline option, this quirk makes that automatic.
214 static __init int set_bios_reboot(struct dmi_blacklist *d)
216 extern int reboot_thru_bios;
217 if (reboot_thru_bios == 0)
219 reboot_thru_bios = 1;
220 printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident);
226 * Some machines require the "reboot=s" commandline option, this quirk makes that automatic.
228 static __init int set_smp_reboot(struct dmi_blacklist *d)
231 extern int reboot_smp;
235 printk(KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n", d->ident);
242 * Some machines require the "reboot=b,s" commandline option, this quirk makes that automatic.
244 static __init int set_smp_bios_reboot(struct dmi_blacklist *d)
252 * Some bioses have a broken protected mode poweroff and need to use realmode
255 static __init int set_realmode_power_off(struct dmi_blacklist *d)
257 if (apm_info.realmode_power_off == 0)
259 apm_info.realmode_power_off = 1;
260 printk(KERN_INFO "%s bios detected. Using realmode poweroff only.\n", d->ident);
267 * Some laptops require interrupts to be enabled during APM calls
270 static __init int set_apm_ints(struct dmi_blacklist *d)
272 if (apm_info.allow_ints == 0)
274 apm_info.allow_ints = 1;
275 printk(KERN_INFO "%s machine detected. Enabling interrupts during APM calls.\n", d->ident);
281 * Some APM bioses corrupt memory or just plain do not work
284 static __init int apm_is_horked(struct dmi_blacklist *d)
286 if (apm_info.disabled == 0)
288 apm_info.disabled = 1;
289 printk(KERN_INFO "%s machine detected. Disabling APM.\n", d->ident);
295 * Some machines, usually laptops, can't handle an enabled local APIC.
296 * The symptoms include hangs or reboots when suspending or resuming,
297 * attaching or detaching the power cord, or entering BIOS setup screens
298 * through magic key sequences.
300 static int __init local_apic_kills_bios(struct dmi_blacklist *d)
302 #ifdef CONFIG_X86_LOCAL_APIC
303 extern int dont_enable_local_apic;
304 if (!dont_enable_local_apic) {
305 dont_enable_local_apic = 1;
306 printk(KERN_WARNING "%s with broken BIOS detected. "
307 "Refusing to enable the local APIC.\n",
315 * Don't access SMBus on IBM systems which get corrupted eeproms
318 static __init int disable_smbus(struct dmi_blacklist *d)
320 if (is_unsafe_smbus == 0) {
322 printk(KERN_INFO "%s machine detected. Disabling SMBus accesses.\n", d->ident);
328 * Work around broken HP Pavilion Notebooks which assign USB to
329 * IRQ 9 even though it is actually wired to IRQ 11
331 static __init int fix_broken_hp_bios_irq9(struct dmi_blacklist *d)
334 extern int broken_hp_bios_irq9;
335 if (broken_hp_bios_irq9 == 0)
337 broken_hp_bios_irq9 = 1;
338 printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident);
345 * Check for clue free BIOS implementations who use
346 * the following QA technique
348 * [ Write BIOS Code ]<------
350 * < Does it Compile >----N--
352 * < Does it Boot Win98 >-N--
356 * Phoenix A04 08/24/2000 is known bad (Dell Inspiron 5000e)
357 * Phoenix A07 09/29/2000 is known good (Dell Inspiron 5000)
360 static __init int broken_apm_power(struct dmi_blacklist *d)
362 apm_info.get_power_status_broken = 1;
363 printk(KERN_WARNING "BIOS strings suggest APM bugs, disabling power status reporting.\n");
368 * Check for a Sony Vaio system
370 * On a Sony system we want to enable the use of the sonypi
371 * driver for Sony-specific goodies like the camera and jogdial.
372 * We also want to avoid using certain functions of the PnP BIOS.
375 static __init int sony_vaio_laptop(struct dmi_blacklist *d)
377 if (is_sony_vaio_laptop == 0)
379 is_sony_vaio_laptop = 1;
380 printk(KERN_INFO "%s laptop detected.\n", d->ident);
386 * This bios swaps the APM minute reporting bytes over (Many sony laptops
387 * have this problem).
390 static __init int swab_apm_power_in_minutes(struct dmi_blacklist *d)
392 apm_info.get_power_status_swabinminutes = 1;
393 printk(KERN_WARNING "BIOS strings suggest APM reports battery life in minutes and wrong byte order.\n");
398 * The Intel 440GX hall of shame.
400 * On many (all we have checked) of these boxes the $PIRQ table is wrong.
401 * The MP1.4 table is right however and so SMP kernels tend to work.
404 extern int skip_ioapic_setup;
405 static __init int broken_pirq(struct dmi_blacklist *d)
407 printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n");
408 printk(KERN_INFO " *** Many BIOSes matching this signature have incorrect IRQ routing tables.\n");
409 printk(KERN_INFO " *** If you see IRQ problems, in particular SCSI resets and hangs at boot\n");
410 printk(KERN_INFO " *** contact your hardware vendor and ask about updates.\n");
411 printk(KERN_INFO " *** Building an SMP kernel may evade the bug some of the time.\n");
412 #ifdef CONFIG_X86_IO_APIC
413 skip_ioapic_setup = 0;
419 * Toshiba keyboard likes to repeat keys when they are not repeated.
422 static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
424 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");
429 * Toshiba fails to preserve interrupts over S1
432 static __init int init_ints_after_s1(struct dmi_blacklist *d)
434 printk(KERN_WARNING "Toshiba with broken S1 detected.\n");
435 dmi_broken |= BROKEN_INIT_AFTER_S1;
439 #ifdef CONFIG_ACPI_SLEEP
440 static __init int reset_videomode_after_s3(struct dmi_blacklist *d)
442 /* See acpi_wakeup.S */
443 extern long acpi_video_flags;
444 acpi_video_flags |= 2;
448 static __init int reset_videobios_after_s3(struct dmi_blacklist *d)
450 extern long acpi_video_flags;
451 acpi_video_flags |= 1;
457 * Some Bioses enable the PS/2 mouse (touchpad) at resume, even if it was
458 * disabled before the suspend. Linux used to get terribly confused by that.
461 static __init int broken_ps2_resume(struct dmi_blacklist *d)
463 printk(KERN_INFO "%s machine detected. Mousepad Resume Bug workaround hopefully not needed.\n", d->ident);
468 * Exploding PnPBIOS. Don't yet know if its the BIOS or us for
472 static __init int exploding_pnp_bios(struct dmi_blacklist *d)
474 printk(KERN_WARNING "%s detected. Disabling PnPBIOS\n", d->ident);
475 dmi_broken |= BROKEN_PNP_BIOS;
479 static __init int acer_cpufreq_pst(struct dmi_blacklist *d)
481 printk(KERN_WARNING "%s laptop with broken PST tables in BIOS detected.\n", d->ident);
482 printk(KERN_WARNING "You need to downgrade to 3A21 (09/09/2002), or try a newer BIOS than 3A71 (01/20/2003)\n");
483 printk(KERN_WARNING "cpufreq scaling has been disabled as a result of this.\n");
484 dmi_broken |= BROKEN_CPUFREQ;
490 * Simple "print if true" callback
493 static __init int print_if_true(struct dmi_blacklist *d)
495 printk("%s\n", d->ident);
500 * Process the DMI blacklists
505 * This will be expanded over time to force things like the APM
506 * interrupt mask settings according to the laptop
509 static __initdata struct dmi_blacklist dmi_blacklist[]={
510 { broken_ps2_resume, "Dell Latitude C600", { /* Handle problems with APM on the C600 */
511 MATCH(DMI_SYS_VENDOR, "Dell"),
512 MATCH(DMI_PRODUCT_NAME, "Latitude C600"),
515 { broken_apm_power, "Dell Inspiron 5000e", { /* Handle problems with APM on Inspiron 5000e */
516 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
517 MATCH(DMI_BIOS_VERSION, "A04"),
518 MATCH(DMI_BIOS_DATE, "08/24/2000"), NO_MATCH
520 { broken_apm_power, "Dell Inspiron 2500", { /* Handle problems with APM on Inspiron 2500 */
521 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
522 MATCH(DMI_BIOS_VERSION, "A12"),
523 MATCH(DMI_BIOS_DATE, "02/04/2002"), NO_MATCH
525 { set_realmode_power_off, "Award Software v4.60 PGMA", { /* broken PM poweroff bios */
526 MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
527 MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
528 MATCH(DMI_BIOS_DATE, "134526184"), NO_MATCH
530 { set_smp_bios_reboot, "Dell PowerEdge 1300", { /* Handle problems with rebooting on Dell 1300's */
531 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
532 MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"),
535 { set_bios_reboot, "Dell PowerEdge 300", { /* Handle problems with rebooting on Dell 1300's */
536 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
537 MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
540 { set_bios_reboot, "Dell PowerEdge 2400", { /* Handle problems with rebooting on Dell 300/800's */
541 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
542 MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
545 { set_apm_ints, "Dell Inspiron", { /* Allow interrupts during suspend on Dell Inspiron laptops*/
546 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
547 MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"),
550 { set_apm_ints, "Compaq 12XL125", { /* Allow interrupts during suspend on Compaq Laptops*/
551 MATCH(DMI_SYS_VENDOR, "Compaq"),
552 MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
553 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
554 MATCH(DMI_BIOS_VERSION,"4.06")
556 { set_apm_ints, "ASUSTeK", { /* Allow interrupts during APM or the clock goes slow */
557 MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
558 MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"),
561 { apm_is_horked, "Trigem Delhi3", { /* APM crashes */
562 MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
563 MATCH(DMI_PRODUCT_NAME, "Delhi3"),
566 { apm_is_horked, "Fujitsu-Siemens", { /* APM crashes */
567 MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"),
568 MATCH(DMI_BIOS_VERSION, "Version1.01"),
571 { apm_is_horked, "Intel D850MD", { /* APM crashes */
572 MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
573 MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"),
576 { apm_is_horked, "Intel D810EMO", { /* APM crashes */
577 MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
578 MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"),
581 { apm_is_horked, "Dell XPS-Z", { /* APM crashes */
582 MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
583 MATCH(DMI_BIOS_VERSION, "A11"),
584 MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
587 { apm_is_horked, "Sharp PC-PJ/AX", { /* APM crashes */
588 MATCH(DMI_SYS_VENDOR, "SHARP"),
589 MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
590 MATCH(DMI_BIOS_VENDOR,"SystemSoft"),
591 MATCH(DMI_BIOS_VERSION,"Version R2.08")
593 { apm_is_horked, "Dell Inspiron 2500", { /* APM crashes */
594 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
595 MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
596 MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
597 MATCH(DMI_BIOS_VERSION,"A11")
599 { sony_vaio_laptop, "Sony Vaio", { /* This is a Sony Vaio laptop */
600 MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
601 MATCH(DMI_PRODUCT_NAME, "PCG-"),
604 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
605 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
606 MATCH(DMI_BIOS_VERSION, "R0206H"),
607 MATCH(DMI_BIOS_DATE, "08/23/99"), NO_MATCH
610 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-N505VX */
611 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
612 MATCH(DMI_BIOS_VERSION, "W2K06H0"),
613 MATCH(DMI_BIOS_DATE, "02/03/00"), NO_MATCH
616 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-XG29 */
617 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
618 MATCH(DMI_BIOS_VERSION, "R0117A0"),
619 MATCH(DMI_BIOS_DATE, "04/25/00"), NO_MATCH
622 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
623 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
624 MATCH(DMI_BIOS_VERSION, "R0121Z1"),
625 MATCH(DMI_BIOS_DATE, "05/11/00"), NO_MATCH
628 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
629 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
630 MATCH(DMI_BIOS_VERSION, "WME01Z1"),
631 MATCH(DMI_BIOS_DATE, "08/11/00"), NO_MATCH
634 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
635 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
636 MATCH(DMI_BIOS_VERSION, "R0206Z3"),
637 MATCH(DMI_BIOS_DATE, "12/25/00"), NO_MATCH
640 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
641 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
642 MATCH(DMI_BIOS_VERSION, "R0203D0"),
643 MATCH(DMI_BIOS_DATE, "05/12/00"), NO_MATCH
646 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
647 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
648 MATCH(DMI_BIOS_VERSION, "R0203Z3"),
649 MATCH(DMI_BIOS_DATE, "08/25/00"), NO_MATCH
652 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
653 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
654 MATCH(DMI_BIOS_VERSION, "R0209Z3"),
655 MATCH(DMI_BIOS_DATE, "05/12/01"), NO_MATCH
658 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-F104K */
659 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
660 MATCH(DMI_BIOS_VERSION, "R0204K2"),
661 MATCH(DMI_BIOS_DATE, "08/28/00"), NO_MATCH
664 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */
665 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
666 MATCH(DMI_BIOS_VERSION, "R0208P1"),
667 MATCH(DMI_BIOS_DATE, "11/09/00"), NO_MATCH
670 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-C1VE */
671 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
672 MATCH(DMI_BIOS_VERSION, "R0204P1"),
673 MATCH(DMI_BIOS_DATE, "09/12/00"), NO_MATCH
676 { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-C1VE */
677 MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
678 MATCH(DMI_BIOS_VERSION, "WXPO1Z3"),
679 MATCH(DMI_BIOS_DATE, "10/26/01"), NO_MATCH
682 { exploding_pnp_bios, "Higraded P14H", { /* BIOSPnP problem */
683 MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
684 MATCH(DMI_BIOS_VERSION, "07.00T"),
685 MATCH(DMI_SYS_VENDOR, "Higraded"),
686 MATCH(DMI_PRODUCT_NAME, "P14H")
689 /* Machines which have problems handling enabled local APICs */
691 { local_apic_kills_bios, "Dell Inspiron", {
692 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
693 MATCH(DMI_PRODUCT_NAME, "Inspiron"),
697 { local_apic_kills_bios, "Dell Latitude", {
698 MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
699 MATCH(DMI_PRODUCT_NAME, "Latitude"),
703 { local_apic_kills_bios, "IBM Thinkpad T20", {
704 MATCH(DMI_BOARD_VENDOR, "IBM"),
705 MATCH(DMI_BOARD_NAME, "264741U"),
709 /* Problem Intel 440GX bioses */
711 { broken_pirq, "SABR1 Bios", { /* Bad $PIR */
712 MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
713 MATCH(DMI_BIOS_VERSION,"SABR1"),
716 { broken_pirq, "l44GX Bios", { /* Bad $PIR */
717 MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
718 MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0094.P10"),
721 { broken_pirq, "l44GX Bios", { /* Bad $PIR */
722 MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
723 MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0120.P12"),
726 { broken_pirq, "l44GX Bios", { /* Bad $PIR */
727 MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
728 MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0125.P13"),
731 { broken_pirq, "l44GX Bios", { /* Bad $PIR */
732 MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
733 MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0066.P07.9906041405"),
737 /* Intel in disguise - In this case they can't hide and they don't run
738 too well either... */
739 { broken_pirq, "Dell PowerEdge 8450", { /* Bad $PIR */
740 MATCH(DMI_PRODUCT_NAME, "Dell PowerEdge 8450"),
741 NO_MATCH, NO_MATCH, NO_MATCH
744 { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */
745 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
746 NO_MATCH, NO_MATCH, NO_MATCH
748 { init_ints_after_s1, "Toshiba Satellite 4030cdt", { /* Reinitialization of 8259 is needed after S1 resume */
749 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
750 NO_MATCH, NO_MATCH, NO_MATCH
752 #ifdef CONFIG_ACPI_SLEEP
753 { reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */
754 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
755 NO_MATCH, NO_MATCH, NO_MATCH
759 { print_if_true, KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.", {
760 MATCH(DMI_SYS_VENDOR, "IBM"),
761 MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"),
765 { fix_broken_hp_bios_irq9, "HP Pavilion N5400 Series Laptop", {
766 MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
767 MATCH(DMI_BIOS_VERSION, "GE.M1.03"),
768 MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"),
769 MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736")
774 * Generic per vendor APM settings
777 { set_apm_ints, "IBM", { /* Allow interrupts during suspend on IBM laptops */
778 MATCH(DMI_SYS_VENDOR, "IBM"),
779 NO_MATCH, NO_MATCH, NO_MATCH
783 * SMBus / sensors settings
786 { disable_smbus, "IBM", {
787 MATCH(DMI_SYS_VENDOR, "IBM"),
788 NO_MATCH, NO_MATCH, NO_MATCH
792 * Some Athlon laptops have really fucked PST tables.
793 * A BIOS update is all that can save them.
794 * Mention this, and disable cpufreq.
796 { acer_cpufreq_pst, "Acer Aspire", {
797 MATCH(DMI_SYS_VENDOR, "Insyde Software"),
798 MATCH(DMI_BIOS_VERSION, "3A71"),
807 * Walk the blacklist table running matching functions until someone
808 * returns 1 or we hit the end.
811 static __init void dmi_check_blacklist(void)
813 struct dmi_blacklist *d;
821 int s = d->matches[i].slot;
824 if(dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
839 * Process a DMI table entry. Right now all we care about are the BIOS
840 * and machine entries. For 2.5 we should pull the smbus controller info
844 static void __init dmi_decode(struct dmi_header *dm)
853 dmi_printk(("BIOS Vendor: %s\n",
854 dmi_string(dm, data[4])));
855 dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
856 dmi_printk(("BIOS Version: %s\n",
857 dmi_string(dm, data[5])));
858 dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
859 dmi_printk(("BIOS Release: %s\n",
860 dmi_string(dm, data[8])));
861 dmi_save_ident(dm, DMI_BIOS_DATE, 8);
864 dmi_printk(("System Vendor: %s\n",
865 dmi_string(dm, data[4])));
866 dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
867 dmi_printk(("Product Name: %s\n",
868 dmi_string(dm, data[5])));
869 dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
870 dmi_printk(("Version: %s\n",
871 dmi_string(dm, data[6])));
872 dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
873 dmi_printk(("Serial Number: %s\n",
874 dmi_string(dm, data[7])));
877 dmi_printk(("Board Vendor: %s\n",
878 dmi_string(dm, data[4])));
879 dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
880 dmi_printk(("Board Name: %s\n",
881 dmi_string(dm, data[5])));
882 dmi_save_ident(dm, DMI_BOARD_NAME, 5);
883 dmi_printk(("Board Version: %s\n",
884 dmi_string(dm, data[6])));
885 dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
890 void __init dmi_scan_machine(void)
892 int err = dmi_iterate(dmi_decode);
894 dmi_check_blacklist();
897 EXPORT_SYMBOL(is_unsafe_smbus);