Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6595 serge 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
 *  Check given machine against acpi_osi_dmi_table[].
7
 *
8
 *  Copyright (C) 2004 Len Brown 
9
 *  Copyright (C) 2002 Andy Grover 
10
 *
11
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12
 *
13
 *  This program is free software; you can redistribute it and/or modify
14
 *  it under the terms of the GNU General Public License as published by
15
 *  the Free Software Foundation; either version 2 of the License, or (at
16
 *  your option) any later version.
17
 *
18
 *  This program is distributed in the hope that it will be useful, but
19
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
20
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21
 *  General Public License for more details.
22
 *
23
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24
 */
25
 
26
#include 
27
#include 
28
#include 
29
#include 
30
 
31
#include "internal.h"
32
 
33
enum acpi_blacklist_predicates {
34
	all_versions,
35
	less_than_or_equal,
36
	equal,
37
	greater_than_or_equal,
38
};
39
 
40
struct acpi_blacklist_item {
41
	char oem_id[7];
42
	char oem_table_id[9];
43
	u32 oem_revision;
44
	char *table;
45
	enum acpi_blacklist_predicates oem_revision_predicate;
46
	char *reason;
47
	u32 is_critical_error;
48
};
49
 
50
static struct dmi_system_id acpi_osi_dmi_table[] __initdata;
51
 
52
/*
53
 * POLICY: If *anything* doesn't work, put it on the blacklist.
54
 *	   If they are critical errors, mark it critical, and abort driver load.
55
 */
56
static struct acpi_blacklist_item acpi_blacklist[] __initdata = {
57
	/* Compaq Presario 1700 */
58
	{"PTLTD ", "  DSDT  ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal,
59
	 "Multiple problems", 1},
60
	/* Sony FX120, FX140, FX150? */
61
	{"SONY  ", "U0      ", 0x20010313, ACPI_SIG_DSDT, less_than_or_equal,
62
	 "ACPI driver problem", 1},
63
	/* Compaq Presario 800, Insyde BIOS */
64
	{"INT440", "SYSFexxx", 0x00001001, ACPI_SIG_DSDT, less_than_or_equal,
65
	 "Does not use _REG to protect EC OpRegions", 1},
66
	/* IBM 600E - _ADR should return 7, but it returns 1 */
67
	{"IBM   ", "TP600E  ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
68
	 "Incorrect _ADR", 1},
69
 
70
	{""}
71
};
72
 
73
int __init acpi_blacklisted(void)
74
{
75
	int i = 0;
76
	int blacklisted = 0;
77
	struct acpi_table_header table_header;
78
 
79
	while (acpi_blacklist[i].oem_id[0] != '\0') {
80
		if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) {
81
			i++;
82
			continue;
83
		}
84
 
85
		if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) {
86
			i++;
87
			continue;
88
		}
89
 
90
		if (strncmp
91
		    (acpi_blacklist[i].oem_table_id, table_header.oem_table_id,
92
		     8)) {
93
			i++;
94
			continue;
95
		}
96
 
97
		if ((acpi_blacklist[i].oem_revision_predicate == all_versions)
98
		    || (acpi_blacklist[i].oem_revision_predicate ==
99
			less_than_or_equal
100
			&& table_header.oem_revision <=
101
			acpi_blacklist[i].oem_revision)
102
		    || (acpi_blacklist[i].oem_revision_predicate ==
103
			greater_than_or_equal
104
			&& table_header.oem_revision >=
105
			acpi_blacklist[i].oem_revision)
106
		    || (acpi_blacklist[i].oem_revision_predicate == equal
107
			&& table_header.oem_revision ==
108
			acpi_blacklist[i].oem_revision)) {
109
 
110
			printk(KERN_ERR PREFIX
111
			       "Vendor \"%6.6s\" System \"%8.8s\" "
112
			       "Revision 0x%x has a known ACPI BIOS problem.\n",
113
			       acpi_blacklist[i].oem_id,
114
			       acpi_blacklist[i].oem_table_id,
115
			       acpi_blacklist[i].oem_revision);
116
 
117
			printk(KERN_ERR PREFIX
118
			       "Reason: %s. This is a %s error\n",
119
			       acpi_blacklist[i].reason,
120
			       (acpi_blacklist[i].
121
				is_critical_error ? "non-recoverable" :
122
				"recoverable"));
123
 
124
			blacklisted = acpi_blacklist[i].is_critical_error;
125
			break;
126
		} else {
127
			i++;
128
		}
129
	}
130
 
131
	dmi_check_system(acpi_osi_dmi_table);
132
 
133
	return blacklisted;
134
}
135
#ifdef CONFIG_DMI
136
static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
137
{
138
	acpi_dmi_osi_linux(1, d);	/* enable */
139
	return 0;
140
}
141
static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
142
{
143
	printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
144
	acpi_osi_setup("!Windows 2006");
145
	acpi_osi_setup("!Windows 2006 SP1");
146
	acpi_osi_setup("!Windows 2006 SP2");
147
	return 0;
148
}
149
static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
150
{
151
	printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
152
	acpi_osi_setup("!Windows 2009");
153
	return 0;
154
}
155
static int __init dmi_disable_osi_win8(const struct dmi_system_id *d)
156
{
157
	printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
158
	acpi_osi_setup("!Windows 2012");
159
	return 0;
160
}
161
#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
162
static int __init dmi_enable_rev_override(const struct dmi_system_id *d)
163
{
164
	printk(KERN_NOTICE PREFIX "DMI detected: %s (force ACPI _REV to 5)\n",
165
	       d->ident);
166
	acpi_rev_override_setup(NULL);
167
	return 0;
168
}
169
#endif
170
 
