1 /* 2 * blacklist.c 3 * 4 * Check to see if the given machine has a known bad ACPI BIOS 5 * or if the BIOS is too old. 6 * 7 * Copyright (C) 2004 Len Brown <len.brown@intel.com> 8 * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com> 9 * 10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or (at 15 * your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, but 18 * WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 * General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License along 23 * with this program; if not, write to the Free Software Foundation, Inc., 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 25 * 26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 27 */ 28 29 #include <linux/kernel.h> 30 #include <linux/module.h> 31 #include <linux/init.h> 32 #include <linux/acpi.h> 33 #include <acpi/acpi_bus.h> 34 #include <linux/dmi.h> 35 36 enum acpi_blacklist_predicates { 37 all_versions, 38 less_than_or_equal, 39 equal, 40 greater_than_or_equal, 41 }; 42 43 struct acpi_blacklist_item { 44 char oem_id[7]; 45 char oem_table_id[9]; 46 u32 oem_revision; 47 char *table; 48 enum acpi_blacklist_predicates oem_revision_predicate; 49 char *reason; 50 u32 is_critical_error; 51 }; 52 53 /* 54 * POLICY: If *anything* doesn't work, put it on the blacklist. 55 * If they are critical errors, mark it critical, and abort driver load. 56 */ 57 static struct acpi_blacklist_item acpi_blacklist[] __initdata = { 58 /* Compaq Presario 1700 */ 59 {"PTLTD ", " DSDT ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal, 60 "Multiple problems", 1}, 61 /* Sony FX120, FX140, FX150? */ 62 {"SONY ", "U0 ", 0x20010313, ACPI_SIG_DSDT, less_than_or_equal, 63 "ACPI driver problem", 1}, 64 /* Compaq Presario 800, Insyde BIOS */ 65 {"INT440", "SYSFexxx", 0x00001001, ACPI_SIG_DSDT, less_than_or_equal, 66 "Does not use _REG to protect EC OpRegions", 1}, 67 /* IBM 600E - _ADR should return 7, but it returns 1 */ 68 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal, 69 "Incorrect _ADR", 1}, 70 {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions, 71 "Bogus PCI routing", 1}, 72 73 {""} 74 }; 75 76 #if CONFIG_ACPI_BLACKLIST_YEAR 77 78 static int __init blacklist_by_year(void) 79 { 80 int year = dmi_get_year(DMI_BIOS_DATE); 81 /* Doesn't exist? Likely an old system */ 82 if (year == -1) { 83 printk(KERN_ERR PREFIX "no DMI BIOS year, " 84 "acpi=force is required to enable ACPI\n" ); 85 return 1; 86 } 87 /* 0? Likely a buggy new BIOS */ 88 if (year == 0) { 89 printk(KERN_ERR PREFIX "DMI BIOS year==0, " 90 "assuming ACPI-capable machine\n" ); 91 return 0; 92 } 93 if (year < CONFIG_ACPI_BLACKLIST_YEAR) { 94 printk(KERN_ERR PREFIX "BIOS age (%d) fails cutoff (%d), " 95 "acpi=force is required to enable ACPI\n", 96 year, CONFIG_ACPI_BLACKLIST_YEAR); 97 return 1; 98 } 99 return 0; 100 } 101 #else 102 static inline int blacklist_by_year(void) 103 { 104 return 0; 105 } 106 #endif 107 108 int __init acpi_blacklisted(void) 109 { 110 int i = 0; 111 int blacklisted = 0; 112 struct acpi_table_header table_header; 113 114 while (acpi_blacklist[i].oem_id[0] != '\0') { 115 if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) { 116 i++; 117 continue; 118 } 119 120 if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) { 121 i++; 122 continue; 123 } 124 125 if (strncmp 126 (acpi_blacklist[i].oem_table_id, table_header.oem_table_id, 127 8)) { 128 i++; 129 continue; 130 } 131 132 if ((acpi_blacklist[i].oem_revision_predicate == all_versions) 133 || (acpi_blacklist[i].oem_revision_predicate == 134 less_than_or_equal 135 && table_header.oem_revision <= 136 acpi_blacklist[i].oem_revision) 137 || (acpi_blacklist[i].oem_revision_predicate == 138 greater_than_or_equal 139 && table_header.oem_revision >= 140 acpi_blacklist[i].oem_revision) 141 || (acpi_blacklist[i].oem_revision_predicate == equal 142 && table_header.oem_revision == 143 acpi_blacklist[i].oem_revision)) { 144 145 printk(KERN_ERR PREFIX 146 "Vendor \"%6.6s\" System \"%8.8s\" " 147 "Revision 0x%x has a known ACPI BIOS problem.\n", 148 acpi_blacklist[i].oem_id, 149 acpi_blacklist[i].oem_table_id, 150 acpi_blacklist[i].oem_revision); 151 152 printk(KERN_ERR PREFIX 153 "Reason: %s. This is a %s error\n", 154 acpi_blacklist[i].reason, 155 (acpi_blacklist[i]. 156 is_critical_error ? "non-recoverable" : 157 "recoverable")); 158 159 blacklisted = acpi_blacklist[i].is_critical_error; 160 break; 161 } else { 162 i++; 163 } 164 } 165 166 blacklisted += blacklist_by_year(); 167 168 return blacklisted; 169 } 170