From f083a329e63d471a5e9238e837772b1b76c218db Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 25 Mar 2006 16:30:19 +0100 Subject: [PATCH] [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 Signed-off-by: Linus Torvalds --- arch/i386/kernel/dmi_scan.c | 30 ++++++++++++++++++++++++++++++ drivers/acpi/blacklist.c | 27 ++++++--------------------- include/linux/dmi.h | 2 ++ 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c index ca2a0cbcac04..d2dfd9c8d691 100644 --- a/arch/i386/kernel/dmi_scan.c +++ b/arch/i386/kernel/dmi_scan.c @@ -299,3 +299,33 @@ struct dmi_device * dmi_find_device(int type, const char *name, return NULL; } EXPORT_SYMBOL(dmi_find_device); + +/** + * dmi_get_year - Return year of a DMI date + * @field: data index (like dmi_get_system_info) + * + * Returns -1 when the field doesn't exist. 0 when it is broken. + */ +int dmi_get_year(int field) +{ + int year; + char *s = dmi_get_system_info(field); + + if (!s) + return -1; + if (*s == '\0') + return 0; + s = strrchr(s, '/'); + if (!s) + return 0; + + s += 1; + year = simple_strtoul(s, NULL, 0); + if (year && year < 100) { /* 2-digit year */ + year += 1900; + if (year < 1996) /* no dates < spec 1.0 */ + year += 100; + } + + return year; +} diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 9824f679a910..f9c972b26f4f 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -77,28 +77,13 @@ static struct acpi_blacklist_item acpi_blacklist[] __initdata = { static int __init blacklist_by_year(void) { - int year; - char *s = dmi_get_system_info(DMI_BIOS_DATE); - - if (!s) - return 0; - if (!*s) - return 0; - - s = strrchr(s, '/'); - if (!s) + int year = dmi_get_year(DMI_BIOS_DATE); + /* Doesn't exist? Likely an old system */ + if (year == -1) + return 1; + /* 0? Likely a buggy new BIOS */ + if (year == 0) return 0; - - s += 1; - - year = simple_strtoul(s, NULL, 0); - - if (year < 100) { /* 2-digit year */ - year += 1900; - if (year < 1996) /* no dates < spec 1.0 */ - year += 100; - } - if (year < CONFIG_ACPI_BLACKLIST_YEAR) { printk(KERN_ERR PREFIX "BIOS age (%d) fails cutoff (%d), " "acpi=force is required to enable ACPI\n", diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 2e6bbe014157..64fd6c366604 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -68,6 +68,7 @@ extern char * dmi_get_system_info(int field); extern struct dmi_device * dmi_find_device(int type, const char *name, struct dmi_device *from); extern void dmi_scan_machine(void); +extern int dmi_get_year(int field); #else @@ -75,6 +76,7 @@ static inline int dmi_check_system(struct dmi_system_id *list) { return 0; } static inline char * dmi_get_system_info(int field) { return NULL; } static inline struct dmi_device * dmi_find_device(int type, const char *name, struct dmi_device *from) { return NULL; } +static inline int dmi_get_year(int year) { return 0; } #endif -- 2.39.2