Patchwork [#upstream] libata: leave port thawed after reset failure

login
register
mail settings
Submitter Tejun Heo
Date May 25, 2011, 10:23 a.m.
Message ID <20110525102356.GH10146@htj.dyndns.org>
Download mbox | patch
Permalink /patch/97319/
State Not Applicable
Delegated to: David Miller
Headers show

Comments

Tejun Heo - May 25, 2011, 10:23 a.m.
libata EH intentionally left a port frozen if it failed
ata_eh_reset().  The intention was avoiding continuous loop of resets
when the controller or attached device is flaky and reporting spurious
hotplug events.  Once port enters this state, it can be recovered with
manual rescan, which seemed reasonable.

However, outside of my convoluted test setup, there have been very few
reports justifying this choice while there have been more cases where
the automatic freezing of the port after hotplug attempt of a faulty
device caused confusion and led to unnecessary resets.

This patch changes the behavior so that the port is thawed after reset
failure.  This change doesn't necessarily solve but makes it easier
and more intuitive to work around hotplug related problems
(ie. re-pluggin or power cycling the device) as reported in the
followings.

  https://bugzilla.kernel.org/show_bug.cgi?id=34712
  http://thread.gmane.org/gmane.linux.kernel/1123265/focus=49548

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Reartes Guillermo <rtguille@gmail.com>
Reported-by: Bruce Stenning <b.stenning@indigovision.com>
---
 drivers/ata/libata-eh.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index dfb6e9d..05797fe 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2885,8 +2885,17 @@  int ata_eh_reset(struct ata_link *link, int classify,
 	    sata_scr_read(link, SCR_STATUS, &sstatus))
 		rc = -ERESTART;
 
-	if (rc == -ERESTART || try >= max_tries)
+	if (rc == -ERESTART || try >= max_tries) {
+		/*
+		 * Thaw host port even if reset failed, so that the port
+		 * can be retried on the next phy event.  This risks
+		 * repeated EH runs but seems to be a better tradeoff than
+		 * shutting down a port after a botched hotplug attempt.
+		 */
+		if (ata_is_host_link(link))
+			ata_eh_thaw_port(ap);
 		goto out;
+	}
 
 	now = jiffies;
 	if (time_before(now, deadline)) {