[PATCH] x86_64: Clean up and tweak ACPI blacklist year code
Andi Kleen [Sat, 25 Mar 2006 15:30:19 +0000 (16:30 +0100)]
 - 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>

arch/i386/kernel/dmi_scan.c
drivers/acpi/blacklist.c
include/linux/dmi.h

index ca2a0cb..d2dfd9c 100644 (file)
@@ -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;
+}
index 9824f67..f9c972b 100644 (file)
@@ -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",
index 2e6bbe0..64fd6c3 100644 (file)
@@ -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