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;
next prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).