mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 12:16:20 +00:00
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>
This commit is contained in:
parent
110f66d25c
commit
f80ae7e45a
1 changed files with 47 additions and 0 deletions
|
@ -2884,6 +2884,50 @@ static bool ahci_broken_online(struct pci_dev *pdev)
|
||||||
return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
|
return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ahci_gtf_filter_workaround(struct ata_host *host)
|
||||||
|
{
|
||||||
|
static const struct dmi_system_id sysids[] = {
|
||||||
|
/*
|
||||||
|
* Aspire 3810T issues a bunch of SATA enable commands
|
||||||
|
* via _GTF including an invalid one and one which is
|
||||||
|
* rejected by the device. Among the successful ones
|
||||||
|
* is FPDMA non-zero offset enable which when enabled
|
||||||
|
* only on the drive side leads to NCQ command
|
||||||
|
* failures. Filter it out.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
.ident = "Aspire 3810T",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3810T"),
|
||||||
|
},
|
||||||
|
.driver_data = (void *)ATA_ACPI_FILTER_FPDMA_OFFSET,
|
||||||
|
},
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
const struct dmi_system_id *dmi = dmi_first_match(sysids);
|
||||||
|
unsigned int filter;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!dmi)
|
||||||
|
return;
|
||||||
|
|
||||||
|
filter = (unsigned long)dmi->driver_data;
|
||||||
|
dev_printk(KERN_INFO, host->dev,
|
||||||
|
"applying extra ACPI _GTF filter 0x%x for %s\n",
|
||||||
|
filter, dmi->ident);
|
||||||
|
|
||||||
|
for (i = 0; i < host->n_ports; i++) {
|
||||||
|
struct ata_port *ap = host->ports[i];
|
||||||
|
struct ata_link *link;
|
||||||
|
struct ata_device *dev;
|
||||||
|
|
||||||
|
ata_for_each_link(link, ap, EDGE)
|
||||||
|
ata_for_each_dev(dev, link, ALL)
|
||||||
|
dev->gtf_filter |= filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
static int printed_version;
|
static int printed_version;
|
||||||
|
@ -3049,6 +3093,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
/* apply workaround for ASUS P5W DH Deluxe mainboard */
|
/* apply workaround for ASUS P5W DH Deluxe mainboard */
|
||||||
ahci_p5wdh_workaround(host);
|
ahci_p5wdh_workaround(host);
|
||||||
|
|
||||||
|
/* apply gtf filter quirk */
|
||||||
|
ahci_gtf_filter_workaround(host);
|
||||||
|
|
||||||
/* initialize adapter */
|
/* initialize adapter */
|
||||||
rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
|
rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
|
Loading…
Reference in a new issue