diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ahci.c | 60 |
1 files changed, 20 insertions, 40 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index acd1162712b1..c95015986c94 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -447,7 +447,8 @@ static const struct ata_port_info ahci_port_info[] = { | |||
447 | [board_ahci_sb600] = | 447 | [board_ahci_sb600] = |
448 | { | 448 | { |
449 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | | 449 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | |
450 | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255), | 450 | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255 | |
451 | AHCI_HFLAG_32BIT_ONLY), | ||
451 | .flags = AHCI_FLAG_COMMON, | 452 | .flags = AHCI_FLAG_COMMON, |
452 | .pio_mask = ATA_PIO4, | 453 | .pio_mask = ATA_PIO4, |
453 | .udma_mask = ATA_UDMA6, | 454 | .udma_mask = ATA_UDMA6, |
@@ -2650,17 +2651,15 @@ static void ahci_p5wdh_workaround(struct ata_host *host) | |||
2650 | } | 2651 | } |
2651 | } | 2652 | } |
2652 | 2653 | ||
2653 | /* | 2654 | /* only some SB600 ahci controllers can do 64bit DMA */ |
2654 | * SB600 ahci controller on certain boards can't do 64bit DMA with | 2655 | static bool ahci_sb600_enable_64bit(struct pci_dev *pdev) |
2655 | * older BIOS. | ||
2656 | */ | ||
2657 | static bool ahci_sb600_32bit_only(struct pci_dev *pdev) | ||
2658 | { | 2656 | { |
2659 | static const struct dmi_system_id sysids[] = { | 2657 | static const struct dmi_system_id sysids[] = { |
2660 | /* | 2658 | /* |
2661 | * The oldest version known to be broken is 0901 and | 2659 | * The oldest version known to be broken is 0901 and |
2662 | * working is 1501 which was released on 2007-10-26. | 2660 | * working is 1501 which was released on 2007-10-26. |
2663 | * Force 32bit DMA on anything older than 1501. | 2661 | * Enable 64bit DMA on 1501 and anything newer. |
2662 | * | ||
2664 | * Please read bko#9412 for more info. | 2663 | * Please read bko#9412 for more info. |
2665 | */ | 2664 | */ |
2666 | { | 2665 | { |
@@ -2672,48 +2671,29 @@ static bool ahci_sb600_32bit_only(struct pci_dev *pdev) | |||
2672 | }, | 2671 | }, |
2673 | .driver_data = "20071026", /* yyyymmdd */ | 2672 | .driver_data = "20071026", /* yyyymmdd */ |
2674 | }, | 2673 | }, |
2675 | /* | ||
2676 | * It's yet unknown whether more recent BIOS fixes the | ||
2677 | * problem. Blacklist the whole board for the time | ||
2678 | * being. Please read the following thread for more | ||
2679 | * info. | ||
2680 | * | ||
2681 | * http://thread.gmane.org/gmane.linux.ide/42326 | ||
2682 | */ | ||
2683 | { | ||
2684 | .ident = "Gigabyte GA-MA69VM-S2", | ||
2685 | .matches = { | ||
2686 | DMI_MATCH(DMI_BOARD_VENDOR, | ||
2687 | "Gigabyte Technology Co., Ltd."), | ||
2688 | DMI_MATCH(DMI_BOARD_NAME, "GA-MA69VM-S2"), | ||
2689 | }, | ||
2690 | }, | ||
2691 | { } | 2674 | { } |
2692 | }; | 2675 | }; |
2693 | const struct dmi_system_id *match; | 2676 | const struct dmi_system_id *match; |
2677 | int year, month, date; | ||
2678 | char buf[9]; | ||
2694 | 2679 | ||
2695 | match = dmi_first_match(sysids); | 2680 | match = dmi_first_match(sysids); |
2696 | if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) || | 2681 | if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) || |
2697 | !match) | 2682 | !match) |
2698 | return false; | 2683 | return false; |
2699 | 2684 | ||
2700 | if (match->driver_data) { | 2685 | dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); |
2701 | int year, month, date; | 2686 | snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); |
2702 | char buf[9]; | ||
2703 | |||
2704 | dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); | ||
2705 | snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); | ||
2706 | |||
2707 | if (strcmp(buf, match->driver_data) >= 0) | ||
2708 | return false; | ||
2709 | 2687 | ||
2688 | if (strcmp(buf, match->driver_data) >= 0) { | ||
2689 | dev_printk(KERN_WARNING, &pdev->dev, "%s: enabling 64bit DMA\n", | ||
2690 | match->ident); | ||
2691 | return true; | ||
2692 | } else { | ||
2710 | dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, " | 2693 | dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, " |
2711 | "forcing 32bit DMA, update BIOS\n", match->ident); | 2694 | "forcing 32bit DMA, update BIOS\n", match->ident); |
2712 | } else | 2695 | return false; |
2713 | dev_printk(KERN_WARNING, &pdev->dev, "%s: this board can't " | 2696 | } |
2714 | "do 64bit DMA, forcing 32bit\n", match->ident); | ||
2715 | |||
2716 | return true; | ||
2717 | } | 2697 | } |
2718 | 2698 | ||
2719 | static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | 2699 | static bool ahci_broken_system_poweroff(struct pci_dev *pdev) |
@@ -2926,9 +2906,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2926 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) | 2906 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) |
2927 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; | 2907 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; |
2928 | 2908 | ||
2929 | /* apply sb600 32bit only quirk */ | 2909 | /* only some SB600s can do 64bit DMA */ |
2930 | if (ahci_sb600_32bit_only(pdev)) | 2910 | if (ahci_sb600_enable_64bit(pdev)) |
2931 | hpriv->flags |= AHCI_HFLAG_32BIT_ONLY; | 2911 | hpriv->flags &= ~AHCI_HFLAG_32BIT_ONLY; |
2932 | 2912 | ||
2933 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) | 2913 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) |
2934 | pci_intx(pdev, 1); | 2914 | pci_intx(pdev, 1); |