diff options
-rw-r--r-- | arch/x86/pci/direct.c | 5 | ||||
-rw-r--r-- | drivers/acpi/blacklist.c | 5 | ||||
-rw-r--r-- | drivers/ata/ahci.c | 2 | ||||
-rw-r--r-- | drivers/firmware/dmi_scan.c | 76 | ||||
-rw-r--r-- | include/linux/dmi.h | 13 |
5 files changed, 76 insertions, 25 deletions
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c index bd13c3e4c6db..347d882b3bb3 100644 --- a/arch/x86/pci/direct.c +++ b/arch/x86/pci/direct.c | |||
@@ -192,13 +192,14 @@ struct pci_raw_ops pci_direct_conf2 = { | |||
192 | static int __init pci_sanity_check(struct pci_raw_ops *o) | 192 | static int __init pci_sanity_check(struct pci_raw_ops *o) |
193 | { | 193 | { |
194 | u32 x = 0; | 194 | u32 x = 0; |
195 | int devfn; | 195 | int year, devfn; |
196 | 196 | ||
197 | if (pci_probe & PCI_NO_CHECKS) | 197 | if (pci_probe & PCI_NO_CHECKS) |
198 | return 1; | 198 | return 1; |
199 | /* Assume Type 1 works for newer systems. | 199 | /* Assume Type 1 works for newer systems. |
200 | This handles machines that don't have anything on PCI Bus 0. */ | 200 | This handles machines that don't have anything on PCI Bus 0. */ |
201 | if (dmi_get_year(DMI_BIOS_DATE) >= 2001) | 201 | dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); |
202 | if (year >= 2001) | ||
202 | return 1; | 203 | return 1; |
203 | 204 | ||
204 | for (devfn = 0; devfn < 0x100; devfn++) { | 205 | for (devfn = 0; devfn < 0x100; devfn++) { |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index f6baa77deefb..0c4ca4d318b3 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -78,9 +78,10 @@ static struct acpi_blacklist_item acpi_blacklist[] __initdata = { | |||
78 | 78 | ||
79 | static int __init blacklist_by_year(void) | 79 | static int __init blacklist_by_year(void) |
80 | { | 80 | { |
81 | int year = dmi_get_year(DMI_BIOS_DATE); | 81 | int year; |
82 | |||
82 | /* Doesn't exist? Likely an old system */ | 83 | /* Doesn't exist? Likely an old system */ |
83 | if (year == -1) { | 84 | if (!dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL)) { |
84 | printk(KERN_ERR PREFIX "no DMI BIOS year, " | 85 | printk(KERN_ERR PREFIX "no DMI BIOS year, " |
85 | "acpi=force is required to enable ACPI\n" ); | 86 | "acpi=force is required to enable ACPI\n" ); |
86 | return 1; | 87 | return 1; |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index be4c39f8ab81..147b9be3b4d2 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -2679,7 +2679,7 @@ static bool ahci_asus_m2a_vm_32bit_only(struct pci_dev *pdev) | |||
2679 | * different versions. | 2679 | * different versions. |
2680 | */ | 2680 | */ |
2681 | date = dmi_get_system_info(DMI_BIOS_DATE); | 2681 | date = dmi_get_system_info(DMI_BIOS_DATE); |
2682 | year = dmi_get_year(DMI_BIOS_DATE); | 2682 | dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); |
2683 | if (date && strlen(date) >= 10 && date[2] == '/' && date[5] == '/' && | 2683 | if (date && strlen(date) >= 10 && date[2] == '/' && date[5] == '/' && |
2684 | (year > 2007 || | 2684 | (year > 2007 || |
2685 | (year == 2007 && strncmp(date, cutoff_mmdd, 5) >= 0))) | 2685 | (year == 2007 && strncmp(date, cutoff_mmdd, 5) >= 0))) |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 531e621677ce..938100f14b16 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -568,36 +568,76 @@ const struct dmi_device * dmi_find_device(int type, const char *name, | |||
568 | EXPORT_SYMBOL(dmi_find_device); | 568 | EXPORT_SYMBOL(dmi_find_device); |
569 | 569 | ||
570 | /** | 570 | /** |
571 | * dmi_get_year - Return year of a DMI date | 571 | * dmi_get_date - parse a DMI date |
572 | * @field: data index (like dmi_get_system_info) | 572 | * @field: data index (see enum dmi_field) |
573 | * @yearp: optional out parameter for the year | ||
574 | * @monthp: optional out parameter for the month | ||
575 | * @dayp: optional out parameter for the day | ||
573 | * | 576 | * |
574 | * Returns -1 when the field doesn't exist. 0 when it is broken. | 577 | * The date field is assumed to be in the form resembling |
578 | * [mm[/dd]]/yy[yy] and the result is stored in the out | ||
579 | * parameters any or all of which can be omitted. | ||
580 | * | ||
581 | * If the field doesn't exist, all out parameters are set to zero | ||
582 | * and false is returned. Otherwise, true is returned with any | ||
583 | * invalid part of date set to zero. | ||
584 | * | ||
585 | * On return, year, month and day are guaranteed to be in the | ||
586 | * range of [0,9999], [0,12] and [0,31] respectively. | ||
575 | */ | 587 | */ |
576 | int dmi_get_year(int field) | 588 | bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp) |
577 | { | 589 | { |
578 | int year; | 590 | int year = 0, month = 0, day = 0; |
579 | const char *s = dmi_get_system_info(field); | 591 | bool exists; |
592 | const char *s, *y; | ||
580 | char *e; | 593 | char *e; |
581 | 594 | ||
582 | if (!s) | 595 | s = dmi_get_system_info(field); |
583 | return -1; | 596 | exists = s; |
584 | if (*s == '\0') | 597 | if (!exists) |
585 | return 0; | 598 | goto out; |
586 | s = strrchr(s, '/'); | ||
587 | if (!s) | ||
588 | return 0; | ||
589 | 599 | ||
590 | s += 1; | 600 | /* |
591 | year = simple_strtoul(s, &e, 10); | 601 | * Determine year first. We assume the date string resembles |
592 | if (s != e && year < 100) { /* 2-digit year */ | 602 | * mm/dd/yy[yy] but the original code extracted only the year |
603 | * from the end. Keep the behavior in the spirit of no | ||
604 | * surprises. | ||
605 | */ | ||
606 | y = strrchr(s, '/'); | ||
607 | if (!y) | ||
608 | goto out; | ||
609 | |||
610 | y++; | ||
611 | year = simple_strtoul(y, &e, 10); | ||
612 | if (y != e && year < 100) { /* 2-digit year */ | ||
593 | year += 1900; | 613 | year += 1900; |
594 | if (year < 1996) /* no dates < spec 1.0 */ | 614 | if (year < 1996) /* no dates < spec 1.0 */ |
595 | year += 100; | 615 | year += 100; |
596 | } | 616 | } |
617 | if (year > 9999) /* year should fit in %04d */ | ||
618 | year = 0; | ||
619 | |||
620 | /* parse the mm and dd */ | ||
621 | month = simple_strtoul(s, &e, 10); | ||
622 | if (s == e || *e != '/' || !month || month > 12) { | ||
623 | month = 0; | ||
624 | goto out; | ||
625 | } | ||
597 | 626 | ||
598 | return year; | 627 | s = e + 1; |
628 | day = simple_strtoul(s, &e, 10); | ||
629 | if (s == y || s == e || *e != '/' || day > 31) | ||
630 | day = 0; | ||
631 | out: | ||
632 | if (yearp) | ||
633 | *yearp = year; | ||
634 | if (monthp) | ||
635 | *monthp = month; | ||
636 | if (dayp) | ||
637 | *dayp = day; | ||
638 | return exists; | ||
599 | } | 639 | } |
600 | EXPORT_SYMBOL(dmi_get_year); | 640 | EXPORT_SYMBOL(dmi_get_date); |
601 | 641 | ||
602 | /** | 642 | /** |
603 | * dmi_walk - Walk the DMI table and get called back for every record | 643 | * dmi_walk - Walk the DMI table and get called back for every record |
diff --git a/include/linux/dmi.h b/include/linux/dmi.h index bb5489c82c99..a8a3e1ac281d 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h | |||
@@ -43,7 +43,7 @@ extern const char * dmi_get_system_info(int field); | |||
43 | extern const struct dmi_device * dmi_find_device(int type, const char *name, | 43 | extern const struct dmi_device * dmi_find_device(int type, const char *name, |
44 | const struct dmi_device *from); | 44 | const struct dmi_device *from); |
45 | extern void dmi_scan_machine(void); | 45 | extern void dmi_scan_machine(void); |
46 | extern int dmi_get_year(int field); | 46 | extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp); |
47 | extern int dmi_name_in_vendors(const char *str); | 47 | extern int dmi_name_in_vendors(const char *str); |
48 | extern int dmi_name_in_serial(const char *str); | 48 | extern int dmi_name_in_serial(const char *str); |
49 | extern int dmi_available; | 49 | extern int dmi_available; |
@@ -58,7 +58,16 @@ static inline const char * dmi_get_system_info(int field) { return NULL; } | |||
58 | static inline const struct dmi_device * dmi_find_device(int type, const char *name, | 58 | static inline const struct dmi_device * dmi_find_device(int type, const char *name, |
59 | const struct dmi_device *from) { return NULL; } | 59 | const struct dmi_device *from) { return NULL; } |
60 | static inline void dmi_scan_machine(void) { return; } | 60 | static inline void dmi_scan_machine(void) { return; } |
61 | static inline int dmi_get_year(int year) { return 0; } | 61 | static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp) |
62 | { | ||
63 | if (yearp) | ||
64 | *yearp = 0; | ||
65 | if (monthp) | ||
66 | *monthp = 0; | ||
67 | if (dayp) | ||
68 | *dayp = 0; | ||
69 | return false; | ||
70 | } | ||
62 | static inline int dmi_name_in_vendors(const char *s) { return 0; } | 71 | static inline int dmi_name_in_vendors(const char *s) { return 0; } |
63 | static inline int dmi_name_in_serial(const char *s) { return 0; } | 72 | static inline int dmi_name_in_serial(const char *s) { return 0; } |
64 | #define dmi_available 0 | 73 | #define dmi_available 0 |