aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r--drivers/ata/ahci.c53
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 */
2655static bool ahci_asus_m2a_vm_32bit_only(struct pci_dev *pdev) 2653static 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))