diff options
author | Len Brown <len.brown@intel.com> | 2008-01-23 23:50:01 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-01-23 23:50:01 -0500 |
commit | 63eac9badbe35054c0ae61a9dbcf4830c7429040 (patch) | |
tree | 2bea2d6df5f2dc9306c9fc17c8755ed3c56d4a12 | |
parent | 3645ca8359328ea4c75bce4af54ad24028381f30 (diff) | |
parent | a1bd4e35e8d9df24db7d7addd74cbfcc87ec9fb3 (diff) |
Pull dmi-2.6.24 into release branch
-rw-r--r-- | drivers/acpi/blacklist.c | 381 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 173 | ||||
-rw-r--r-- | drivers/firmware/dmi-id.c | 2 | ||||
-rw-r--r-- | drivers/firmware/dmi_scan.c | 8 | ||||
-rw-r--r-- | include/linux/acpi.h | 7 | ||||
-rw-r--r-- | include/linux/dmi.h | 4 |
6 files changed, 528 insertions, 47 deletions
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 3ec110ce00c8..8809654d6cc9 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Check to see if the given machine has a known bad ACPI BIOS | 4 | * Check to see if the given machine has a known bad ACPI BIOS |
5 | * or if the BIOS is too old. | 5 | * or if the BIOS is too old. |
6 | * Check given machine against acpi_osi_dmi_table[]. | ||
6 | * | 7 | * |
7 | * Copyright (C) 2004 Len Brown <len.brown@intel.com> | 8 | * Copyright (C) 2004 Len Brown <len.brown@intel.com> |
8 | * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com> | 9 | * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com> |
@@ -50,6 +51,8 @@ struct acpi_blacklist_item { | |||
50 | u32 is_critical_error; | 51 | u32 is_critical_error; |
51 | }; | 52 | }; |
52 | 53 | ||
54 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata; | ||
55 | |||
53 | /* | 56 | /* |
54 | * POLICY: If *anything* doesn't work, put it on the blacklist. | 57 | * POLICY: If *anything* doesn't work, put it on the blacklist. |
55 | * If they are critical errors, mark it critical, and abort driver load. | 58 | * If they are critical errors, mark it critical, and abort driver load. |
@@ -165,5 +168,383 @@ int __init acpi_blacklisted(void) | |||
165 | 168 | ||
166 | blacklisted += blacklist_by_year(); | 169 | blacklisted += blacklist_by_year(); |
167 | 170 | ||
171 | dmi_check_system(acpi_osi_dmi_table); | ||
172 | |||
168 | return blacklisted; | 173 | return blacklisted; |
169 | } | 174 | } |
175 | #ifdef CONFIG_DMI | ||
176 | static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) | ||
177 | { | ||
178 | acpi_dmi_osi_linux(1, d); /* enable */ | ||
179 | return 0; | ||
180 | } | ||
181 | static int __init dmi_disable_osi_linux(const struct dmi_system_id *d) | ||
182 | { | ||
183 | acpi_dmi_osi_linux(0, d); /* disable */ | ||
184 | return 0; | ||
185 | } | ||
186 | static int __init dmi_unknown_osi_linux(const struct dmi_system_id *d) | ||
187 | { | ||
188 | acpi_dmi_osi_linux(-1, d); /* unknown */ | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | * Most BIOS that invoke OSI(Linux) do nothing with it. | ||
194 | * But some cause Linux to break. | ||
195 | * Only a couple use it to make Linux run better. | ||
196 | * | ||
197 | * Thus, Linux should continue to disable OSI(Linux) by default, | ||
198 | * should continue to discourage BIOS writers from using it, and | ||
199 | * should whitelist the few existing systems that require it. | ||
200 | * | ||
201 | * If it appears clear a vendor isn't using OSI(Linux) | ||
202 | * for anything constructive, blacklist them by name to disable | ||
203 | * unnecessary dmesg warnings on all of their products. | ||
204 | */ | ||
205 | |||
206 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | ||
207 | /* | ||
208 | * Disable OSI(Linux) warnings on all "Acer, inc." | ||
209 | * | ||
210 | * _OSI(Linux) disables the latest Windows BIOS code: | ||
211 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"), | ||
212 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"), | ||
213 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"), | ||
214 | * _OSI(Linux) effect unknown: | ||
215 | * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"), | ||
216 | */ | ||
217 | { | ||
218 | .callback = dmi_disable_osi_linux, | ||
219 | .ident = "Acer, inc.", | ||
220 | .matches = { | ||
221 | DMI_MATCH(DMI_SYS_VENDOR, "Acer, inc."), | ||
222 | }, | ||
223 | }, | ||
224 | /* | ||
225 | * Disable OSI(Linux) warnings on all "Acer" | ||
226 | * | ||
227 | * _OSI(Linux) effect unknown: | ||
228 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), | ||
229 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), | ||
230 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"), | ||
231 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"), | ||
232 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 6460"), | ||
233 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 7510"), | ||
234 | * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"), | ||
235 | */ | ||
236 | { | ||
237 | .callback = dmi_unknown_osi_linux, | ||
238 | .ident = "Acer", | ||
239 | .matches = { | ||
240 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
241 | }, | ||
242 | }, | ||
243 | /* | ||
244 | * Disable OSI(Linux) warnings on all "Apple Computer, Inc." | ||
245 | * | ||
246 | * _OSI(Linux) confirmed to be a NOP: | ||
247 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), | ||
248 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"), | ||
249 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"), | ||
250 | * _OSI(Linux) effect unknown: | ||
251 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacPro2,1"), | ||
252 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"), | ||
253 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"), | ||
254 | */ | ||
255 | { | ||
256 | .callback = dmi_disable_osi_linux, | ||
257 | .ident = "Apple", | ||
258 | .matches = { | ||
259 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), | ||
260 | }, | ||
261 | }, | ||
262 | /* | ||
263 | * Disable OSI(Linux) warnings on all "BenQ" | ||
264 | * | ||
265 | * _OSI(Linux) confirmed to be a NOP: | ||
266 | * DMI_MATCH(DMI_PRODUCT_NAME, "Joybook S31"), | ||
267 | */ | ||
268 | { | ||
269 | .callback = dmi_disable_osi_linux, | ||
270 | .ident = "BenQ", | ||
271 | .matches = { | ||
272 | DMI_MATCH(DMI_SYS_VENDOR, "BenQ"), | ||
273 | }, | ||
274 | }, | ||
275 | /* | ||
276 | * Disable OSI(Linux) warnings on all "Clevo Co." | ||
277 | * | ||
278 | * _OSI(Linux) confirmed to be a NOP: | ||
279 | * DMI_MATCH(DMI_PRODUCT_NAME, "M570RU"), | ||
280 | */ | ||
281 | { | ||
282 | .callback = dmi_disable_osi_linux, | ||
283 | .ident = "Clevo", | ||
284 | .matches = { | ||
285 | DMI_MATCH(DMI_SYS_VENDOR, "Clevo Co."), | ||
286 | }, | ||
287 | }, | ||
288 | /* | ||
289 | * Disable OSI(Linux) warnings on all "COMPAL" | ||
290 | * | ||
291 | * _OSI(Linux) confirmed to be a NOP: | ||
292 | * DMI_MATCH(DMI_BOARD_NAME, "HEL8X"), | ||
293 | * _OSI(Linux) unknown effect: | ||
294 | * DMI_MATCH(DMI_BOARD_NAME, "IFL91"), | ||
295 | */ | ||
296 | { | ||
297 | .callback = dmi_unknown_osi_linux, | ||
298 | .ident = "Compal", | ||
299 | .matches = { | ||
300 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
301 | }, | ||
302 | }, | ||
303 | { /* OSI(Linux) touches USB, breaks suspend to disk */ | ||
304 | .callback = dmi_disable_osi_linux, | ||
305 | .ident = "Dell Dimension 5150", | ||
306 | .matches = { | ||
307 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
308 | DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM051"), | ||
309 | }, | ||
310 | }, | ||
311 | { /* OSI(Linux) is a NOP */ | ||
312 | .callback = dmi_disable_osi_linux, | ||
313 | .ident = "Dell", | ||
314 | .matches = { | ||
315 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
316 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1501"), | ||
317 | }, | ||
318 | }, | ||
319 | { /* OSI(Linux) effect unknown */ | ||
320 | .callback = dmi_unknown_osi_linux, | ||
321 | .ident = "Dell", | ||
322 | .matches = { | ||
323 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
324 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D830"), | ||
325 | }, | ||
326 | }, | ||
327 | { /* OSI(Linux) effect unknown */ | ||
328 | .callback = dmi_unknown_osi_linux, | ||
329 | .ident = "Dell", | ||
330 | .matches = { | ||
331 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
332 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX620"), | ||
333 | }, | ||
334 | }, | ||
335 | { /* OSI(Linux) effect unknown */ | ||
336 | .callback = dmi_unknown_osi_linux, | ||
337 | .ident = "Dell", | ||
338 | .matches = { | ||
339 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
340 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1900"), | ||
341 | }, | ||
342 | }, | ||
343 | { /* OSI(Linux) touches USB */ | ||
344 | .callback = dmi_disable_osi_linux, | ||
345 | .ident = "Dell", | ||
346 | .matches = { | ||
347 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
348 | DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 390"), | ||
349 | }, | ||
350 | }, | ||
351 | { /* OSI(Linux) is a NOP */ | ||
352 | .callback = dmi_disable_osi_linux, | ||
353 | .ident = "Dell Vostro 1000", | ||
354 | .matches = { | ||
355 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
356 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1000"), | ||
357 | }, | ||
358 | }, | ||
359 | { /* OSI(Linux) effect unknown */ | ||
360 | .callback = dmi_unknown_osi_linux, | ||
361 | .ident = "Dell", | ||
362 | .matches = { | ||
363 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
364 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge SC440"), | ||
365 | }, | ||
366 | }, | ||
367 | { /* OSI(Linux) effect unknown */ | ||
368 | .callback = dmi_unknown_osi_linux, | ||
369 | .ident = "Dialogue Flybook V5", | ||
370 | .matches = { | ||
371 | DMI_MATCH(DMI_SYS_VENDOR, "Dialogue Technology Corporation"), | ||
372 | DMI_MATCH(DMI_PRODUCT_NAME, "Flybook V5"), | ||
373 | }, | ||
374 | }, | ||
375 | /* | ||
376 | * Disable OSI(Linux) warnings on all "FUJITSU SIEMENS" | ||
377 | * | ||
378 | * _OSI(Linux) disables latest Windows BIOS code: | ||
379 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2510"), | ||
380 | * _OSI(Linux) confirmed to be a NOP: | ||
381 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1536"), | ||
382 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1556"), | ||
383 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 1546"), | ||
384 | * _OSI(Linux) unknown effect: | ||
385 | * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo M1425"), | ||
386 | * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo Si 1520"), | ||
387 | * DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), | ||
388 | */ | ||
389 | { | ||
390 | .callback = dmi_disable_osi_linux, | ||
391 | .ident = "Fujitsu Siemens", | ||
392 | .matches = { | ||
393 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
394 | }, | ||
395 | }, | ||
396 | /* | ||
397 | * Disable OSI(Linux) warnings on all "Hewlett-Packard" | ||
398 | * | ||
399 | * _OSI(Linux) confirmed to be a NOP: | ||
400 | * .ident = "HP Pavilion tx 1000" | ||
401 | * DMI_MATCH(DMI_BOARD_NAME, "30BF"), | ||
402 | * .ident = "HP Pavilion dv2000" | ||
403 | * DMI_MATCH(DMI_BOARD_NAME, "30B5"), | ||
404 | * .ident = "HP Pavilion dv5000", | ||
405 | * DMI_MATCH(DMI_BOARD_NAME, "30A7"), | ||
406 | * .ident = "HP Pavilion dv6300 30BC", | ||
407 | * DMI_MATCH(DMI_BOARD_NAME, "30BC"), | ||
408 | * .ident = "HP Pavilion dv6000", | ||
409 | * DMI_MATCH(DMI_BOARD_NAME, "30B7"), | ||
410 | * DMI_MATCH(DMI_BOARD_NAME, "30B8"), | ||
411 | * .ident = "HP Pavilion dv9000", | ||
412 | * DMI_MATCH(DMI_BOARD_NAME, "30B9"), | ||
413 | * .ident = "HP Pavilion dv9500", | ||
414 | * DMI_MATCH(DMI_BOARD_NAME, "30CB"), | ||
415 | * .ident = "HP/Compaq Presario C500", | ||
416 | * DMI_MATCH(DMI_BOARD_NAME, "30C6"), | ||
417 | * .ident = "HP/Compaq Presario F500", | ||
418 | * DMI_MATCH(DMI_BOARD_NAME, "30D3"), | ||
419 | * _OSI(Linux) unknown effect: | ||
420 | * .ident = "HP Pavilion dv6500", | ||
421 | * DMI_MATCH(DMI_BOARD_NAME, "30D0"), | ||
422 | */ | ||
423 | { | ||
424 | .callback = dmi_disable_osi_linux, | ||
425 | .ident = "Hewlett-Packard", | ||
426 | .matches = { | ||
427 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
428 | }, | ||
429 | }, | ||
430 | /* | ||
431 | * Lenovo has a mix of systems OSI(Linux) situations | ||
432 | * and thus we can not wildcard the vendor. | ||
433 | * | ||
434 | * _OSI(Linux) helps sound | ||
435 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), | ||
436 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), | ||
437 | * _OSI(Linux) is a NOP: | ||
438 | * DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), | ||
439 | */ | ||
440 | { | ||
441 | .callback = dmi_enable_osi_linux, | ||
442 | .ident = "Lenovo ThinkPad R61", | ||
443 | .matches = { | ||
444 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
445 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), | ||
446 | }, | ||
447 | }, | ||
448 | { | ||
449 | .callback = dmi_enable_osi_linux, | ||
450 | .ident = "Lenovo ThinkPad T61", | ||
451 | .matches = { | ||
452 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
453 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), | ||
454 | }, | ||
455 | }, | ||
456 | { | ||
457 | .callback = dmi_unknown_osi_linux, | ||
458 | .ident = "Lenovo 3000 V100", | ||
459 | .matches = { | ||
460 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
461 | DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"), | ||
462 | }, | ||
463 | }, | ||
464 | { | ||
465 | .callback = dmi_disable_osi_linux, | ||
466 | .ident = "Lenovo 3000 N100", | ||
467 | .matches = { | ||
468 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
469 | DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), | ||
470 | }, | ||
471 | }, | ||
472 | /* | ||
473 | * Disable OSI(Linux) warnings on all "LG Electronics" | ||
474 | * | ||
475 | * _OSI(Linux) confirmed to be a NOP: | ||
476 | * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"), | ||
477 | */ | ||
478 | { | ||
479 | .callback = dmi_disable_osi_linux, | ||
480 | .ident = "LG", | ||
481 | .matches = { | ||
482 | DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), | ||
483 | }, | ||
484 | }, | ||
485 | /* NEC - OSI(Linux) effect unknown */ | ||
486 | { | ||
487 | .callback = dmi_unknown_osi_linux, | ||
488 | .ident = "NEC VERSA M360", | ||
489 | .matches = { | ||
490 | DMI_MATCH(DMI_SYS_VENDOR, "NEC Computers SAS"), | ||
491 | DMI_MATCH(DMI_PRODUCT_NAME, "NEC VERSA M360"), | ||
492 | }, | ||
493 | }, | ||
494 | /* | ||
495 | * Disable OSI(Linux) warnings on all "Samsung Electronics" | ||
496 | * | ||
497 | * OSI(Linux) disables PNP0C32 and other BIOS code for Windows: | ||
498 | * DMI_MATCH(DMI_PRODUCT_NAME, "R40P/R41P"), | ||
499 | * DMI_MATCH(DMI_PRODUCT_NAME, "R59P/R60P/R61P"), | ||
500 | */ | ||
501 | { | ||
502 | .callback = dmi_disable_osi_linux, | ||
503 | .ident = "Samsung", | ||
504 | .matches = { | ||
505 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
506 | }, | ||
507 | }, | ||
508 | /* | ||
509 | * Disable OSI(Linux) warnings on all "Sony Corporation" | ||
510 | * | ||
511 | * _OSI(Linux) is a NOP: | ||
512 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ650N"), | ||
513 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ38GP_C"), | ||
514 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-TZ21MN_N"), | ||
515 | * _OSI(Linux) unknown effect: | ||
516 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ11M"), | ||
517 | */ | ||
518 | { | ||
519 | .callback = dmi_unknown_osi_linux, | ||
520 | .ident = "Sony", | ||
521 | .matches = { | ||
522 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
523 | }, | ||
524 | }, | ||
525 | /* | ||
526 | * Disable OSI(Linux) warnings on all "TOSHIBA" | ||
527 | * | ||
528 | * _OSI(Linux) breaks sound (bugzilla 7787): | ||
529 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P100"), | ||
530 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P105"), | ||
531 | * _OSI(Linux) is a NOP: | ||
532 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A100"), | ||
533 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A210"), | ||
534 | * _OSI(Linux) unknown effect: | ||
535 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A135"), | ||
536 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A200"), | ||
537 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P205"), | ||
538 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U305"), | ||
539 | */ | ||
540 | { | ||
541 | .callback = dmi_disable_osi_linux, | ||
542 | .ident = "Toshiba", | ||
543 | .matches = { | ||
544 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
545 | }, | ||
546 | }, | ||
547 | {} | ||
548 | }; | ||
549 | |||
550 | #endif /* CONFIG_DMI */ | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e3a673a00845..e53fb516f9d4 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -77,11 +77,55 @@ static struct workqueue_struct *kacpi_notify_wq; | |||
77 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | 77 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ |
78 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; | 78 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; |
79 | 79 | ||
80 | static int osi_linux; /* disable _OSI(Linux) by default */ | 80 | /* |
81 | * "Ode to _OSI(Linux)" | ||
82 | * | ||
83 | * osi_linux -- Control response to BIOS _OSI(Linux) query. | ||
84 | * | ||
85 | * As Linux evolves, the features that it supports change. | ||
86 | * So an OSI string such as "Linux" is not specific enough | ||
87 | * to be useful across multiple versions of Linux. It | ||
88 | * doesn't identify any particular feature, interface, | ||
89 | * or even any particular version of Linux... | ||
90 | * | ||
91 | * Unfortunately, Linux-2.6.22 and earlier responded "yes" | ||
92 | * to a BIOS _OSI(Linux) query. When | ||
93 | * a reference mobile BIOS started using it, its use | ||
94 | * started to spread to many vendor platforms. | ||
95 | * As it is not supportable, we need to halt that spread. | ||
96 | * | ||
97 | * Today, most BIOS references to _OSI(Linux) are noise -- | ||
98 | * they have no functional effect and are just dead code | ||
99 | * carried over from the reference BIOS. | ||
100 | * | ||
101 | * The next most common case is that _OSI(Linux) harms Linux, | ||
102 | * usually by causing the BIOS to follow paths that are | ||
103 | * not tested during Windows validation. | ||
104 | * | ||
105 | * Finally, there is a short list of platforms | ||
106 | * where OSI(Linux) benefits Linux. | ||
107 | * | ||
108 | * In Linux-2.6.23, OSI(Linux) is first disabled by default. | ||
109 | * DMI is used to disable the dmesg warning about OSI(Linux) | ||
110 | * on platforms where it is known to have no effect. | ||
111 | * But a dmesg warning remains for systems where | ||
112 | * we do not know if OSI(Linux) is good or bad for the system. | ||
113 | * DMI is also used to enable OSI(Linux) for the machines | ||
114 | * that are known to need it. | ||
115 | * | ||
116 | * BIOS writers should NOT query _OSI(Linux) on future systems. | ||
117 | * It will be ignored by default, and to get Linux to | ||
118 | * not ignore it will require a kernel source update to | ||
119 | * add a DMI entry, or a boot-time "acpi_osi=Linux" invocation. | ||
120 | */ | ||
121 | #define OSI_LINUX_ENABLE 0 | ||
81 | 122 | ||
82 | #ifdef CONFIG_DMI | 123 | struct osi_linux { |
83 | static struct __initdata dmi_system_id acpi_osl_dmi_table[]; | 124 | unsigned int enable:1; |
84 | #endif | 125 | unsigned int dmi:1; |
126 | unsigned int cmdline:1; | ||
127 | unsigned int known:1; | ||
128 | } osi_linux = { OSI_LINUX_ENABLE, 0, 0, 0}; | ||
85 | 129 | ||
86 | static void __init acpi_request_region (struct acpi_generic_address *addr, | 130 | static void __init acpi_request_region (struct acpi_generic_address *addr, |
87 | unsigned int length, char *desc) | 131 | unsigned int length, char *desc) |
@@ -133,7 +177,6 @@ device_initcall(acpi_reserve_resources); | |||
133 | 177 | ||
134 | acpi_status __init acpi_os_initialize(void) | 178 | acpi_status __init acpi_os_initialize(void) |
135 | { | 179 | { |
136 | dmi_check_system(acpi_osl_dmi_table); | ||
137 | return AE_OK; | 180 | return AE_OK; |
138 | } | 181 | } |
139 | 182 | ||
@@ -964,13 +1007,37 @@ static int __init acpi_os_name_setup(char *str) | |||
964 | 1007 | ||
965 | __setup("acpi_os_name=", acpi_os_name_setup); | 1008 | __setup("acpi_os_name=", acpi_os_name_setup); |
966 | 1009 | ||
967 | static void enable_osi_linux(int enable) { | 1010 | static void __init set_osi_linux(unsigned int enable) |
1011 | { | ||
1012 | if (osi_linux.enable != enable) { | ||
1013 | osi_linux.enable = enable; | ||
1014 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", | ||
1015 | enable ? "Add": "Delet"); | ||
1016 | } | ||
1017 | return; | ||
1018 | } | ||
968 | 1019 | ||
969 | if (osi_linux != enable) | 1020 | static void __init acpi_cmdline_osi_linux(unsigned int enable) |
970 | printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n", | 1021 | { |
971 | enable ? "En": "Dis"); | 1022 | osi_linux.cmdline = 1; /* cmdline set the default */ |
1023 | set_osi_linux(enable); | ||
1024 | |||
1025 | return; | ||
1026 | } | ||
1027 | |||
1028 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | ||
1029 | { | ||
1030 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ | ||
1031 | |||
1032 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | ||
1033 | |||
1034 | if (enable == -1) | ||
1035 | return; | ||
1036 | |||
1037 | osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */ | ||
1038 | |||
1039 | set_osi_linux(enable); | ||
972 | 1040 | ||
973 | osi_linux = enable; | ||
974 | return; | 1041 | return; |
975 | } | 1042 | } |
976 | 1043 | ||
@@ -987,12 +1054,12 @@ static int __init acpi_osi_setup(char *str) | |||
987 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 1054 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); |
988 | acpi_gbl_create_osi_method = FALSE; | 1055 | acpi_gbl_create_osi_method = FALSE; |
989 | } else if (!strcmp("!Linux", str)) { | 1056 | } else if (!strcmp("!Linux", str)) { |
990 | enable_osi_linux(0); | 1057 | acpi_cmdline_osi_linux(0); /* !enable */ |
991 | } else if (*str == '!') { | 1058 | } else if (*str == '!') { |
992 | if (acpi_osi_invalidate(++str) == AE_OK) | 1059 | if (acpi_osi_invalidate(++str) == AE_OK) |
993 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | 1060 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); |
994 | } else if (!strcmp("Linux", str)) { | 1061 | } else if (!strcmp("Linux", str)) { |
995 | enable_osi_linux(1); | 1062 | acpi_cmdline_osi_linux(1); /* enable */ |
996 | } else if (*osi_additional_string == '\0') { | 1063 | } else if (*osi_additional_string == '\0') { |
997 | strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); | 1064 | strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); |
998 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | 1065 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); |
@@ -1141,6 +1208,34 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) | |||
1141 | return (AE_OK); | 1208 | return (AE_OK); |
1142 | } | 1209 | } |
1143 | 1210 | ||
1211 | /** | ||
1212 | * acpi_dmi_dump - dump DMI slots needed for blacklist entry | ||
1213 | * | ||
1214 | * Returns 0 on success | ||
1215 | */ | ||
1216 | int acpi_dmi_dump(void) | ||
1217 | { | ||
1218 | |||
1219 | if (!dmi_available) | ||
1220 | return -1; | ||
1221 | |||
1222 | printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n", | ||
1223 | dmi_get_slot(DMI_SYS_VENDOR)); | ||
1224 | printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n", | ||
1225 | dmi_get_slot(DMI_PRODUCT_NAME)); | ||
1226 | printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n", | ||
1227 | dmi_get_slot(DMI_PRODUCT_VERSION)); | ||
1228 | printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n", | ||
1229 | dmi_get_slot(DMI_BOARD_NAME)); | ||
1230 | printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n", | ||
1231 | dmi_get_slot(DMI_BIOS_VENDOR)); | ||
1232 | printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n", | ||
1233 | dmi_get_slot(DMI_BIOS_DATE)); | ||
1234 | |||
1235 | return 0; | ||
1236 | } | ||
1237 | |||
1238 | |||
1144 | /****************************************************************************** | 1239 | /****************************************************************************** |
1145 | * | 1240 | * |
1146 | * FUNCTION: acpi_os_validate_interface | 1241 | * FUNCTION: acpi_os_validate_interface |
@@ -1160,13 +1255,29 @@ acpi_os_validate_interface (char *interface) | |||
1160 | if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX)) | 1255 | if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX)) |
1161 | return AE_OK; | 1256 | return AE_OK; |
1162 | if (!strcmp("Linux", interface)) { | 1257 | if (!strcmp("Linux", interface)) { |
1163 | printk(KERN_WARNING PREFIX | 1258 | |
1164 | "System BIOS is requesting _OSI(Linux)\n"); | 1259 | printk(KERN_NOTICE PREFIX |
1165 | printk(KERN_WARNING PREFIX | 1260 | "BIOS _OSI(Linux) query %s%s\n", |
1166 | "If \"acpi_osi=Linux\" works better,\n" | 1261 | osi_linux.enable ? "honored" : "ignored", |
1167 | "Please send dmidecode " | 1262 | osi_linux.cmdline ? " via cmdline" : |
1168 | "to linux-acpi@vger.kernel.org\n"); | 1263 | osi_linux.dmi ? " via DMI" : ""); |
1169 | if(osi_linux) | 1264 | |
1265 | if (!osi_linux.dmi) { | ||
1266 | if (acpi_dmi_dump()) | ||
1267 | printk(KERN_NOTICE PREFIX | ||
1268 | "[please extract dmidecode output]\n"); | ||
1269 | printk(KERN_NOTICE PREFIX | ||
1270 | "Please send DMI info above to " | ||
1271 | "linux-acpi@vger.kernel.org\n"); | ||
1272 | } | ||
1273 | if (!osi_linux.known && !osi_linux.cmdline) { | ||
1274 | printk(KERN_NOTICE PREFIX | ||
1275 | "If \"acpi_osi=%sLinux\" works better, " | ||
1276 | "please notify linux-acpi@vger.kernel.org\n", | ||
1277 | osi_linux.enable ? "!" : ""); | ||
1278 | } | ||
1279 | |||
1280 | if (osi_linux.enable) | ||
1170 | return AE_OK; | 1281 | return AE_OK; |
1171 | } | 1282 | } |
1172 | return AE_SUPPORT; | 1283 | return AE_SUPPORT; |
@@ -1198,28 +1309,4 @@ acpi_os_validate_address ( | |||
1198 | return AE_OK; | 1309 | return AE_OK; |
1199 | } | 1310 | } |
1200 | 1311 | ||
1201 | #ifdef CONFIG_DMI | ||
1202 | static int dmi_osi_linux(const struct dmi_system_id *d) | ||
1203 | { | ||
1204 | printk(KERN_NOTICE "%s detected: enabling _OSI(Linux)\n", d->ident); | ||
1205 | enable_osi_linux(1); | ||
1206 | return 0; | ||
1207 | } | ||
1208 | |||
1209 | static struct dmi_system_id acpi_osl_dmi_table[] __initdata = { | ||
1210 | /* | ||
1211 | * Boxes that need _OSI(Linux) | ||
1212 | */ | ||
1213 | { | ||
1214 | .callback = dmi_osi_linux, | ||
1215 | .ident = "Intel Napa CRB", | ||
1216 | .matches = { | ||
1217 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), | ||
1218 | DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"), | ||
1219 | }, | ||
1220 | }, | ||
1221 | {} | ||
1222 | }; | ||
1223 | #endif /* CONFIG_DMI */ | ||
1224 | |||
1225 | #endif | 1312 | #endif |
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index bc132d8f79cb..313c99cbdc62 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c | |||
@@ -173,8 +173,6 @@ static struct device *dmi_dev; | |||
173 | if (dmi_get_system_info(_field)) \ | 173 | if (dmi_get_system_info(_field)) \ |
174 | sys_dmi_attributes[i++] = &sys_dmi_##_name##_attr.dev_attr.attr; | 174 | sys_dmi_attributes[i++] = &sys_dmi_##_name##_attr.dev_attr.attr; |
175 | 175 | ||
176 | extern int dmi_available; | ||
177 | |||
178 | /* In a separate function to keep gcc 3.2 happy - do NOT merge this in | 176 | /* In a separate function to keep gcc 3.2 happy - do NOT merge this in |
179 | dmi_id_init! */ | 177 | dmi_id_init! */ |
180 | static void __init dmi_id_init_attr_table(void) | 178 | static void __init dmi_id_init_attr_table(void) |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 0cdadea7a40e..5e596a7e3601 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -470,3 +470,11 @@ int dmi_get_year(int field) | |||
470 | return year; | 470 | return year; |
471 | } | 471 | } |
472 | 472 | ||
473 | /** | ||
474 | * dmi_get_slot - return dmi_ident[slot] | ||
475 | * @slot: index into dmi_ident[] | ||
476 | */ | ||
477 | char *dmi_get_slot(int slot) | ||
478 | { | ||
479 | return(dmi_ident[slot]); | ||
480 | } | ||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index e3c16c981e46..63f2e6ed698f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
41 | #include <acpi/acpi_numa.h> | 41 | #include <acpi/acpi_numa.h> |
42 | #include <asm/acpi.h> | 42 | #include <asm/acpi.h> |
43 | #include <linux/dmi.h> | ||
43 | 44 | ||
44 | 45 | ||
45 | #ifdef CONFIG_ACPI | 46 | #ifdef CONFIG_ACPI |
@@ -192,7 +193,9 @@ extern int ec_transaction(u8 command, | |||
192 | #endif /*CONFIG_ACPI_EC*/ | 193 | #endif /*CONFIG_ACPI_EC*/ |
193 | 194 | ||
194 | extern int acpi_blacklisted(void); | 195 | extern int acpi_blacklisted(void); |
195 | extern void acpi_bios_year(char *s); | 196 | #ifdef CONFIG_DMI |
197 | extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); | ||
198 | #endif | ||
196 | 199 | ||
197 | #ifdef CONFIG_ACPI_NUMA | 200 | #ifdef CONFIG_ACPI_NUMA |
198 | int acpi_get_pxm(acpi_handle handle); | 201 | int acpi_get_pxm(acpi_handle handle); |
@@ -226,5 +229,5 @@ static inline int acpi_boot_table_init(void) | |||
226 | return 0; | 229 | return 0; |
227 | } | 230 | } |
228 | 231 | ||
229 | #endif /* CONFIG_ACPI */ | 232 | #endif /* !CONFIG_ACPI */ |
230 | #endif /*_LINUX_ACPI_H*/ | 233 | #endif /*_LINUX_ACPI_H*/ |
diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 00fc7a9c35ec..5b42a659a308 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h | |||
@@ -78,6 +78,8 @@ extern const struct dmi_device * dmi_find_device(int type, const char *name, | |||
78 | extern void dmi_scan_machine(void); | 78 | extern void dmi_scan_machine(void); |
79 | extern int dmi_get_year(int field); | 79 | extern int dmi_get_year(int field); |
80 | extern int dmi_name_in_vendors(const char *str); | 80 | extern int dmi_name_in_vendors(const char *str); |
81 | extern int dmi_available; | ||
82 | extern char *dmi_get_slot(int slot); | ||
81 | 83 | ||
82 | #else | 84 | #else |
83 | 85 | ||
@@ -87,6 +89,8 @@ static inline const struct dmi_device * dmi_find_device(int type, const char *na | |||
87 | const struct dmi_device *from) { return NULL; } | 89 | const struct dmi_device *from) { return NULL; } |
88 | static inline int dmi_get_year(int year) { return 0; } | 90 | static inline int dmi_get_year(int year) { return 0; } |
89 | static inline int dmi_name_in_vendors(const char *s) { return 0; } | 91 | static inline int dmi_name_in_vendors(const char *s) { return 0; } |
92 | #define dmi_available 0 | ||
93 | static inline char *dmi_get_slot(int slot) { return NULL; } | ||
90 | 94 | ||
91 | #endif | 95 | #endif |
92 | 96 | ||