1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * blacklist.c |
4 | * |
5 | * Check to see if the given machine has a known bad ACPI BIOS |
6 | * or if the BIOS is too old. |
7 | * Check given machine against acpi_rev_dmi_table[]. |
8 | * |
9 | * Copyright (C) 2004 Len Brown <len.brown@intel.com> |
10 | * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com> |
11 | */ |
12 | |
13 | #define pr_fmt(fmt) "ACPI: " fmt |
14 | |
15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> |
17 | #include <linux/acpi.h> |
18 | #include <linux/dmi.h> |
19 | |
20 | #include "internal.h" |
21 | |
22 | #ifdef CONFIG_DMI |
23 | static const struct dmi_system_id acpi_rev_dmi_table[] __initconst; |
24 | #endif |
25 | |
26 | /* |
27 | * POLICY: If *anything* doesn't work, put it on the blacklist. |
28 | * If they are critical errors, mark it critical, and abort driver load. |
29 | */ |
30 | static struct acpi_platform_list acpi_blacklist[] __initdata = { |
31 | /* Compaq Presario 1700 */ |
32 | {"PTLTD " , " DSDT " , 0x06040000, ACPI_SIG_DSDT, less_than_or_equal, |
33 | "Multiple problems" , 1}, |
34 | /* Sony FX120, FX140, FX150? */ |
35 | {"SONY " , "U0 " , 0x20010313, ACPI_SIG_DSDT, less_than_or_equal, |
36 | "ACPI driver problem" , 1}, |
37 | /* Compaq Presario 800, Insyde BIOS */ |
38 | {"INT440" , "SYSFexxx" , 0x00001001, ACPI_SIG_DSDT, less_than_or_equal, |
39 | "Does not use _REG to protect EC OpRegions" , 1}, |
40 | /* IBM 600E - _ADR should return 7, but it returns 1 */ |
41 | {"IBM " , "TP600E " , 0x00000105, ACPI_SIG_DSDT, less_than_or_equal, |
42 | "Incorrect _ADR" , 1}, |
43 | |
44 | { } |
45 | }; |
46 | |
47 | int __init acpi_blacklisted(void) |
48 | { |
49 | int i; |
50 | int blacklisted = 0; |
51 | |
52 | i = acpi_match_platform_list(plat: acpi_blacklist); |
53 | if (i >= 0) { |
54 | pr_err("Vendor \"%6.6s\" System \"%8.8s\" Revision 0x%x has a known ACPI BIOS problem.\n" , |
55 | acpi_blacklist[i].oem_id, |
56 | acpi_blacklist[i].oem_table_id, |
57 | acpi_blacklist[i].oem_revision); |
58 | |
59 | pr_err("Reason: %s. This is a %s error\n" , |
60 | acpi_blacklist[i].reason, |
61 | (acpi_blacklist[i].data ? |
62 | "non-recoverable" : "recoverable" )); |
63 | |
64 | blacklisted = acpi_blacklist[i].data; |
65 | } |
66 | |
67 | (void)early_acpi_osi_init(); |
68 | #ifdef CONFIG_DMI |
69 | dmi_check_system(list: acpi_rev_dmi_table); |
70 | #endif |
71 | |
72 | return blacklisted; |
73 | } |
74 | #ifdef CONFIG_DMI |
75 | #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE |
76 | static int __init dmi_enable_rev_override(const struct dmi_system_id *d) |
77 | { |
78 | pr_notice("DMI detected: %s (force ACPI _REV to 5)\n" , d->ident); |
79 | acpi_rev_override_setup(NULL); |
80 | return 0; |
81 | } |
82 | #endif |
83 | |
84 | static const struct dmi_system_id acpi_rev_dmi_table[] __initconst = { |
85 | #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE |
86 | /* |
87 | * DELL XPS 13 (2015) switches sound between HDA and I2S |
88 | * depending on the ACPI _REV callback. If userspace supports |
89 | * I2S sufficiently (or if you do not care about sound), you |
90 | * can safely disable this quirk. |
91 | */ |
92 | { |
93 | .callback = dmi_enable_rev_override, |
94 | .ident = "DELL XPS 13 (2015)" , |
95 | .matches = { |
96 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
97 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343" ), |
98 | }, |
99 | }, |
100 | { |
101 | .callback = dmi_enable_rev_override, |
102 | .ident = "DELL Precision 5520" , |
103 | .matches = { |
104 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
105 | DMI_MATCH(DMI_PRODUCT_NAME, "Precision 5520" ), |
106 | }, |
107 | }, |
108 | { |
109 | .callback = dmi_enable_rev_override, |
110 | .ident = "DELL Precision 3520" , |
111 | .matches = { |
112 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
113 | DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3520" ), |
114 | }, |
115 | }, |
116 | /* |
117 | * Resolves a quirk with the Dell Latitude 3350 that |
118 | * causes the ethernet adapter to not function. |
119 | */ |
120 | { |
121 | .callback = dmi_enable_rev_override, |
122 | .ident = "DELL Latitude 3350" , |
123 | .matches = { |
124 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
125 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3350" ), |
126 | }, |
127 | }, |
128 | { |
129 | .callback = dmi_enable_rev_override, |
130 | .ident = "DELL Inspiron 7537" , |
131 | .matches = { |
132 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
133 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537" ), |
134 | }, |
135 | }, |
136 | #endif |
137 | {} |
138 | }; |
139 | |
140 | #endif /* CONFIG_DMI */ |
141 | |