diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-08 15:22:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-08 15:22:45 -0400 |
commit | 36a07902c2134649c4af7f07980413ffb1a56085 (patch) | |
tree | be9c931f200aa3505647750ac87a6f8f124a5485 /drivers/ata/ahci.c | |
parent | f579bbcd9bb8b688df03191b92c56ab8af4d6322 (diff) | |
parent | 7affb32a32eabbbe42d6746923ec1d0bf7327234 (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
pata_atp867x: add Power Management support
pata_atp867x: PIO support fixes
pata_atp867x: clarifications in timings calculations and cable detection
pata_atp867x: fix it to not claim MWDMA support
libata: fix incorrect link online check during probe
ahci: filter FPDMA non-zero offset enable for Aspire 3810T
libata: make gtf_filter per-dev
libata: implement more acpi filtering options
libata: cosmetic updates
ahci: display all AHCI 1.3 HBA capability flags (v2)
pata_ali: trivial fix of a very frequent spelling mistake
ahci: disable 64bit DMA by default on SB600s
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 193 |
1 files changed, 133 insertions, 60 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index acd1162712b1..4edca6eb73ae 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -122,6 +122,7 @@ enum { | |||
122 | HOST_VERSION = 0x10, /* AHCI spec. version compliancy */ | 122 | HOST_VERSION = 0x10, /* AHCI spec. version compliancy */ |
123 | HOST_EM_LOC = 0x1c, /* Enclosure Management location */ | 123 | HOST_EM_LOC = 0x1c, /* Enclosure Management location */ |
124 | HOST_EM_CTL = 0x20, /* Enclosure Management Control */ | 124 | HOST_EM_CTL = 0x20, /* Enclosure Management Control */ |
125 | HOST_CAP2 = 0x24, /* host capabilities, extended */ | ||
125 | 126 | ||
126 | /* HOST_CTL bits */ | 127 | /* HOST_CTL bits */ |
127 | HOST_RESET = (1 << 0), /* reset controller; self-clear */ | 128 | HOST_RESET = (1 << 0), /* reset controller; self-clear */ |
@@ -129,16 +130,29 @@ enum { | |||
129 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ | 130 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ |
130 | 131 | ||
131 | /* HOST_CAP bits */ | 132 | /* HOST_CAP bits */ |
133 | HOST_CAP_SXS = (1 << 5), /* Supports External SATA */ | ||
132 | HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */ | 134 | HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */ |
133 | HOST_CAP_SSC = (1 << 14), /* Slumber capable */ | 135 | HOST_CAP_CCC = (1 << 7), /* Command Completion Coalescing */ |
136 | HOST_CAP_PART = (1 << 13), /* Partial state capable */ | ||
137 | HOST_CAP_SSC = (1 << 14), /* Slumber state capable */ | ||
138 | HOST_CAP_PIO_MULTI = (1 << 15), /* PIO multiple DRQ support */ | ||
139 | HOST_CAP_FBS = (1 << 16), /* FIS-based switching support */ | ||
134 | HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */ | 140 | HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */ |
141 | HOST_CAP_ONLY = (1 << 18), /* Supports AHCI mode only */ | ||
135 | HOST_CAP_CLO = (1 << 24), /* Command List Override support */ | 142 | HOST_CAP_CLO = (1 << 24), /* Command List Override support */ |
143 | HOST_CAP_LED = (1 << 25), /* Supports activity LED */ | ||
136 | HOST_CAP_ALPM = (1 << 26), /* Aggressive Link PM support */ | 144 | HOST_CAP_ALPM = (1 << 26), /* Aggressive Link PM support */ |
137 | HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ | 145 | HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ |
146 | HOST_CAP_MPS = (1 << 28), /* Mechanical presence switch */ | ||
138 | HOST_CAP_SNTF = (1 << 29), /* SNotification register */ | 147 | HOST_CAP_SNTF = (1 << 29), /* SNotification register */ |
139 | HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ | 148 | HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ |
140 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ | 149 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ |
141 | 150 | ||
151 | /* HOST_CAP2 bits */ | ||
152 | HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */ | ||
153 | HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */ | ||
154 | HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */ | ||
155 | |||
142 | /* registers for each SATA port */ | 156 | /* registers for each SATA port */ |
143 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ | 157 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ |
144 | PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */ | 158 | PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */ |
@@ -267,8 +281,10 @@ struct ahci_em_priv { | |||
267 | struct ahci_host_priv { | 281 | struct ahci_host_priv { |
268 | unsigned int flags; /* AHCI_HFLAG_* */ | 282 | unsigned int flags; /* AHCI_HFLAG_* */ |
269 | u32 cap; /* cap to use */ | 283 | u32 cap; /* cap to use */ |
284 | u32 cap2; /* cap2 to use */ | ||
270 | u32 port_map; /* port map to use */ | 285 | u32 port_map; /* port map to use */ |
271 | u32 saved_cap; /* saved initial cap */ | 286 | u32 saved_cap; /* saved initial cap */ |
287 | u32 saved_cap2; /* saved initial cap2 */ | ||
272 | u32 saved_port_map; /* saved initial port_map */ | 288 | u32 saved_port_map; /* saved initial port_map */ |
273 | u32 em_loc; /* enclosure management location */ | 289 | u32 em_loc; /* enclosure management location */ |
274 | }; | 290 | }; |
@@ -331,12 +347,15 @@ static void ahci_init_sw_activity(struct ata_link *link); | |||
331 | 347 | ||
332 | static ssize_t ahci_show_host_caps(struct device *dev, | 348 | static ssize_t ahci_show_host_caps(struct device *dev, |
333 | struct device_attribute *attr, char *buf); | 349 | struct device_attribute *attr, char *buf); |
350 | static ssize_t ahci_show_host_cap2(struct device *dev, | ||
351 | struct device_attribute *attr, char *buf); | ||
334 | static ssize_t ahci_show_host_version(struct device *dev, | 352 | static ssize_t ahci_show_host_version(struct device *dev, |
335 | struct device_attribute *attr, char *buf); | 353 | struct device_attribute *attr, char *buf); |
336 | static ssize_t ahci_show_port_cmd(struct device *dev, | 354 | static ssize_t ahci_show_port_cmd(struct device *dev, |
337 | struct device_attribute *attr, char *buf); | 355 | struct device_attribute *attr, char *buf); |
338 | 356 | ||
339 | DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); | 357 | DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); |
358 | DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); | ||
340 | DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); | 359 | DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); |
341 | DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); | 360 | DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); |
342 | 361 | ||
@@ -345,6 +364,7 @@ static struct device_attribute *ahci_shost_attrs[] = { | |||
345 | &dev_attr_em_message_type, | 364 | &dev_attr_em_message_type, |
346 | &dev_attr_em_message, | 365 | &dev_attr_em_message, |
347 | &dev_attr_ahci_host_caps, | 366 | &dev_attr_ahci_host_caps, |
367 | &dev_attr_ahci_host_cap2, | ||
348 | &dev_attr_ahci_host_version, | 368 | &dev_attr_ahci_host_version, |
349 | &dev_attr_ahci_port_cmd, | 369 | &dev_attr_ahci_port_cmd, |
350 | NULL | 370 | NULL |
@@ -447,7 +467,8 @@ static const struct ata_port_info ahci_port_info[] = { | |||
447 | [board_ahci_sb600] = | 467 | [board_ahci_sb600] = |
448 | { | 468 | { |
449 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | | 469 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | |
450 | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255), | 470 | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255 | |
471 | AHCI_HFLAG_32BIT_ONLY), | ||
451 | .flags = AHCI_FLAG_COMMON, | 472 | .flags = AHCI_FLAG_COMMON, |
452 | .pio_mask = ATA_PIO4, | 473 | .pio_mask = ATA_PIO4, |
453 | .udma_mask = ATA_UDMA6, | 474 | .udma_mask = ATA_UDMA6, |
@@ -732,6 +753,16 @@ static ssize_t ahci_show_host_caps(struct device *dev, | |||
732 | return sprintf(buf, "%x\n", hpriv->cap); | 753 | return sprintf(buf, "%x\n", hpriv->cap); |
733 | } | 754 | } |
734 | 755 | ||
756 | static ssize_t ahci_show_host_cap2(struct device *dev, | ||
757 | struct device_attribute *attr, char *buf) | ||
758 | { | ||
759 | struct Scsi_Host *shost = class_to_shost(dev); | ||
760 | struct ata_port *ap = ata_shost_to_port(shost); | ||
761 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
762 | |||
763 | return sprintf(buf, "%x\n", hpriv->cap2); | ||
764 | } | ||
765 | |||
735 | static ssize_t ahci_show_host_version(struct device *dev, | 766 | static ssize_t ahci_show_host_version(struct device *dev, |
736 | struct device_attribute *attr, char *buf) | 767 | struct device_attribute *attr, char *buf) |
737 | { | 768 | { |
@@ -771,7 +802,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
771 | struct ahci_host_priv *hpriv) | 802 | struct ahci_host_priv *hpriv) |
772 | { | 803 | { |
773 | void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; | 804 | void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; |
774 | u32 cap, port_map; | 805 | u32 cap, cap2, vers, port_map; |
775 | int i; | 806 | int i; |
776 | int mv; | 807 | int mv; |
777 | 808 | ||
@@ -784,6 +815,14 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
784 | hpriv->saved_cap = cap = readl(mmio + HOST_CAP); | 815 | hpriv->saved_cap = cap = readl(mmio + HOST_CAP); |
785 | hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL); | 816 | hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL); |
786 | 817 | ||
818 | /* CAP2 register is only defined for AHCI 1.2 and later */ | ||
819 | vers = readl(mmio + HOST_VERSION); | ||
820 | if ((vers >> 16) > 1 || | ||
821 | ((vers >> 16) == 1 && (vers & 0xFFFF) >= 0x200)) | ||
822 | hpriv->saved_cap2 = cap2 = readl(mmio + HOST_CAP2); | ||
823 | else | ||
824 | hpriv->saved_cap2 = cap2 = 0; | ||
825 | |||
787 | /* some chips have errata preventing 64bit use */ | 826 | /* some chips have errata preventing 64bit use */ |
788 | if ((cap & HOST_CAP_64) && (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)) { | 827 | if ((cap & HOST_CAP_64) && (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)) { |
789 | dev_printk(KERN_INFO, &pdev->dev, | 828 | dev_printk(KERN_INFO, &pdev->dev, |
@@ -869,6 +908,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
869 | 908 | ||
870 | /* record values to use during operation */ | 909 | /* record values to use during operation */ |
871 | hpriv->cap = cap; | 910 | hpriv->cap = cap; |
911 | hpriv->cap2 = cap2; | ||
872 | hpriv->port_map = port_map; | 912 | hpriv->port_map = port_map; |
873 | } | 913 | } |
874 | 914 | ||
@@ -887,6 +927,8 @@ static void ahci_restore_initial_config(struct ata_host *host) | |||
887 | void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; | 927 | void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; |
888 | 928 | ||
889 | writel(hpriv->saved_cap, mmio + HOST_CAP); | 929 | writel(hpriv->saved_cap, mmio + HOST_CAP); |
930 | if (hpriv->saved_cap2) | ||
931 | writel(hpriv->saved_cap2, mmio + HOST_CAP2); | ||
890 | writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL); | 932 | writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL); |
891 | (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ | 933 | (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ |
892 | } | 934 | } |
@@ -2534,13 +2576,14 @@ static void ahci_print_info(struct ata_host *host) | |||
2534 | struct ahci_host_priv *hpriv = host->private_data; | 2576 | struct ahci_host_priv *hpriv = host->private_data; |
2535 | struct pci_dev *pdev = to_pci_dev(host->dev); | 2577 | struct pci_dev *pdev = to_pci_dev(host->dev); |
2536 | void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; | 2578 | void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; |
2537 | u32 vers, cap, impl, speed; | 2579 | u32 vers, cap, cap2, impl, speed; |
2538 | const char *speed_s; | 2580 | const char *speed_s; |
2539 | u16 cc; | 2581 | u16 cc; |
2540 | const char *scc_s; | 2582 | const char *scc_s; |
2541 | 2583 | ||
2542 | vers = readl(mmio + HOST_VERSION); | 2584 | vers = readl(mmio + HOST_VERSION); |
2543 | cap = hpriv->cap; | 2585 | cap = hpriv->cap; |
2586 | cap2 = hpriv->cap2; | ||
2544 | impl = hpriv->port_map; | 2587 | impl = hpriv->port_map; |
2545 | 2588 | ||
2546 | speed = (cap >> 20) & 0xf; | 2589 | speed = (cap >> 20) & 0xf; |
@@ -2583,25 +2626,29 @@ static void ahci_print_info(struct ata_host *host) | |||
2583 | "flags: " | 2626 | "flags: " |
2584 | "%s%s%s%s%s%s%s" | 2627 | "%s%s%s%s%s%s%s" |
2585 | "%s%s%s%s%s%s%s" | 2628 | "%s%s%s%s%s%s%s" |
2586 | "%s\n" | 2629 | "%s%s%s%s%s%s\n" |
2587 | , | 2630 | , |
2588 | 2631 | ||
2589 | cap & (1 << 31) ? "64bit " : "", | 2632 | cap & HOST_CAP_64 ? "64bit " : "", |
2590 | cap & (1 << 30) ? "ncq " : "", | 2633 | cap & HOST_CAP_NCQ ? "ncq " : "", |
2591 | cap & (1 << 29) ? "sntf " : "", | 2634 | cap & HOST_CAP_SNTF ? "sntf " : "", |
2592 | cap & (1 << 28) ? "ilck " : "", | 2635 | cap & HOST_CAP_MPS ? "ilck " : "", |
2593 | cap & (1 << 27) ? "stag " : "", | 2636 | cap & HOST_CAP_SSS ? "stag " : "", |
2594 | cap & (1 << 26) ? "pm " : "", | 2637 | cap & HOST_CAP_ALPM ? "pm " : "", |
2595 | cap & (1 << 25) ? "led " : "", | 2638 | cap & HOST_CAP_LED ? "led " : "", |
2596 | 2639 | cap & HOST_CAP_CLO ? "clo " : "", | |
2597 | cap & (1 << 24) ? "clo " : "", | 2640 | cap & HOST_CAP_ONLY ? "only " : "", |
2598 | cap & (1 << 19) ? "nz " : "", | 2641 | cap & HOST_CAP_PMP ? "pmp " : "", |
2599 | cap & (1 << 18) ? "only " : "", | 2642 | cap & HOST_CAP_FBS ? "fbs " : "", |
2600 | cap & (1 << 17) ? "pmp " : "", | 2643 | cap & HOST_CAP_PIO_MULTI ? "pio " : "", |
2601 | cap & (1 << 15) ? "pio " : "", | 2644 | cap & HOST_CAP_SSC ? "slum " : "", |
2602 | cap & (1 << 14) ? "slum " : "", | 2645 | cap & HOST_CAP_PART ? "part " : "", |
2603 | cap & (1 << 13) ? "part " : "", | 2646 | cap & HOST_CAP_CCC ? "ccc " : "", |
2604 | cap & (1 << 6) ? "ems ": "" | 2647 | cap & HOST_CAP_EMS ? "ems " : "", |
2648 | cap & HOST_CAP_SXS ? "sxs " : "", | ||
2649 | cap2 & HOST_CAP2_APST ? "apst " : "", | ||
2650 | cap2 & HOST_CAP2_NVMHCI ? "nvmp " : "", | ||
2651 | cap2 & HOST_CAP2_BOH ? "boh " : "" | ||
2605 | ); | 2652 | ); |
2606 | } | 2653 | } |
2607 | 2654 | ||
@@ -2650,17 +2697,15 @@ static void ahci_p5wdh_workaround(struct ata_host *host) | |||
2650 | } | 2697 | } |
2651 | } | 2698 | } |
2652 | 2699 | ||
2653 | /* | 2700 | /* only some SB600 ahci controllers can do 64bit DMA */ |
2654 | * SB600 ahci controller on certain boards can't do 64bit DMA with | 2701 | 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 | { | 2702 | { |
2659 | static const struct dmi_system_id sysids[] = { | 2703 | static const struct dmi_system_id sysids[] = { |
2660 | /* | 2704 | /* |
2661 | * The oldest version known to be broken is 0901 and | 2705 | * The oldest version known to be broken is 0901 and |
2662 | * working is 1501 which was released on 2007-10-26. | 2706 | * working is 1501 which was released on 2007-10-26. |
2663 | * Force 32bit DMA on anything older than 1501. | 2707 | * Enable 64bit DMA on 1501 and anything newer. |
2708 | * | ||
2664 | * Please read bko#9412 for more info. | 2709 | * Please read bko#9412 for more info. |
2665 | */ | 2710 | */ |
2666 | { | 2711 | { |
@@ -2672,48 +2717,29 @@ static bool ahci_sb600_32bit_only(struct pci_dev *pdev) | |||
2672 | }, | 2717 | }, |
2673 | .driver_data = "20071026", /* yyyymmdd */ | 2718 | .driver_data = "20071026", /* yyyymmdd */ |
2674 | }, | 2719 | }, |
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 | { } | 2720 | { } |
2692 | }; | 2721 | }; |
2693 | const struct dmi_system_id *match; | 2722 | const struct dmi_system_id *match; |
2723 | int year, month, date; | ||
2724 | char buf[9]; | ||
2694 | 2725 | ||
2695 | match = dmi_first_match(sysids); | 2726 | match = dmi_first_match(sysids); |
2696 | if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) || | 2727 | if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) || |
2697 | !match) | 2728 | !match) |
2698 | return false; | 2729 | return false; |
2699 | 2730 | ||
2700 | if (match->driver_data) { | 2731 | dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); |
2701 | int year, month, date; | 2732 | 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 | 2733 | ||
2734 | if (strcmp(buf, match->driver_data) >= 0) { | ||
2735 | dev_printk(KERN_WARNING, &pdev->dev, "%s: enabling 64bit DMA\n", | ||
2736 | match->ident); | ||
2737 | return true; | ||
2738 | } else { | ||
2710 | dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, " | 2739 | dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, " |
2711 | "forcing 32bit DMA, update BIOS\n", match->ident); | 2740 | "forcing 32bit DMA, update BIOS\n", match->ident); |
2712 | } else | 2741 | return false; |
2713 | dev_printk(KERN_WARNING, &pdev->dev, "%s: this board can't " | 2742 | } |
2714 | "do 64bit DMA, forcing 32bit\n", match->ident); | ||
2715 | |||
2716 | return true; | ||
2717 | } | 2743 | } |
2718 | 2744 | ||
2719 | static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | 2745 | static bool ahci_broken_system_poweroff(struct pci_dev *pdev) |
@@ -2858,6 +2884,50 @@ static bool ahci_broken_online(struct pci_dev *pdev) | |||
2858 | return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); | 2884 | return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); |
2859 | } | 2885 | } |
2860 | 2886 | ||
2887 | static void ahci_gtf_filter_workaround(struct ata_host *host) | ||
2888 | { | ||
2889 | static const struct dmi_system_id sysids[] = { | ||
2890 | /* | ||
2891 | * Aspire 3810T issues a bunch of SATA enable commands | ||
2892 | * via _GTF including an invalid one and one which is | ||
2893 | * rejected by the device. Among the successful ones | ||
2894 | * is FPDMA non-zero offset enable which when enabled | ||
2895 | * only on the drive side leads to NCQ command | ||
2896 | * failures. Filter it out. | ||
2897 | */ | ||
2898 | { | ||
2899 | .ident = "Aspire 3810T", | ||
2900 | .matches = { | ||
2901 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
2902 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3810T"), | ||
2903 | }, | ||
2904 | .driver_data = (void *)ATA_ACPI_FILTER_FPDMA_OFFSET, | ||
2905 | }, | ||
2906 | { } | ||
2907 | }; | ||
2908 | const struct dmi_system_id *dmi = dmi_first_match(sysids); | ||
2909 | unsigned int filter; | ||
2910 | int i; | ||
2911 | |||
2912 | if (!dmi) | ||
2913 | return; | ||
2914 | |||
2915 | filter = (unsigned long)dmi->driver_data; | ||
2916 | dev_printk(KERN_INFO, host->dev, | ||
2917 | "applying extra ACPI _GTF filter 0x%x for %s\n", | ||
2918 | filter, dmi->ident); | ||
2919 | |||
2920 | for (i = 0; i < host->n_ports; i++) { | ||
2921 | struct ata_port *ap = host->ports[i]; | ||
2922 | struct ata_link *link; | ||
2923 | struct ata_device *dev; | ||
2924 | |||
2925 | ata_for_each_link(link, ap, EDGE) | ||
2926 | ata_for_each_dev(dev, link, ALL) | ||
2927 | dev->gtf_filter |= filter; | ||
2928 | } | ||
2929 | } | ||
2930 | |||
2861 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2931 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2862 | { | 2932 | { |
2863 | static int printed_version; | 2933 | static int printed_version; |
@@ -2926,9 +2996,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) | 2996 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) |
2927 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; | 2997 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; |
2928 | 2998 | ||
2929 | /* apply sb600 32bit only quirk */ | 2999 | /* only some SB600s can do 64bit DMA */ |
2930 | if (ahci_sb600_32bit_only(pdev)) | 3000 | if (ahci_sb600_enable_64bit(pdev)) |
2931 | hpriv->flags |= AHCI_HFLAG_32BIT_ONLY; | 3001 | hpriv->flags &= ~AHCI_HFLAG_32BIT_ONLY; |
2932 | 3002 | ||
2933 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) | 3003 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) |
2934 | pci_intx(pdev, 1); | 3004 | pci_intx(pdev, 1); |
@@ -3023,6 +3093,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3023 | /* apply workaround for ASUS P5W DH Deluxe mainboard */ | 3093 | /* apply workaround for ASUS P5W DH Deluxe mainboard */ |
3024 | ahci_p5wdh_workaround(host); | 3094 | ahci_p5wdh_workaround(host); |
3025 | 3095 | ||
3096 | /* apply gtf filter quirk */ | ||
3097 | ahci_gtf_filter_workaround(host); | ||
3098 | |||
3026 | /* initialize adapter */ | 3099 | /* initialize adapter */ |
3027 | rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); | 3100 | rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); |
3028 | if (rc) | 3101 | if (rc) |