Commit 2fcad9d2 authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik

ahci: disable 64bit DMA by default on SB600s

Till now only one board, ASUS M2A-VM, can do 64bit dma with recent
BIOSen.  Enabling 64bit DMA by default already broke three boards.
Enabling 64bit DMA isn't worth these regressions.  Disable 64bit DMA
by default and enable it only on boards which are known to work.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Reported-by: default avatarGabriele Balducci <balducci@units.it>
Reported-by: maierp@informatik.tu-muenchen.de
Cc: Shane Huang <shane.huang@amd.com>
Cc: stable@kernel.org
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 19d031e0
...@@ -447,7 +447,8 @@ static const struct ata_port_info ahci_port_info[] = { ...@@ -447,7 +447,8 @@ static const struct ata_port_info ahci_port_info[] = {
[board_ahci_sb600] = [board_ahci_sb600] =
{ {
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255), AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255 |
AHCI_HFLAG_32BIT_ONLY),
.flags = AHCI_FLAG_COMMON, .flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6, .udma_mask = ATA_UDMA6,
...@@ -2650,17 +2651,15 @@ static void ahci_p5wdh_workaround(struct ata_host *host) ...@@ -2650,17 +2651,15 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
} }
} }
/* /* only some SB600 ahci controllers can do 64bit DMA */
* SB600 ahci controller on certain boards can't do 64bit DMA with static bool ahci_sb600_enable_64bit(struct pci_dev *pdev)
* older BIOS.
*/
static bool ahci_sb600_32bit_only(struct pci_dev *pdev)
{ {
static const struct dmi_system_id sysids[] = { static const struct dmi_system_id sysids[] = {
/* /*
* The oldest version known to be broken is 0901 and * The oldest version known to be broken is 0901 and
* working is 1501 which was released on 2007-10-26. * working is 1501 which was released on 2007-10-26.
* Force 32bit DMA on anything older than 1501. * Enable 64bit DMA on 1501 and anything newer.
*
* Please read bko#9412 for more info. * Please read bko#9412 for more info.
*/ */
{ {
...@@ -2672,48 +2671,29 @@ static bool ahci_sb600_32bit_only(struct pci_dev *pdev) ...@@ -2672,48 +2671,29 @@ static bool ahci_sb600_32bit_only(struct pci_dev *pdev)
}, },
.driver_data = "20071026", /* yyyymmdd */ .driver_data = "20071026", /* yyyymmdd */
}, },
/*
* It's yet unknown whether more recent BIOS fixes the
* problem. Blacklist the whole board for the time
* being. Please read the following thread for more
* info.
*
* http://thread.gmane.org/gmane.linux.ide/42326
*/
{
.ident = "Gigabyte GA-MA69VM-S2",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR,
"Gigabyte Technology Co., Ltd."),
DMI_MATCH(DMI_BOARD_NAME, "GA-MA69VM-S2"),
},
},
{ } { }
}; };
const struct dmi_system_id *match; const struct dmi_system_id *match;
int year, month, date;
char buf[9];
match = dmi_first_match(sysids); match = dmi_first_match(sysids);
if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) || if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) ||
!match) !match)
return false; return false;
if (match->driver_data) { dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
int year, month, date; snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
char buf[9];
dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
if (strcmp(buf, match->driver_data) >= 0)
return false;
if (strcmp(buf, match->driver_data) >= 0) {
dev_printk(KERN_WARNING, &pdev->dev, "%s: enabling 64bit DMA\n",
match->ident);
return true;
} else {
dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, " dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, "
"forcing 32bit DMA, update BIOS\n", match->ident); "forcing 32bit DMA, update BIOS\n", match->ident);
} else return false;
dev_printk(KERN_WARNING, &pdev->dev, "%s: this board can't " }
"do 64bit DMA, forcing 32bit\n", match->ident);
return true;
} }
static bool ahci_broken_system_poweroff(struct pci_dev *pdev) 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,9 +2906,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
/* apply sb600 32bit only quirk */ /* only some SB600s can do 64bit DMA */
if (ahci_sb600_32bit_only(pdev)) if (ahci_sb600_enable_64bit(pdev))
hpriv->flags |= AHCI_HFLAG_32BIT_ONLY; hpriv->flags &= ~AHCI_HFLAG_32BIT_ONLY;
if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
pci_intx(pdev, 1); pci_intx(pdev, 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment