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 4/5] sata_mv new mv_sata_hardreset handler
Date: Mon, 31 Mar 2008 19:35:59 -0400	[thread overview]
Message-ID: <47F1755F.9000303@rtr.ca> (raw)
In-Reply-To: <47F1736F.8020104@rtr.ca>

Introduce mv_sata_hardreset() to perform a link hard reset
while dealing with certain chipset errata during the reset.

Also beef up error-handling in mv_prereset() to trigger a hard reset
whenever mv_stop_edma() fails.

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

--- old/drivers/ata/sata_mv.c	2008-03-31 18:14:40.000000000 -0400
+++ linux/drivers/ata/sata_mv.c	2008-03-31 18:24:50.000000000 -0400
@@ -2388,7 +2388,97 @@
 
 static int mv_prereset(struct ata_link *link, unsigned long deadline)
 {
-	mv_stop_edma(link->ap);
+	if (mv_stop_edma(link->ap))
+		link->eh_context.i.action |= ATA_EH_HARDRESET;
+	return ata_std_prereset(link, deadline);
+}
+
+/**
+ *	mv_sata_hardreset - reset host port via SATA phy reset
+ *	@link: link to reset
+ *	@class: resulting class of attached device
+ *	@deadline: deadline jiffies for the operation
+ *
+ *	SATA phy-reset host port using DET bits of SControl register,
+ *	wait for !BSY and classify the attached device.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep)
+ *
+ *	RETURNS:
+ *	0 on success, -errno otherwise.
+ */
+int mv_sata_hardreset(struct ata_link *link, unsigned int *class,
+			unsigned long deadline)
+{
+	struct ata_port *ap = link->ap;
+	struct mv_host_priv *hpriv = ap->host->private_data;
+	const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
+	int rc, attempts = 0, extra = 0;
+	u32 sstatus;
+
+	DPRINTK("ENTER\n");
+
+	/* FIXME:
+	 * Except for the outer do-while construct below, this function
+	 * is an exact clone of sata_std_hardreset() from libata-core.c.
+	 *
+	 * Once this driver is stable, we should re-org libata so we can share
+	 * more of that code, rather than duplicating so much of it here
+	 * and in other drivers.
+	 */
+
+	/* do-while is workaround for errata FEr SATA#10 (part 2) */
+	do {
+		/* do hardreset */
+		rc = sata_link_hardreset(link, timing, deadline + extra);
+		if (rc) {
+			ata_link_printk(link, KERN_ERR,
+					"COMRESET failed (errno=%d)\n", rc);
+			return rc;
+		}
+		sata_scr_read(&ap->link, SCR_STATUS, &sstatus);
+		if (!IS_GEN_I(hpriv) && ++attempts >= 5 && sstatus == 0x121) {
+			/* Force 1.5gb/s link speed and try again */
+			mv_setup_ifctl(mv_ap_base(ap), 0);
+			if (time_after(jiffies + HZ, deadline))
+				extra = HZ; /* only extend it once, max */
+		}
+	} while (sstatus != 0x0 && sstatus != 0x113 && sstatus != 0x123);
+
+	/* TODO: phy layer with polling, timeouts, etc. */
+	if (ata_link_offline(link)) {
+		*class = ATA_DEV_NONE;
+		DPRINTK("EXIT, link offline\n");
+		return 0;
+	}
+
+	/* wait a while before checking status */
+	ata_wait_after_reset(ap, deadline + extra);
+
+	/* If PMP is supported, we have to do follow-up SRST.  Note
+	 * that some PMPs don't send D2H Reg FIS after hardreset at
+	 * all if the first port is empty.  Wait for it just for a
+	 * second and request follow-up SRST.
+	 */
+	if (ap->flags & ATA_FLAG_PMP) {
+		ata_wait_ready(ap, jiffies + HZ);
+		return -EAGAIN;
+	}
+
+	rc = ata_wait_ready(ap, deadline + extra);
+	/* link occupied, -ENODEV too is an error */
+	if (rc) {
+		ata_link_printk(link, KERN_ERR,
+				"COMRESET failed (errno=%d)\n", rc);
+		return rc;
+	}
+
+	ap->ops->dev_select(ap, 0);	/* probably unnecessary */
+
+	*class = ata_dev_try_classify(link->device, 1, NULL);
+
+	DPRINTK("EXIT, class=%u\n", *class);
 	return 0;
 }
 
@@ -2402,9 +2492,8 @@
 
 	mv_reset_channel(hpriv, mmio, ap->port_no);
 	pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
-	mv_phy_reset(ap, class, deadline);
 
-	return 0;
+	return mv_sata_hardreset(link, class, deadline);
 }
 
 static void mv_postreset(struct ata_link *link, unsigned int *classes)

  parent reply	other threads:[~2008-03-31 23:36 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 ` [PATCH 2/5] sata_mv clean up mv_stop_edma usage Mark Lord
2008-04-02  1:59   ` 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 ` Mark Lord [this message]
2008-04-02  2:31   ` [PATCH 4/5] sata_mv new mv_sata_hardreset handler 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=47F1755F.9000303@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.