From 603037c3d1a42d5013f035355a2c60b0006a9fdf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 11 Mar 2010 11:37:16 +0900 Subject: ahci: add missing nv IDs bko#15481 shows that we're missing some NVIDIA ahci PCI IDs. Peer Chen confirms that IDs 0x580-0x58f are reserved for cases where Linux ID option is selected in the BIOS and are only used for mcp65-73. Add 0x0581-0x058f. http://bugzilla.kernel.org/show_bug.cgi?id=15481 Signed-off-by: Tejun Heo Cc: Peer Chen Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6bd930b..9e5b121 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -641,6 +641,21 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */ { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */ { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0581), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0582), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0583), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0584), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0585), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0586), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0587), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0588), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0589), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058a), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058b), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058c), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058d), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058e), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058f), board_ahci_yesncq }, /* Linux ID */ { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */ { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */ { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */ -- cgit v0.10.2 From 9deb343189b3cf45e84dd08480f330575ffe2004 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 16 Mar 2010 09:50:26 +0900 Subject: ahci: use BIOS date in broken_suspend list HP is recycling both DMI_PRODUCT_NAME and DMI_BIOS_VERSION making ahci_broken_suspend() trigger for later products which are not affected by the original problems. Match BIOS date instead of version and add references to bko's so that full information can be found easier later. This fixes http://bugzilla.kernel.org/show_bug.cgi?id=15462 Signed-off-by: Tejun Heo Reported-by: tigerfishdaisy@gmail.com Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 9e5b121..e7e2c7a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -3037,6 +3037,14 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) * On HP dv[4-6] and HDX18 with earlier BIOSen, link * to the harddisk doesn't become online after * resuming from STR. Warn and fail suspend. + * + * http://bugzilla.kernel.org/show_bug.cgi?id=12276 + * + * Use dates instead of versions to match as HP is + * apparently recycling both product and version + * strings. + * + * http://bugzilla.kernel.org/show_bug.cgi?id=15462 */ { .ident = "dv4", @@ -3045,7 +3053,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), }, - .driver_data = "F.30", /* cutoff BIOS version */ + .driver_data = "20090105", /* F.30 */ }, { .ident = "dv5", @@ -3054,7 +3062,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv5 Notebook PC"), }, - .driver_data = "F.16", /* cutoff BIOS version */ + .driver_data = "20090506", /* F.16 */ }, { .ident = "dv6", @@ -3063,7 +3071,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6 Notebook PC"), }, - .driver_data = "F.21", /* cutoff BIOS version */ + .driver_data = "20090423", /* F.21 */ }, { .ident = "HDX18", @@ -3072,7 +3080,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP HDX18 Notebook PC"), }, - .driver_data = "F.23", /* cutoff BIOS version */ + .driver_data = "20090430", /* F.23 */ }, /* * Acer eMachines G725 has the same problem. BIOS @@ -3080,6 +3088,8 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) * work. Inbetween, there are V1.06, V2.06 and V3.03 * that we don't have much idea about. For now, * blacklist anything older than V3.04. + * + * http://bugzilla.kernel.org/show_bug.cgi?id=15104 */ { .ident = "G725", @@ -3087,19 +3097,21 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_SYS_VENDOR, "eMachines"), DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"), }, - .driver_data = "V3.04", /* cutoff BIOS version */ + .driver_data = "20091216", /* V3.04 */ }, { } /* terminate list */ }; const struct dmi_system_id *dmi = dmi_first_match(sysids); - const char *ver; + int year, month, date; + char buf[9]; if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) return false; - ver = dmi_get_system_info(DMI_BIOS_VERSION); + dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); + snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); - return !ver || strcmp(ver, dmi->driver_data) < 0; + return strcmp(buf, dmi->driver_data) < 0; } static bool ahci_broken_online(struct pci_dev *pdev) -- cgit v0.10.2 From 5db5b0215af94a36d4bf10900ff9707b6d5c1610 Mon Sep 17 00:00:00 2001 From: Shane Huang Date: Tue, 16 Mar 2010 18:08:55 +0800 Subject: ahci: pp->active_link is not reliable when FBS is enabled pp->active_link is not reliable when FBS is enabled. Both PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because mixed NCQ and non-NCQ commands may be in flight. Signed-off-by: Shane Huang Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e7e2c7a..fdc9bcb 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -2278,7 +2278,7 @@ static void ahci_port_intr(struct ata_port *ap) struct ahci_port_priv *pp = ap->private_data; struct ahci_host_priv *hpriv = ap->host->private_data; int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); - u32 status, qc_active; + u32 status, qc_active = 0; int rc; status = readl(port_mmio + PORT_IRQ_STAT); @@ -2336,11 +2336,22 @@ static void ahci_port_intr(struct ata_port *ap) } } - /* pp->active_link is valid iff any command is in flight */ - if (ap->qc_active && pp->active_link->sactive) - qc_active = readl(port_mmio + PORT_SCR_ACT); - else - qc_active = readl(port_mmio + PORT_CMD_ISSUE); + /* pp->active_link is not reliable once FBS is enabled, both + * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because + * NCQ and non-NCQ commands may be in flight at the same time. + */ + if (pp->fbs_enabled) { + if (ap->qc_active) { + qc_active = readl(port_mmio + PORT_SCR_ACT); + qc_active |= readl(port_mmio + PORT_CMD_ISSUE); + } + } else { + /* pp->active_link is valid iff any command is in flight */ + if (ap->qc_active && pp->active_link->sactive) + qc_active = readl(port_mmio + PORT_SCR_ACT); + else + qc_active = readl(port_mmio + PORT_CMD_ISSUE); + } rc = ata_qc_complete_multiple(ap, qc_active); -- cgit v0.10.2