Commit 58a09b38cfcd700b796ea07ae3d2e0efbb28b561

Authored by Shane Huang
Committed by Jeff Garzik
1 parent 7654db1a92

[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>

Showing 2 changed files with 51 additions and 2 deletions Side-by-side Diff

... ... @@ -431,8 +431,7 @@
431 431 [board_ahci_sb600] =
432 432 {
433 433 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
434   - AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
435   - AHCI_HFLAG_SECT255),
  434 + AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255),
436 435 .flags = AHCI_FLAG_COMMON,
437 436 .pio_mask = ATA_PIO4,
438 437 .udma_mask = ATA_UDMA6,
... ... @@ -2585,6 +2584,51 @@
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 + */
  2593 +static 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 +
2588 2632 static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
2589 2633 {
2590 2634 static const struct dmi_system_id broken_systems[] = {
... ... @@ -2744,6 +2788,10 @@
2744 2788 /* SB800 does NOT need the workaround to ignore SERR_INTERNAL */
2745 2789 if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
2746 2790 hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
  2791 +
  2792 + /* apply ASUS M2A_VM quirk */
  2793 + if (ahci_asus_m2a_vm_32bit_only(pdev))
  2794 + hpriv->flags |= AHCI_HFLAG_32BIT_ONLY;
2747 2795  
2748 2796 if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
2749 2797 pci_enable_msi(pdev);
drivers/firmware/dmi_scan.c
... ... @@ -596,6 +596,7 @@
596 596  
597 597 return year;
598 598 }
  599 +EXPORT_SYMBOL(dmi_get_year);
599 600  
600 601 /**
601 602 * dmi_walk - Walk the DMI table and get called back for every record