aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorShane Huang <shane.huang@amd.com>2009-05-27 03:04:43 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-06-10 11:05:00 -0400
commit58a09b38cfcd700b796ea07ae3d2e0efbb28b561 (patch)
tree3979b8943a043413f15503a0967b1942c407cf46 /drivers
parent7654db1a9256d746ae4d229ba675f616a5d5e1a1 (diff)
[libata] ahci: Restore SB600 SATA controller 64 bit DMA
Community reported one SB600 SATA issue(BZ #9412), which led to 64 bit DMA disablement for all SB600 revisions by driver maintainers with commits c7a42156d99bcea7f8173ba7a6034bbaa2ecb77c and 4cde32fc4b32e96a99063af3183acdfd54c563f0. But the root cause is ASUS M2A-VM system BIOS bug in old revisions like 0901, while forcing into 32bit DMA happens to work as workaround. Now it's time to withdraw 4cde32fc4b32e96a99063af3183acdfd54c563f0 so as to restore the SB600 SATA 64bit DMA capability. This patch is also adding the workaround for M2A-VM old BIOS revisions, but users are suggested to upgrade their system BIOS to the latest one if they meet this issue. Signed-off-by: Shane Huang <shane.huang@amd.com> Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c52
-rw-r--r--drivers/firmware/dmi_scan.c1
2 files changed, 51 insertions, 2 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 2141a31f176b..15a23031833f 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -431,8 +431,7 @@ static const struct ata_port_info ahci_port_info[] = {
431 [board_ahci_sb600] = 431 [board_ahci_sb600] =
432 { 432 {
433 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | 433 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
434 AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | 434 AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255),
435 AHCI_HFLAG_SECT255),
436 .flags = AHCI_FLAG_COMMON, 435 .flags = AHCI_FLAG_COMMON,
437 .pio_mask = ATA_PIO4, 436 .pio_mask = ATA_PIO4,
438 .udma_mask = ATA_UDMA6, 437 .udma_mask = ATA_UDMA6,
@@ -2585,6 +2584,51 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
2585 } 2584 }
2586} 2585}
2587 2586
2587/*
2588 * SB600 ahci controller on ASUS M2A-VM can't do 64bit DMA with older
2589 * BIOS. The oldest version known to be broken is 0901 and working is
2590 * 1501 which was released on 2007-10-26. Force 32bit DMA on anything
2591 * older than 1501. Please read bko#9412 for more info.
2592 */
2593static bool ahci_asus_m2a_vm_32bit_only(struct pci_dev *pdev)
2594{
2595 static const struct dmi_system_id sysids[] = {
2596 {
2597 .ident = "ASUS M2A-VM",
2598 .matches = {
2599 DMI_MATCH(DMI_BOARD_VENDOR,
2600 "ASUSTeK Computer INC."),
2601 DMI_MATCH(DMI_BOARD_NAME, "M2A-VM"),
2602 },
2603 },
2604 { }
2605 };
2606 const char *cutoff_mmdd = "10/26";
2607 const char *date;
2608 int year;
2609
2610 if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) ||
2611 !dmi_check_system(sysids))
2612 return false;
2613
2614 /*
2615 * Argh.... both version and date are free form strings.
2616 * Let's hope they're using the same date format across
2617 * different versions.
2618 */
2619 date = dmi_get_system_info(DMI_BIOS_DATE);
2620 year = dmi_get_year(DMI_BIOS_DATE);
2621 if (date && strlen(date) >= 10 && date[2] == '/' && date[5] == '/' &&
2622 (year > 2007 ||
2623 (year == 2007 && strncmp(date, cutoff_mmdd, 5) >= 0)))
2624 return false;
2625
2626 dev_printk(KERN_WARNING, &pdev->dev, "ASUS M2A-VM: BIOS too old, "
2627 "forcing 32bit DMA, update BIOS\n");
2628
2629 return true;
2630}
2631
2588static bool ahci_broken_system_poweroff(struct pci_dev *pdev) 2632static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
2589{ 2633{
2590 static const struct dmi_system_id broken_systems[] = { 2634 static const struct dmi_system_id broken_systems[] = {
@@ -2745,6 +2789,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2745 if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) 2789 if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
2746 hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; 2790 hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
2747 2791
2792 /* apply ASUS M2A_VM quirk */
2793 if (ahci_asus_m2a_vm_32bit_only(pdev))
2794 hpriv->flags |= AHCI_HFLAG_32BIT_ONLY;
2795
2748 if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) 2796 if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
2749 pci_enable_msi(pdev); 2797 pci_enable_msi(pdev);
2750 2798
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 5f1b5400d96a..24c84ae81527 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -596,6 +596,7 @@ int dmi_get_year(int field)
596 596
597 return year; 597 return year;
598} 598}
599EXPORT_SYMBOL(dmi_get_year);
599 600
600/** 601/**
601 * dmi_walk - Walk the DMI table and get called back for every record 602 * dmi_walk - Walk the DMI table and get called back for every record