All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Lord <liml@rtr.ca>
To: IDE/ATA development list <linux-ide@vger.kernel.org>,
	Jeff Garzik <jgarzik@pobox.com>, Tejun Heo <htejun@gmail.com>
Subject: [PATCH 2/5] sata_mv clean up mv_stop_edma usage
Date: Mon, 31 Mar 2008 19:34:40 -0400	[thread overview]
Message-ID: <47F17510.7060902@rtr.ca> (raw)
In-Reply-To: <47F1736F.8020104@rtr.ca>

Clean up uses of mv_stop_edma{_engine}() to match datasheet requirements.

Signed-off-by: Mark Lord <mlord@pobox.com>
---

--- old/drivers/ata/sata_mv.c	2008-03-31 17:18:15.000000000 -0400
+++ linux/drivers/ata/sata_mv.c	2008-03-31 18:12:56.000000000 -0400
@@ -517,7 +517,7 @@
 static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
 			     unsigned int port_no);
 static int mv_stop_edma(struct ata_port *ap);
-static int mv_stop_edma_engine(struct ata_port *ap);
+static int mv_stop_edma_engine(void __iomem *port_mmio);
 static void mv_edma_cfg(struct ata_port *ap, int want_ncq);
 
 /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below
@@ -805,7 +805,7 @@
 	if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
 		int using_ncq = ((pp->pp_flags & MV_PP_FLAG_NCQ_EN) != 0);
 		if (want_ncq != using_ncq)
-			mv_stop_edma_engine(ap);
+			mv_stop_edma(ap);
 	}
 	if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
 		struct mv_host_priv *hpriv = ap->host->private_data;
@@ -841,57 +841,41 @@
 
 /**
  *      mv_stop_edma_engine - Disable eDMA engine
- *      @ap: ATA channel to manipulate
- *
- *      Verify the local cache of the eDMA state is accurate with a
- *      WARN_ON.
+ *      @port_mmio: io base address
  *
  *      LOCKING:
  *      Inherited from caller.
  */
-static int mv_stop_edma_engine(struct ata_port *ap)
+static int mv_stop_edma_engine(void __iomem *port_mmio)
 {
-	void __iomem *port_mmio = mv_ap_base(ap);
-	struct mv_port_priv *pp	= ap->private_data;
-	u32 reg;
-	int i, err = 0;
+	int i;
 
-	if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
-		/* Disable EDMA if active.   The disable bit auto clears.
-		 */
-		writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
-		pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
-	} else {
-		WARN_ON(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS));
-	}
+	/* Disable eDMA.  The disable bit auto clears. */
+	writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
 
-	/* now properly wait for the eDMA to stop */
-	for (i = 1000; i > 0; i--) {
-		reg = readl(port_mmio + EDMA_CMD_OFS);
+	/* Wait for the chip to confirm eDMA is off. */
+	for (i = 10000; i > 0; i--) {
+		u32 reg = readl(port_mmio + EDMA_CMD_OFS);
 		if (!(reg & EDMA_EN))
-			break;
-
-		udelay(100);
-	}
-
-	if (reg & EDMA_EN) {
-		ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
-		err = -EIO;
+			return 0;
+		udelay(10);
 	}
-
-	return err;
+	return -EIO;
 }
 
 static int mv_stop_edma(struct ata_port *ap)
 {
-	unsigned long flags;
-	int rc;
-
-	spin_lock_irqsave(&ap->host->lock, flags);
-	rc = mv_stop_edma_engine(ap);
-	spin_unlock_irqrestore(&ap->host->lock, flags);
+	void __iomem *port_mmio = mv_ap_base(ap);
+	struct mv_port_priv *pp = ap->private_data;
 
-	return rc;
+	if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
+		return 0;
+	pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+	if (mv_stop_edma_engine(port_mmio)) {
+		ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
+		return -EIO;
+	}
+	return 0;
 }
 
 #ifdef ATA_DEBUG
@@ -1401,7 +1385,7 @@
 		 * port.  Turn off EDMA so there won't be problems accessing
 		 * shadow block, etc registers.
 		 */
