diff options
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 147b9be3b4d2..aa03b49a9af2 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -2647,14 +2647,18 @@ static void ahci_p5wdh_workaround(struct ata_host *host) | |||
2647 | } | 2647 | } |
2648 | 2648 | ||
2649 | /* | 2649 | /* |
2650 | * SB600 ahci controller on ASUS M2A-VM can't do 64bit DMA with older | 2650 | * SB600 ahci controller on certain boards can't do 64bit DMA with |
2651 | * BIOS. The oldest version known to be broken is 0901 and working is | 2651 | * older BIOS. |
2652 | * 1501 which was released on 2007-10-26. Force 32bit DMA on anything | ||
2653 | * older than 1501. Please read bko#9412 for more info. | ||
2654 | */ | 2652 | */ |
2655 | static bool ahci_asus_m2a_vm_32bit_only(struct pci_dev *pdev) | 2653 | static bool ahci_sb600_32bit_only(struct pci_dev *pdev) |
2656 | { | 2654 | { |
2657 | static const struct dmi_system_id sysids[] = { | 2655 | static const struct dmi_system_id sysids[] = { |
2656 | /* | ||
2657 | * The oldest version known to be broken is 0901 and | ||
2658 | * working is 1501 which was released on 2007-10-26. | ||
2659 | * Force 32bit DMA on anything older than 1501. | ||
2660 | * Please read bko#9412 for more info. | ||
2661 | */ | ||
2658 | { | 2662 | { |
2659 | .ident = "ASUS M2A-VM", | 2663 | .ident = "ASUS M2A-VM", |
2660 | .matches = { | 2664 | .matches = { |
@@ -2662,31 +2666,32 @@ static bool ahci_asus_m2a_vm_32bit_only(struct pci_dev *pdev) | |||
2662 | "ASUSTeK Computer INC."), | 2666 | "ASUSTeK Computer INC."), |
2663 | DMI_MATCH(DMI_BOARD_NAME, "M2A-VM"), | 2667 | DMI_MATCH(DMI_BOARD_NAME, "M2A-VM"), |
2664 | }, | 2668 | }, |
2669 | .driver_data = "20071026", /* yyyymmdd */ | ||
2665 | }, | 2670 | }, |
2666 | { } | 2671 | { } |
2667 | }; | 2672 | }; |
2668 | const char *cutoff_mmdd = "10/26"; | 2673 | const struct dmi_system_id *match; |
2669 | const char *date; | ||
2670 | int year; | ||
2671 | 2674 | ||
2675 | match = dmi_first_match(sysids); | ||
2672 | if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) || | 2676 | if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) || |
2673 | !dmi_check_system(sysids)) | 2677 | !match) |
2674 | return false; | 2678 | return false; |
2675 | 2679 | ||
2676 | /* | 2680 | if (match->driver_data) { |
2677 | * Argh.... both version and date are free form strings. | 2681 | int year, month, date; |
2678 | * Let's hope they're using the same date format across | 2682 | char buf[9]; |
2679 | * different versions. | 2683 | |
2680 | */ | 2684 | dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); |
2681 | date = dmi_get_system_info(DMI_BIOS_DATE); | 2685 | snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); |
2682 | dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); | ||
2683 | if (date && strlen(date) >= 10 && date[2] == '/' && date[5] == '/' && | ||
2684 | (year > 2007 || | ||
2685 | (year == 2007 && strncmp(date, cutoff_mmdd, 5) >= 0))) | ||
2686 | return false; | ||
2687 | 2686 | ||
2688 | dev_printk(KERN_WARNING, &pdev->dev, "ASUS M2A-VM: BIOS too old, " | 2687 | if (strcmp(buf, match->driver_data) >= 0) |
2689 | "forcing 32bit DMA, update BIOS\n"); | 2688 | return false; |
2689 | |||
2690 | dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, " | ||
2691 | "forcing 32bit DMA, update BIOS\n", match->ident); | ||
2692 | } else | ||
2693 | dev_printk(KERN_WARNING, &pdev->dev, "%s: this board can't " | ||
2694 | "do 64bit DMA, forcing 32bit\n", match->ident); | ||
2690 | 2695 | ||
2691 | return true; | 2696 | return true; |
2692 | } | 2697 | } |
@@ -2901,8 +2906,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2901 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) | 2906 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) |
2902 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; | 2907 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; |
2903 | 2908 | ||
2904 | /* apply ASUS M2A_VM quirk */ | 2909 | /* apply sb600 32bit only quirk */ |
2905 | if (ahci_asus_m2a_vm_32bit_only(pdev)) | 2910 | if (ahci_sb600_32bit_only(pdev)) |
2906 | hpriv->flags |= AHCI_HFLAG_32BIT_ONLY; | 2911 | hpriv->flags |= AHCI_HFLAG_32BIT_ONLY; |
2907 | 2912 | ||
2908 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) | 2913 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) |