aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2008-03-31 19:34:40 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:21 -0400
commitb562468cc3bd0c81decba1f5f39a7173f839e57e (patch)
tree60239c6f86eb2aa92e59d16f74c1dabd474d2046 /drivers/ata
parente12bef50b7660cf7c19d1cd3eac381b9eff734d7 (diff)
sata_mv clean up mv_stop_edma usage
Clean up uses of mv_stop_edma{_engine}() to match datasheet requirements. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_mv.c87
1 files changed, 42 insertions, 45 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index ee6ca97c4545..5b9f937d0f87 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -517,7 +517,7 @@ static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
517static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, 517static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
518 unsigned int port_no); 518 unsigned int port_no);
519static int mv_stop_edma(struct ata_port *ap); 519static int mv_stop_edma(struct ata_port *ap);
520static int mv_stop_edma_engine(struct ata_port *ap); 520static int mv_stop_edma_engine(void __iomem *port_mmio);
521static void mv_edma_cfg(struct ata_port *ap, int want_ncq); 521static void mv_edma_cfg(struct ata_port *ap, int want_ncq);
522 522
523/* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below 523/* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below
@@ -805,7 +805,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
805 if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { 805 if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
806 int using_ncq = ((pp->pp_flags & MV_PP_FLAG_NCQ_EN) != 0); 806 int using_ncq = ((pp->pp_flags & MV_PP_FLAG_NCQ_EN) != 0);
807 if (want_ncq != using_ncq) 807 if (want_ncq != using_ncq)
808 mv_stop_edma_engine(ap); 808 mv_stop_edma(ap);
809 } 809 }
810 if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { 810 if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
811 struct mv_host_priv *hpriv = ap->host->private_data; 811 struct mv_host_priv *hpriv = ap->host->private_data;
@@ -841,57 +841,41 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
841 841
842/** 842/**
843 * mv_stop_edma_engine - Disable eDMA engine 843 * mv_stop_edma_engine - Disable eDMA engine
844 * @ap: ATA channel to manipulate 844 * @port_mmio: io base address
845 *
846 * Verify the local cache of the eDMA state is accurate with a
847 * WARN_ON.
848 * 845 *
849 * LOCKING: 846 * LOCKING:
850 * Inherited from caller. 847 * Inherited from caller.
851 */ 848 */
852static int mv_stop_edma_engine(struct ata_port *ap) 849static int mv_stop_edma_engine(void __iomem *port_mmio)
853{ 850{
854 void __iomem *port_mmio = mv_ap_base(ap); 851 int i;
855 struct mv_port_priv *pp = ap->private_data;
856 u32 reg;
857 int i, err = 0;
858 852
859 if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { 853 /* Disable eDMA. The disable bit auto clears. */
860 /* Disable EDMA if active. The disable bit auto clears. 854 writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
861 */
862 writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
863 pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
864 } else {
865 WARN_ON(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS));
866 }
867 855
868 /* now properly wait for the eDMA to stop */ 856 /* Wait for the chip to confirm eDMA is off. */
869 for (i = 1000; i > 0; i--) { 857 for (i = 10000; i > 0; i--) {
870 reg = readl(port_mmio + EDMA_CMD_OFS); 858 u32 reg = readl(port_mmio + EDMA_CMD_OFS);
871 if (!(reg & EDMA_EN)) 859 if (!(reg & EDMA_EN))
872 break; 860 return 0;
873 861 udelay(10);
874 udelay(100);
875 }
876
877 if (reg & EDMA_EN) {
878 ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
879 err = -EIO;
880 } 862 }
881 863 return -EIO;
882 return err;
883} 864}
884 865
885static int mv_stop_edma(struct ata_port *ap) 866static int mv_stop_edma(struct ata_port *ap)
886{ 867{
887 unsigned long flags; 868 void __iomem *port_mmio = mv_ap_base(ap);
888 int rc; 869 struct mv_port_priv *pp = ap->private_data;
889
890 spin_lock_irqsave(&ap->host->lock, flags);
891 rc = mv_stop_edma_engine(ap);
892 spin_unlock_irqrestore(&ap->host->lock, flags);
893 870
894 return rc; 871 if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
872 return 0;
873 pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
874 if (mv_stop_edma_engine(port_mmio)) {
875 ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
876 return -EIO;
877 }
878 return 0;
895} 879}
896 880
897#ifdef ATA_DEBUG 881#ifdef ATA_DEBUG
@@ -1401,7 +1385,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
1401 * port. Turn off EDMA so there won't be problems accessing 1385 * port. Turn off EDMA so there won't be problems accessing
1402 * shadow block, etc registers. 1386 * shadow block, etc registers.
1403 */ 1387 */
1404 mv_stop_edma_engine(ap); 1388 mv_stop_edma(ap);
1405 return ata_qc_issue_prot(qc); 1389 return ata_qc_issue_prot(qc);
1406 } 1390 }
1407 1391
@@ -1915,8 +1899,12 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio,
1915{ 1899{
1916 void __iomem *port_mmio = mv_port_base(mmio, port); 1900 void __iomem *port_mmio = mv_port_base(mmio, port);
1917 1901
1918 writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); 1902 /*
1919 1903 * The datasheet warns against setting ATA_RST when EDMA is active
1904 * (but doesn't say what the problem might be). So we first try
1905 * to disable the EDMA engine before doing the ATA_RST operation.
1906 */
1907 mv_stop_edma_engine(port_mmio);
1920 mv_reset_channel(hpriv, mmio, port); 1908 mv_reset_channel(hpriv, mmio, port);
1921 1909
1922 ZERO(0x028); /* command */ 1910 ZERO(0x028); /* command */
@@ -2191,8 +2179,12 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv,
2191{ 2179{
2192 void __iomem *port_mmio = mv_port_base(mmio, port); 2180 void __iomem *port_mmio = mv_port_base(mmio, port);
2193 2181
2194 writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); 2182 /*
2195 2183 * The datasheet warns against setting ATA_RST when EDMA is active
2184 * (but doesn't say what the problem might be). So we first try
2185 * to disable the EDMA engine before doing the ATA_RST operation.
2186 */
2187 mv_stop_edma_engine(port_mmio);
2196 mv_reset_channel(hpriv, mmio, port); 2188 mv_reset_channel(hpriv, mmio, port);
2197 2189
2198 ZERO(0x028); /* command */ 2190 ZERO(0x028); /* command */
@@ -2250,6 +2242,10 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
2250 return; 2242 return;
2251} 2243}
2252 2244
2245/*
2246 * Caller must ensure that EDMA is not active,
2247 * by first doing mv_stop_edma() where needed.
2248 */
2253static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, 2249static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
2254 unsigned int port_no) 2250 unsigned int port_no)
2255{ 2251{
@@ -2392,10 +2388,11 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
2392{ 2388{
2393 struct ata_port *ap = link->ap; 2389 struct ata_port *ap = link->ap;
2394 struct mv_host_priv *hpriv = ap->host->private_data; 2390 struct mv_host_priv *hpriv = ap->host->private_data;
2391 struct mv_port_priv *pp = ap->private_data;
2395 void __iomem *mmio = hpriv->base; 2392 void __iomem *mmio = hpriv->base;
2396 2393
2397 mv_stop_edma(ap);
2398 mv_reset_channel(hpriv, mmio, ap->port_no); 2394 mv_reset_channel(hpriv, mmio, ap->port_no);
2395 pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
2399 mv_phy_reset(ap, class, deadline); 2396 mv_phy_reset(ap, class, deadline);
2400 2397
2401 return 0; 2398 return 0;