-		mv_stop_edma_engine(ap);
+		mv_stop_edma(ap);
 		return ata_qc_issue_prot(qc);
 	}
 
@@ -1915,8 +1899,12 @@
 {
 	void __iomem *port_mmio = mv_port_base(mmio, port);
 
-	writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
-
+	/*
+	 * The datasheet warns against setting ATA_RST when EDMA is active
+	 * (but doesn't say what the problem might be).  So we first try
+	 * to disable the EDMA engine before doing the ATA_RST operation.
+	 */
+	mv_stop_edma_engine(port_mmio);
 	mv_reset_channel(hpriv, mmio, port);
 
 	ZERO(0x028);	/* command */
@@ -2191,8 +2179,12 @@
 {
 	void __iomem *port_mmio = mv_port_base(mmio, port);
 
-	writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
-
+	/*
+	 * The datasheet warns against setting ATA_RST when EDMA is active
+	 * (but doesn't say what the problem might be).  So we first try
+	 * to disable the EDMA engine before doing the ATA_RST operation.
+	 */
+	mv_stop_edma_engine(port_mmio);
 	mv_reset_channel(hpriv, mmio, port);
 
 	ZERO(0x028);		/* command */
@@ -2250,6 +2242,10 @@
 	return;
 }
 
+/*
+ * Caller must ensure that EDMA is not active,
+ * by first doing mv_stop_edma() where needed.
+ */
 static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
 			     unsigned int port_no)
 {
@@ -2392,10 +2388,11 @@
 {
 	struct ata_port *ap = link->ap;
 	struct mv_host_priv *hpriv = ap->host->private_data;
+	struct mv_port_priv *pp = ap->private_data;
 	void __iomem *mmio = hpriv->base;
 
-	mv_stop_edma(ap);
 	mv_reset_channel(hpriv, mmio, ap->port_no);
+	pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
 	mv_phy_reset(ap, class, deadline);
 
 	return 0;

  parent reply	other threads:[~2008-03-31 23:34 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-31 23:27 [PATCH 0/5] sata_mv cleanups Mark Lord
2008-03-31 23:33 ` [PATCH 1/5] sata_mv cosmetic fixes Mark Lord
2008-04-04  7:56   ` Jeff Garzik
2008-03-31 23:34 ` Mark Lord [this message]
2008-04-02  1:59   ` [PATCH 2/5] sata_mv clean up mv_stop_edma usage Tejun Heo
2008-04-02 19:33     ` Mark Lord
2008-04-02 19:42       ` Jeff Garzik
2008-04-02 19:47         ` Mark Lord
2008-04-03  0:47           ` Tejun Heo
2008-04-04  7:59   ` Jeff Garzik
2008-03-31 23:35 ` [PATCH 3/5] sata_mv fix ifctl handling Mark Lord
2008-03-31 23:35 ` [PATCH 4/5] sata_mv new mv_sata_hardreset handler Mark Lord
2008-04-02  2:31   ` Tejun Heo
2008-04-02 19:33     ` Mark Lord
2008-04-02 19:51     ` Mark Lord
2008-04-03  0:49       ` Tejun Heo
2008-04-03  2:48         ` Mark Lord
2008-04-03  3:15           ` Tejun Heo
2008-04-03 14:01             ` Mark Lord
2008-04-03 14:04               ` Mark Lord
2008-04-03 14:09                 ` Tejun Heo
2008-04-03 14:21                   ` Mark Lord
2008-04-03 14:35                     ` Tejun Heo
2008-04-03 15:05                       ` Mark Lord
2008-04-03 14:05               ` Tejun Heo
2008-03-31 23:36 ` [PATCH 5/5] sata_mv remove mv_phy_reset and mv_postreset Mark Lord
2008-04-04  8:02   ` Jeff Garzik
2008-04-04 14:25     ` Mark Lord
2008-04-11  0:21     ` [PATCH] sata_mv rework hardreset sequence Mark Lord
2008-04-16  1:17       ` Mark Lord

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47F17510.7060902@rtr.ca \
    --to=liml@rtr.ca \
    --cc=htejun@gmail.com \
    --cc=jgarzik@pobox.com \
    --cc=linux-ide@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.