aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorShane Huang <shane.huang@amd.com>2009-08-07 03:05:52 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-09-11 02:31:52 -0400
commit78d5ae39af19a02a3d16213c0f62930d9a5d25f7 (patch)
treee74c4be53167bd7d7efe9ad4188062831d0ab8be /drivers
parent02cb009bb942007b76c38da4cc2ca0a0a974c667 (diff)
ahci: kill @force_restart and refine CLO for ahci_kick_engine()
This patch refines ahci_kick_engine() after discussion with Tejun about FBS(FIS-based switching) support preparation: a. Kill @force_restart and always kick the engine. The only case where @force_restart is zero is when it's called from ahci_p5wdh_hardreset() Actually at that point, BSY is pretty much guaranteed to be set. b. If PMP is attached, ignore busy and always do CLO. (AHCI-1.3 9.2) Signed-off-by: Shane Huang <shane.huang@amd.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 5fb9c3a1f404..d4cd9c203314 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1634,7 +1634,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
1634 pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); 1634 pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16);
1635} 1635}
1636 1636
1637static int ahci_kick_engine(struct ata_port *ap, int force_restart) 1637static int ahci_kick_engine(struct ata_port *ap)
1638{ 1638{
1639 void __iomem *port_mmio = ahci_port_base(ap); 1639 void __iomem *port_mmio = ahci_port_base(ap);
1640 struct ahci_host_priv *hpriv = ap->host->private_data; 1640 struct ahci_host_priv *hpriv = ap->host->private_data;
@@ -1642,18 +1642,16 @@ static int ahci_kick_engine(struct ata_port *ap, int force_restart)
1642 u32 tmp; 1642 u32 tmp;
1643 int busy, rc; 1643 int busy, rc;
1644 1644
1645 /* do we need to kick the port? */
1646 busy = status & (ATA_BUSY | ATA_DRQ);
1647 if (!busy && !force_restart)
1648 return 0;
1649
1650 /* stop engine */ 1645 /* stop engine */
1651 rc = ahci_stop_engine(ap); 1646 rc = ahci_stop_engine(ap);
1652 if (rc) 1647 if (rc)
1653 goto out_restart; 1648 goto out_restart;
1654 1649
1655 /* need to do CLO? */ 1650 /* need to do CLO?
1656 if (!busy) { 1651 * always do CLO if PMP is attached (AHCI-1.3 9.2)
1652 */
1653 busy = status & (ATA_BUSY | ATA_DRQ);
1654 if (!busy && !sata_pmp_attached(ap)) {
1657 rc = 0; 1655 rc = 0;
1658 goto out_restart; 1656 goto out_restart;
1659 } 1657 }
@@ -1701,7 +1699,7 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
1701 tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1699 tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1,
1702 1, timeout_msec); 1700 1, timeout_msec);
1703 if (tmp & 0x1) { 1701 if (tmp & 0x1) {
1704 ahci_kick_engine(ap, 1); 1702 ahci_kick_engine(ap);
1705 return -EBUSY; 1703 return -EBUSY;
1706 } 1704 }
1707 } else 1705 } else
@@ -1724,7 +1722,7 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
1724 DPRINTK("ENTER\n"); 1722 DPRINTK("ENTER\n");
1725 1723
1726 /* prepare for SRST (AHCI-1.1 10.4.1) */ 1724 /* prepare for SRST (AHCI-1.1 10.4.1) */
1727 rc = ahci_kick_engine(ap, 1); 1725 rc = ahci_kick_engine(ap);
1728 if (rc && rc != -EOPNOTSUPP) 1726 if (rc && rc != -EOPNOTSUPP)
1729 ata_link_printk(link, KERN_WARNING, 1727 ata_link_printk(link, KERN_WARNING,
1730 "failed to reset engine (errno=%d)\n", rc); 1728 "failed to reset engine (errno=%d)\n", rc);
@@ -1940,7 +1938,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
1940 rc = ata_wait_after_reset(link, jiffies + 2 * HZ, 1938 rc = ata_wait_after_reset(link, jiffies + 2 * HZ,
1941 ahci_check_ready); 1939 ahci_check_ready);
1942 if (rc) 1940 if (rc)
1943 ahci_kick_engine(ap, 0); 1941 ahci_kick_engine(ap);
1944 } 1942 }
1945 return rc; 1943 return rc;
1946} 1944}
@@ -2321,7 +2319,7 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
2321 2319
2322 /* make DMA engine forget about the failed command */ 2320 /* make DMA engine forget about the failed command */
2323 if (qc->flags & ATA_QCFLAG_FAILED) 2321 if (qc->flags & ATA_QCFLAG_FAILED)
2324 ahci_kick_engine(ap, 1); 2322 ahci_kick_engine(ap);
2325} 2323}
2326 2324
2327static void ahci_pmp_attach(struct ata_port *ap) 2325static void ahci_pmp_attach(struct ata_port *ap)