aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/blacklist.c5
-rw-r--r--drivers/ata/ahci.c2
-rw-r--r--drivers/firmware/dmi_scan.c76
3 files changed, 62 insertions, 21 deletions
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