diff options
author | Shane Huang <shane.huang@amd.com> | 2009-08-07 03:05:52 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-09-11 02:31:52 -0400 |
commit | 78d5ae39af19a02a3d16213c0f62930d9a5d25f7 (patch) | |
tree | e74c4be53167bd7d7efe9ad4188062831d0ab8be /drivers/ata | |
parent | 02cb009bb942007b76c38da4cc2ca0a0a974c667 (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/ata')
-rw-r--r-- | drivers/ata/ahci.c | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5fb9c3a1f40..d4cd9c20331 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 | ||
1637 | static int ahci_kick_engine(struct ata_port *ap, int force_restart) | 1637 | static 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 | ||
2327 | static void ahci_pmp_attach(struct ata_port *ap) | 2325 | static void ahci_pmp_attach(struct ata_port *ap) |