ahci: make ahci_asus_m2a_vm_32bit_only() quirk more generic

It turns out ASUS M2A-VM isn't the only one with the 32bit DMA
problem.  Make ahci_asus_m2a_vm_32bit_only() more generic using the
new dmi_get_date() and rename it to ahci_sb600_32bit_only().  Cut off
date is now pointed to by dmi_system_id->driver_data in "yyyymmdd"
format and it's now also allowed to be omitted.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Sandor Bodo-Merle <sbodomerle@gmail.com>
Cc: Shane Huang <shane.huang@amd.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
Tejun Heo 2009-08-16 21:04:02 +09:00 committed by Jeff Garzik
parent 3e5cd1f257
commit 03d783bf55
1 changed files with 29 additions and 24 deletions

View File

@ -2647,14 +2647,18 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
} }
/* /*
* SB600 ahci controller on ASUS M2A-VM can't do 64bit DMA with older * SB600 ahci controller on certain boards can't do 64bit DMA with
* BIOS. The oldest version known to be broken is 0901 and working is * older BIOS.
* 1501 which was released on 2007-10-26. Force 32bit DMA on anything
* older than 1501. Please read bko#9412 for more info.
*/ */
static bool ahci_asus_m2a_vm_32bit_only(struct pci_dev *pdev) 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
* working is 1501 which was released on 2007-10-26.
* Force 32bit DMA on anything older than 1501.
* Please read bko#9412 for more info.
*/
{ {
.ident = "ASUS M2A-VM", .ident = "ASUS M2A-VM",
.matches = { .matches = {
@ -2662,31 +2666,32 @@ static bool ahci_asus_m2a_vm_32bit_only(struct pci_dev *pdev)
"ASUSTeK Computer INC."), "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "M2A-VM"), DMI_MATCH(DMI_BOARD_NAME, "M2A-VM"),
}, },
.driver_data = "20071026", /* yyyymmdd */
}, },
{ } { }
}; };
const char *cutoff_mmdd = "10/26"; const struct dmi_system_id *match;
const char *date;
int year;
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) ||
!dmi_check_system(sysids)) !match)
return false; return false;
/* if (match->driver_data) {
* Argh.... both version and date are free form strings. int year, month, date;
* Let's hope they're using the same date format across char buf[9];
* different versions.
*/
date = dmi_get_system_info(DMI_BIOS_DATE);
dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL);
if (date && strlen(date) >= 10 && date[2] == '/' && date[5] == '/' &&
(year > 2007 ||
(year == 2007 && strncmp(date, cutoff_mmdd, 5) >= 0)))
return false;
dev_printk(KERN_WARNING, &pdev->dev, "ASUS M2A-VM: BIOS too old, " dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
"forcing 32bit DMA, update BIOS\n"); snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
if (strcmp(buf, match->driver_data) >= 0)
return false;
dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, "
"forcing 32bit DMA, update BIOS\n", match->ident);
} else
dev_printk(KERN_WARNING, &pdev->dev, "%s: this board can't "
"do 64bit DMA, forcing 32bit\n", match->ident);
return true; return true;
} }
@ -2901,8 +2906,8 @@ 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 ASUS M2A_VM quirk */ /* apply sb600 32bit only quirk */
if (ahci_asus_m2a_vm_32bit_only(pdev)) if (ahci_sb600_32bit_only(pdev))
hpriv->flags |= AHCI_HFLAG_32BIT_ONLY; hpriv->flags |= AHCI_HFLAG_32BIT_ONLY;
if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))