aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-09-15 15:18:03 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-10-06 00:26:29 -0400
commitf80ae7e45a0e03da188494c6e947a5c8b0cdfb4a (patch)
treef5e6e64cdce07c6e202ba3d0f96a54845550a031 /drivers/ata
parent110f66d25c33c2259b1125255fa7063ab07b8340 (diff)
ahci: filter FPDMA non-zero offset enable for Aspire 3810T
Curiously, Aspire 3810T issues many SATA feature enable commands via _GTF, of which one is invalid and another is not supported by the drive. In the process, it also enables FPDMA non-zero offset. However, the feature also needs to be supported and enabled from the controller and it's wrong to enable it from _GTF unless the controller can do it by default. Currently, this ends up enabling FPDMA non-zero offset only on the drive side leading to NCQ command failures and eventual disabling of NCQ. This patch makes libata filter out FPDMA non-zero offset enable for the machine. This was reported by Marcus Meissner in bnc#522790. https://bugzilla.novell.com/show_bug.cgi?id=522790 Reported-by: Marcus Meissner <meissner@novell.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index a47d309df2f2..4edca6eb73ae 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -2884,6 +2884,50 @@ static bool ahci_broken_online(struct pci_dev *pdev)
2884 return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); 2884 return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
2885} 2885}
2886 2886
2887static 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
2887static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 2931static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2888{ 2932{
2889 static int printed_version; 2933 static int printed_version;
@@ -3049,6 +3093,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
3049 /* apply workaround for ASUS P5W DH Deluxe mainboard */ 3093 /* apply workaround for ASUS P5W DH Deluxe mainboard */
3050 ahci_p5wdh_workaround(host); 3094 ahci_p5wdh_workaround(host);
3051 3095
3096 /* apply gtf filter quirk */
3097 ahci_gtf_filter_workaround(host);
3098
3052 /* initialize adapter */ 3099 /* initialize adapter */
3053 rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); 3100 rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
3054 if (rc) 3101 if (rc)