aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-12-07 15:53:15 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-12-07 15:53:15 -0500
commit94545baded0bfbabdc30a3a4cb48b3db479dd6ef (patch)
tree1ce09d319261627a03ce8ef75055f3f6a4a35ea7
parent7962024e9d16e9349d76b553326f3fa7be64305e (diff)
parent459ad68893a84fb0881e57919340b97edbbc3dc7 (diff)
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev: libata: kill spurious NCQ completion detection ahci: don't attach if ICH6 is in combined mode ata_piix: add Toshiba Tecra M4 to broken suspend list ahci: fix engine reset failed message
-rw-r--r--drivers/ata/ahci.c96
-rw-r--r--drivers/ata/ata_piix.c7
-rw-r--r--drivers/ata/libata-core.c18
3 files changed, 31 insertions, 90 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 4688dbf2d111..54f38c21dd95 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -193,6 +193,8 @@ enum {
193 ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | 193 ATA_FLAG_ACPI_SATA | ATA_FLAG_AN |
194 ATA_FLAG_IPM, 194 ATA_FLAG_IPM,
195 AHCI_LFLAG_COMMON = ATA_LFLAG_SKIP_D2H_BSY, 195 AHCI_LFLAG_COMMON = ATA_LFLAG_SKIP_D2H_BSY,
196
197 ICH_MAP = 0x90, /* ICH MAP register */
196}; 198};
197 199
198struct ahci_cmd_hdr { 200struct ahci_cmd_hdr {
@@ -1271,9 +1273,9 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
1271 1273
1272 /* prepare for SRST (AHCI-1.1 10.4.1) */ 1274 /* prepare for SRST (AHCI-1.1 10.4.1) */
1273 rc = ahci_kick_engine(ap, 1); 1275 rc = ahci_kick_engine(ap, 1);
1274 if (rc) 1276 if (rc && rc != -EOPNOTSUPP)
1275 ata_link_printk(link, KERN_WARNING, 1277 ata_link_printk(link, KERN_WARNING,
1276 "failed to reset engine (errno=%d)", rc); 1278 "failed to reset engine (errno=%d)\n", rc);
1277 1279
1278 ata_tf_init(link->device, &tf); 1280 ata_tf_init(link->device, &tf);
1279 1281
@@ -1638,7 +1640,7 @@ static void ahci_port_intr(struct ata_port *ap)
1638 struct ahci_host_priv *hpriv = ap->host->private_data; 1640 struct ahci_host_priv *hpriv = ap->host->private_data;
1639 int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); 1641 int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
1640 u32 status, qc_active; 1642 u32 status, qc_active;
1641 int rc, known_irq = 0; 1643 int rc;
1642 1644
1643 status = readl(port_mmio + PORT_IRQ_STAT); 1645 status = readl(port_mmio + PORT_IRQ_STAT);
1644 writel(status, port_mmio + PORT_IRQ_STAT); 1646 writel(status, port_mmio + PORT_IRQ_STAT);
@@ -1696,80 +1698,12 @@ static void ahci_port_intr(struct ata_port *ap)
1696 1698
1697 rc = ata_qc_complete_multiple(ap, qc_active, NULL); 1699 rc = ata_qc_complete_multiple(ap, qc_active, NULL);
1698 1700
1699 /* If resetting, spurious or invalid completions are expected, 1701 /* while resetting, invalid completions are expected */
1700 * return unconditionally. 1702 if (unlikely(rc < 0 && !resetting)) {
1701 */
1702 if (resetting)
1703 return;
1704
1705 if (rc > 0)
1706 return;
1707 if (rc < 0) {
1708 ehi->err_mask |= AC_ERR_HSM; 1703 ehi->err_mask |= AC_ERR_HSM;
1709 ehi->action |= ATA_EH_SOFTRESET; 1704 ehi->action |= ATA_EH_SOFTRESET;
1710 ata_port_freeze(ap); 1705 ata_port_freeze(ap);
1711 return;
1712 } 1706 }
1713
1714 /* hmmm... a spurious interrupt */
1715
1716 /* if !NCQ, ignore. No modern ATA device has broken HSM
1717 * implementation for non-NCQ commands.
1718 */
1719 if (!ap->link.sactive)
1720 return;
1721
1722 if (status & PORT_IRQ_D2H_REG_FIS) {
1723 if (!pp->ncq_saw_d2h)
1724 ata_port_printk(ap, KERN_INFO,
1725 "D2H reg with I during NCQ, "
1726 "this message won't be printed again\n");
1727 pp->ncq_saw_d2h = 1;
1728 known_irq = 1;
1729 }
1730
1731 if (status & PORT_IRQ_DMAS_FIS) {
1732 if (!pp->ncq_saw_dmas)
1733 ata_port_printk(ap, KERN_INFO,
1734 "DMAS FIS during NCQ, "
1735 "this message won't be printed again\n");
1736 pp->ncq_saw_dmas = 1;
1737 known_irq = 1;
1738 }
1739
1740 if (status & PORT_IRQ_SDB_FIS) {
1741 const __le32 *f = pp->rx_fis + RX_FIS_SDB;
1742
1743 if (le32_to_cpu(f[1])) {
1744 /* SDB FIS containing spurious completions
1745 * might be dangerous, whine and fail commands
1746 * with HSM violation. EH will turn off NCQ
1747 * after several such failures.
1748 */
1749 ata_ehi_push_desc(ehi,
1750 "spurious completions during NCQ "
1751 "issue=0x%x SAct=0x%x FIS=%08x:%08x",
1752 readl(port_mmio + PORT_CMD_ISSUE),
1753 readl(port_mmio + PORT_SCR_ACT),
1754 le32_to_cpu(f[0]), le32_to_cpu(f[1]));
1755 ehi->err_mask |= AC_ERR_HSM;
1756 ehi->action |= ATA_EH_SOFTRESET;
1757 ata_port_freeze(ap);
1758 } else {
1759 if (!pp->ncq_saw_sdb)
1760 ata_port_printk(ap, KERN_INFO,
1761 "spurious SDB FIS %08x:%08x during NCQ, "
1762 "this message won't be printed again\n",
1763 le32_to_cpu(f[0]), le32_to_cpu(f[1]));
1764 pp->ncq_saw_sdb = 1;
1765 }
1766 known_irq = 1;
1767 }
1768
1769 if (!known_irq)
1770 ata_port_printk(ap, KERN_INFO, "spurious interrupt "
1771 "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n",
1772 status, ap->link.active_tag, ap->link.sactive);
1773} 1707}
1774 1708
1775static void ahci_irq_clear(struct ata_port *ap) 1709static void ahci_irq_clear(struct ata_port *ap)
@@ -2273,6 +2207,22 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2273 if (rc) 2207 if (rc)
2274 return rc; 2208 return rc;
2275 2209
2210 if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
2211 (pdev->device == 0x2652 || pdev->device == 0x2653)) {
2212 u8 map;
2213
2214 /* ICH6s share the same PCI ID for both piix and ahci
2215 * modes. Enabling ahci mode while MAP indicates
2216 * combined mode is a bad idea. Yield to ata_piix.
2217 */
2218 pci_read_config_byte(pdev, ICH_MAP, &map);
2219 if (map & 0x3) {
2220 dev_printk(KERN_INFO, &pdev->dev, "controller is in "
2221 "combined mode, can't enable AHCI mode\n");
2222 return -ENODEV;
2223 }
2224 }
2225
2276 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); 2226 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
2277 if (!hpriv) 2227 if (!hpriv)
2278 return -ENOMEM; 2228 return -ENOMEM;
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index b538e1d22bf2..bb62a588f489 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -974,6 +974,13 @@ static int piix_broken_suspend(void)
974 }, 974 },
975 }, 975 },
976 { 976 {
977 .ident = "TECRA M4",
978 .matches = {
979 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
980 DMI_MATCH(DMI_PRODUCT_NAME, "Tecra M4"),
981 },
982 },
983 {
977 .ident = "TECRA M5", 984 .ident = "TECRA M5",
978 .matches = { 985 .matches = {
979 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 986 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b514a80f1370..e4dea8623a71 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4140,6 +4140,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
4140 /* Devices where NCQ should be avoided */ 4140 /* Devices where NCQ should be avoided */
4141 /* NCQ is slow */ 4141 /* NCQ is slow */
4142 { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ }, 4142 { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ },
4143 { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
4143 /* http://thread.gmane.org/gmane.linux.ide/14907 */ 4144 /* http://thread.gmane.org/gmane.linux.ide/14907 */
4144 { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ }, 4145 { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ },
4145 /* NCQ is broken */ 4146 /* NCQ is broken */
@@ -4154,23 +4155,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
4154 { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, }, 4155 { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, },
4155 { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, 4156 { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, },
4156 { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, 4157 { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, },
4157 /* Drives which do spurious command completion */
4158 { "HTS541680J9SA00", "SB2IC7EP", ATA_HORKAGE_NONCQ, },
4159 { "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, },
4160 { "HDT722516DLA380", "V43OA96A", ATA_HORKAGE_NONCQ, },
4161 { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
4162 { "Hitachi HTS542525K9SA00", "BBFOC31P", ATA_HORKAGE_NONCQ, },
4163 { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
4164 { "WDC WD3200AAJS-00RYA0", "12.01B01", ATA_HORKAGE_NONCQ, },
4165 { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, },
4166 { "ST9120822AS", "3.CLF", ATA_HORKAGE_NONCQ, },
4167 { "ST9160821AS", "3.CLF", ATA_HORKAGE_NONCQ, },
4168 { "ST9160821AS", "3.ALD", ATA_HORKAGE_NONCQ, },
4169 { "ST9160821AS", "3.CCD", ATA_HORKAGE_NONCQ, },
4170 { "ST3160812AS", "3.ADJ", ATA_HORKAGE_NONCQ, },
4171 { "ST980813AS", "3.ADB", ATA_HORKAGE_NONCQ, },
4172 { "SAMSUNG HD401LJ", "ZZ100-15", ATA_HORKAGE_NONCQ, },
4173 { "Maxtor 7V300F0", "VA111900", ATA_HORKAGE_NONCQ, },
4174 4158
4175 /* devices which puke on READ_NATIVE_MAX */ 4159 /* devices which puke on READ_NATIVE_MAX */
4176 { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, 4160 { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, },