aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r--drivers/ata/ahci.c100
1 files changed, 27 insertions, 73 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ed9b407e42d4..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 {
@@ -536,6 +538,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
536 { PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci }, /* MCP77 */ 538 { PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci }, /* MCP77 */
537 { PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci }, /* MCP77 */ 539 { PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci }, /* MCP77 */
538 { PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci }, /* MCP77 */ 540 { PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci }, /* MCP77 */
541 { PCI_VDEVICE(NVIDIA, 0x0ab4), board_ahci }, /* MCP79 */
542 { PCI_VDEVICE(NVIDIA, 0x0ab5), board_ahci }, /* MCP79 */
543 { PCI_VDEVICE(NVIDIA, 0x0ab6), board_ahci }, /* MCP79 */
544 { PCI_VDEVICE(NVIDIA, 0x0ab7), board_ahci }, /* MCP79 */
539 { PCI_VDEVICE(NVIDIA, 0x0ab8), board_ahci }, /* MCP79 */ 545 { PCI_VDEVICE(NVIDIA, 0x0ab8), board_ahci }, /* MCP79 */
540 { PCI_VDEVICE(NVIDIA, 0x0ab9), board_ahci }, /* MCP79 */ 546 { PCI_VDEVICE(NVIDIA, 0x0ab9), board_ahci }, /* MCP79 */
541 { PCI_VDEVICE(NVIDIA, 0x0aba), board_ahci }, /* MCP79 */ 547 { PCI_VDEVICE(NVIDIA, 0x0aba), board_ahci }, /* MCP79 */
@@ -1267,9 +1273,9 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
1267 1273
1268 /* prepare for SRST (AHCI-1.1 10.4.1) */ 1274 /* prepare for SRST (AHCI-1.1 10.4.1) */
1269 rc = ahci_kick_engine(ap, 1); 1275 rc = ahci_kick_engine(ap, 1);
1270 if (rc) 1276 if (rc && rc != -EOPNOTSUPP)
1271 ata_link_printk(link, KERN_WARNING, 1277 ata_link_printk(link, KERN_WARNING,
1272 "failed to reset engine (errno=%d)", rc); 1278 "failed to reset engine (errno=%d)\n", rc);
1273 1279
1274 ata_tf_init(link->device, &tf); 1280 ata_tf_init(link->device, &tf);
1275 1281
@@ -1634,7 +1640,7 @@ static void ahci_port_intr(struct ata_port *ap)
1634 struct ahci_host_priv *hpriv = ap->host->private_data; 1640 struct ahci_host_priv *hpriv = ap->host->private_data;
1635 int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); 1641 int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
1636 u32 status, qc_active; 1642 u32 status, qc_active;
1637 int rc, known_irq = 0; 1643 int rc;
1638 1644
1639 status = readl(port_mmio + PORT_IRQ_STAT); 1645 status = readl(port_mmio + PORT_IRQ_STAT);
1640 writel(status, port_mmio + PORT_IRQ_STAT); 1646 writel(status, port_mmio + PORT_IRQ_STAT);
@@ -1692,80 +1698,12 @@ static void ahci_port_intr(struct ata_port *ap)
1692 1698
1693 rc = ata_qc_complete_multiple(ap, qc_active, NULL); 1699 rc = ata_qc_complete_multiple(ap, qc_active, NULL);
1694 1700
1695 /* If resetting, spurious or invalid completions are expected, 1701 /* while resetting, invalid completions are expected */
1696 * return unconditionally. 1702 if (unlikely(rc < 0 && !resetting)) {
1697 */
1698 if (resetting)
1699 return;
1700
1701 if (rc > 0)
1702 return;
1703 if (rc < 0) {
1704 ehi->err_mask |= AC_ERR_HSM; 1703 ehi->err_mask |= AC_ERR_HSM;
1705 ehi->action |= ATA_EH_SOFTRESET; 1704 ehi->action |= ATA_EH_SOFTRESET;
1706 ata_port_freeze(ap); 1705 ata_port_freeze(ap);
1707 return;
1708 } 1706 }
1709
1710 /* hmmm... a spurious interrupt */
1711
1712 /* if !NCQ, ignore. No modern ATA device has broken HSM
1713 * implementation for non-NCQ commands.
1714 */
1715 if (!ap->link.sactive)
1716 return;
1717
1718 if (status & PORT_IRQ_D2H_REG_FIS) {
1719 if (!pp->ncq_saw_d2h)
1720 ata_port_printk(ap, KERN_INFO,
1721 "D2H reg with I during NCQ, "
1722 "this message won't be printed again\n");
1723 pp->ncq_saw_d2h = 1;
1724 known_irq = 1;
1725 }
1726
1727 if (status & PORT_IRQ_DMAS_FIS) {
1728 if (!pp->ncq_saw_dmas)
1729 ata_port_printk(ap, KERN_INFO,
1730 "DMAS FIS during NCQ, "
1731 "this message won't be printed again\n");
1732 pp->ncq_saw_dmas = 1;
1733 known_irq = 1;
1734 }
1735
1736 if (status & PORT_IRQ_SDB_FIS) {
1737 const __le32 *f = pp->rx_fis + RX_FIS_SDB;
1738
1739 if (le32_to_cpu(f[1])) {
1740 /* SDB FIS containing spurious completions
1741 * might be dangerous, whine and fail commands
1742 * with HSM violation. EH will turn off NCQ
1743 * after several such failures.
1744 */
1745 ata_ehi_push_desc(ehi,
1746 "spurious completions during NCQ "
1747 "issue=0x%x SAct=0x%x FIS=%08x:%08x",
1748 readl(port_mmio + PORT_CMD_ISSUE),
1749 readl(port_mmio + PORT_SCR_ACT),
1750 le32_to_cpu(f[0]), le32_to_cpu(f[1]));
1751 ehi->err_mask |= AC_ERR_HSM;
1752 ehi->action |= ATA_EH_SOFTRESET;
1753 ata_port_freeze(ap);
1754 } else {
1755 if (!pp->ncq_saw_sdb)
1756 ata_port_printk(ap, KERN_INFO,
1757 "spurious SDB FIS %08x:%08x during NCQ, "
1758 "this message won't be printed again\n",
1759 le32_to_cpu(f[0]), le32_to_cpu(f[1]));
1760 pp->ncq_saw_sdb = 1;
1761 }
1762 known_irq = 1;
1763 }
1764
1765 if (!known_irq)
1766 ata_port_printk(ap, KERN_INFO, "spurious interrupt "
1767 "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n",
1768 status, ap->link.active_tag, ap->link.sactive);
1769} 1707}
1770 1708
1771static void ahci_irq_clear(struct ata_port *ap) 1709static void ahci_irq_clear(struct ata_port *ap)
@@ -2269,6 +2207,22 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2269 if (rc) 2207 if (rc)
2270 return rc; 2208 return rc;
2271 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
2272 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); 2226 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
2273 if (!hpriv) 2227 if (!hpriv)
2274 return -ENOMEM; 2228 return -ENOMEM;