aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/pci/direct.c5
-rw-r--r--drivers/acpi/blacklist.c5
-rw-r--r--drivers/ata/ahci.c2
-rw-r--r--drivers/firmware/dmi_scan.c76
-rw-r--r--include/linux/dmi.h13
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 = {
192static int __init pci_sanity_check(struct pci_raw_ops *o) 192static 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
79static int __init blacklist_by_year(void) 79static 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,
568EXPORT_SYMBOL(dmi_find_device); 568EXPORT_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 */
576int dmi_get_year(int field) 588bool 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;
631out:
632 if (yearp)
633 *yearp = year;
634 if (monthp)
635 *monthp = month;
636 if (dayp)
637 *dayp = day;
638 return exists;
599} 639}
600EXPORT_SYMBOL(dmi_get_year); 640EXPORT_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);
43extern const struct dmi_device * dmi_find_device(int type, const char *name, 43extern const struct dmi_device * dmi_find_device(int type, const char *name,
44 const struct dmi_device *from); 44 const struct dmi_device *from);
45extern void dmi_scan_machine(void); 45extern void dmi_scan_machine(void);
46extern int dmi_get_year(int field); 46extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp);
47extern int dmi_name_in_vendors(const char *str); 47extern int dmi_name_in_vendors(const char *str);
48extern int dmi_name_in_serial(const char *str); 48extern int dmi_name_in_serial(const char *str);
49extern int dmi_available; 49extern int dmi_available;
@@ -58,7 +58,16 @@ static inline const char * dmi_get_system_info(int field) { return NULL; }
58static inline const struct dmi_device * dmi_find_device(int type, const char *name, 58static 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; }
60static inline void dmi_scan_machine(void) { return; } 60static inline void dmi_scan_machine(void) { return; }
61static inline int dmi_get_year(int year) { return 0; } 61static 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}
62static inline int dmi_name_in_vendors(const char *s) { return 0; } 71static inline int dmi_name_in_vendors(const char *s) { return 0; }
63static inline int dmi_name_in_serial(const char *s) { return 0; } 72static inline int dmi_name_in_serial(const char *s) { return 0; }
64#define dmi_available 0 73#define dmi_available 0