Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] x86_64: Clean up and tweak ACPI blacklist year code

- Move the core parser into dmi_scan.c. It can be useful for other
subsystems too.
- Differentiate between field doesn't exist and field is 0 or
unparseable. The first case is likely an old BIOS with broken ACPI,
the later is likely a slightly buggy BIOS where someone forget to
edit the date. Don't blacklist in the later case.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Andi Kleen and committed by
Linus Torvalds
f083a329 e6fc99c6

+38 -21
+30
arch/i386/kernel/dmi_scan.c
··· 299 299 return NULL; 300 300 } 301 301 EXPORT_SYMBOL(dmi_find_device); 302 + 303 + /** 304 + * dmi_get_year - Return year of a DMI date 305 + * @field: data index (like dmi_get_system_info) 306 + * 307 + * Returns -1 when the field doesn't exist. 0 when it is broken. 308 + */ 309 + int dmi_get_year(int field) 310 + { 311 + int year; 312 + char *s = dmi_get_system_info(field); 313 + 314 + if (!s) 315 + return -1; 316 + if (*s == '\0') 317 + return 0; 318 + s = strrchr(s, '/'); 319 + if (!s) 320 + return 0; 321 + 322 + s += 1; 323 + year = simple_strtoul(s, NULL, 0); 324 + if (year && year < 100) { /* 2-digit year */ 325 + year += 1900; 326 + if (year < 1996) /* no dates < spec 1.0 */ 327 + year += 100; 328 + } 329 + 330 + return year; 331 + }
+6 -21
drivers/acpi/blacklist.c
··· 77 77 78 78 static int __init blacklist_by_year(void) 79 79 { 80 - int year; 81 - char *s = dmi_get_system_info(DMI_BIOS_DATE); 82 - 83 - if (!s) 80 + int year = dmi_get_year(DMI_BIOS_DATE); 81 + /* Doesn't exist? Likely an old system */ 82 + if (year == -1) 83 + return 1; 84 + /* 0? Likely a buggy new BIOS */ 85 + if (year == 0) 84 86 return 0; 85 - if (!*s) 86 - return 0; 87 - 88 - s = strrchr(s, '/'); 89 - if (!s) 90 - return 0; 91 - 92 - s += 1; 93 - 94 - year = simple_strtoul(s, NULL, 0); 95 - 96 - if (year < 100) { /* 2-digit year */ 97 - year += 1900; 98 - if (year < 1996) /* no dates < spec 1.0 */ 99 - year += 100; 100 - } 101 - 102 87 if (year < CONFIG_ACPI_BLACKLIST_YEAR) { 103 88 printk(KERN_ERR PREFIX "BIOS age (%d) fails cutoff (%d), " 104 89 "acpi=force is required to enable ACPI\n",
+2
include/linux/dmi.h
··· 68 68 extern struct dmi_device * dmi_find_device(int type, const char *name, 69 69 struct dmi_device *from); 70 70 extern void dmi_scan_machine(void); 71 + extern int dmi_get_year(int field); 71 72 72 73 #else 73 74 ··· 76 75 static inline char * dmi_get_system_info(int field) { return NULL; } 77 76 static inline struct dmi_device * dmi_find_device(int type, const char *name, 78 77 struct dmi_device *from) { return NULL; } 78 + static inline int dmi_get_year(int year) { return 0; } 79 79 80 80 #endif 81 81