171
static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
172
	{
173
	.callback = dmi_disable_osi_vista,
174
	.ident = "Fujitsu Siemens",
175
	.matches = {
176
		     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
177
		     DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
178
		},
179
	},
180
	{
181
	/*
182
	 * There have a NVIF method in MSI GX723 DSDT need call by Nvidia
183
	 * driver (e.g. nouveau) when user press brightness hotkey.
184
	 * Currently, nouveau driver didn't do the job and it causes there
185
	 * have a infinite while loop in DSDT when user press hotkey.
186
	 * We add MSI GX723's dmi information to this table for workaround
187
	 * this issue.
188
	 * Will remove MSI GX723 from the table after nouveau grows support.
189
	 */
190
	.callback = dmi_disable_osi_vista,
191
	.ident = "MSI GX723",
192
	.matches = {
193
		     DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
194
		     DMI_MATCH(DMI_PRODUCT_NAME, "GX723"),
195
		},
196
	},
197
	{
198
	.callback = dmi_disable_osi_vista,
199
	.ident = "Sony VGN-NS10J_S",
200
	.matches = {
201
		     DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
202
		     DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"),
203
		},
204
	},
205
	{
206
	.callback = dmi_disable_osi_vista,
207
	.ident = "Sony VGN-SR290J",
208
	.matches = {
209
		     DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
210
		     DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"),
211
		},
212
	},
213
	{
214
	.callback = dmi_disable_osi_vista,
215
	.ident = "VGN-NS50B_L",
216
	.matches = {
217
		     DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
218
		     DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"),
219
		},
220
	},
221
	{
222
	.callback = dmi_disable_osi_vista,
223
	.ident = "VGN-SR19XN",
224
	.matches = {
225
		     DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
226
		     DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"),
227
		},
228
	},
229
	{
230
	.callback = dmi_disable_osi_vista,
231
	.ident = "Toshiba Satellite L355",
232
	.matches = {
233
		     DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
234
		     DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"),
235
		},
236
	},
237
	{
238
	.callback = dmi_disable_osi_win7,
239
	.ident = "ASUS K50IJ",
240
	.matches = {
241
		     DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
242
		     DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"),
243
		},
244
	},
245
	{
246
	.callback = dmi_disable_osi_vista,
247
	.ident = "Toshiba P305D",
248
	.matches = {
249
		     DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
250
		     DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"),
251
		},
252
	},
253
	{
254
	.callback = dmi_disable_osi_vista,
255
	.ident = "Toshiba NB100",
256
	.matches = {
257
		     DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
258
		     DMI_MATCH(DMI_PRODUCT_NAME, "NB100"),
259
		},
260
	},
261
 
262
	/*
263
	 * The wireless hotkey does not work on those machines when
264
	 * returning true for _OSI("Windows 2012")
265
	 */
266
	{
267
	.callback = dmi_disable_osi_win8,
268
	.ident = "Dell Inspiron 7737",
269
	.matches = {
270
		    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
271
		    DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"),
272
		},
273
	},
274
	{
275
	.callback = dmi_disable_osi_win8,
276
	.ident = "Dell Inspiron 7537",
277
	.matches = {
278
		    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
279
		    DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"),
280
		},
281
	},
282
	{
283
	.callback = dmi_disable_osi_win8,
284
	.ident = "Dell Inspiron 5437",
285
	.matches = {
286
		    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
287
		    DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"),
288
		},
289
	},
290
	{
291
	.callback = dmi_disable_osi_win8,
292
	.ident = "Dell Inspiron 3437",
293
	.matches = {
294
		    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
295
		    DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"),
296
		},
297
	},
298
	{
299
	.callback = dmi_disable_osi_win8,
300
	.ident = "Dell Vostro 3446",
301
	.matches = {
302
		    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
303
		    DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"),
304
		},
305
	},
306
	{
307
	.callback = dmi_disable_osi_win8,
308
	.ident = "Dell Vostro 3546",
309
	.matches = {
310
		    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
311
		    DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"),
312
		},
313
	},
314
 
315
	/*
316
	 * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
317
	 * Linux ignores it, except for the machines enumerated below.
318
	 */
319
 
320
	/*
321
	 * Without this this EEEpc exports a non working WMI interface, with
322
	 * this it exports a working "good old" eeepc_laptop interface, fixing
323
	 * both brightness control, and rfkill not working.
324
	 */
325
	{
326
	.callback = dmi_enable_osi_linux,
327
	.ident = "Asus EEE PC 1015PX",
328
	.matches = {
329
		     DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
330
		     DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"),
331
		},
332
	},
333
 
334
#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
335
	/*
336
	 * DELL XPS 13 (2015) switches sound between HDA and I2S
337
	 * depending on the ACPI _REV callback. If userspace supports
338
	 * I2S sufficiently (or if you do not care about sound), you
339
	 * can safely disable this quirk.
340
	 */
341
	{
342
	 .callback = dmi_enable_rev_override,
343
	 .ident = "DELL XPS 13 (2015)",
344
	 .matches = {
345
		      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
346
		      DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"),
347
		},
348
	},
349
#endif
350
	{}
351
};
352
 
353
#endif /* CONFIG_DMI */