linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHSET 01/03] prep for hotplug support, take 3
@ 2006-05-19 13:16 Tejun Heo
  2006-05-19 13:16 ` [PATCH 03/14] libata-hp-prep: make some ata_device fields persistent Tejun Heo
                   ` (13 more replies)
  0 siblings, 14 replies; 35+ messages in thread
From: Tejun Heo @ 2006-05-19 13:16 UTC (permalink / raw)
  To: jgarzik, mlord, albertcc, alan, axboe, forrest.zhao, linux-ide,
	htejun

Hello,

This is This is part of patchset series described in [T].

This is the third take of prep-for-hotplug-support patchset.  Changes
from the last take[L] are

* sata_phy_debounce() now takes const array of three ulongs for timing
  parameters.  This makes it easy to define and export different
  predefined timing parameters and to pass timing parameter through
  other functions.  sata_phy_resume() is changed to take timing
  parameters and pass it to sata_phy_debounce() intead of crude
  boolean @quick.

* Three predefined parameters are provided - sata_deb_timing_boot,
  sata_deb_timing_eh and sata_deb_timing_before_fsrst.  These
  predefined parameters are used in the new hotplug framework and
  don't have to be long enough to cover all the cases.  The goal is to
  cover most cases in reasonable amount of time.  If timeout occurs,
  libata will give it more time and then retry.

* prereset() framework has been updated such that prereset() can tell
  EH what reset mechanism to use or to skip reset completely.  This
  way, HRST_TO_RESUME handling is confined into prereset() and device
  detection from prereset() is handled cleanly.

* ata_std_prereset() has been updated to handle different behaviors
  controllers show on hotplug.  Some controllers can wait for the
  first FIS34, some can only after COMRESET, others just can't.  These
  are controlled by two flags - ATA_FLAG_HRST_TO_RESUME and
  ATA_FLAG_CANT_WAIT_FIS34.  Note that those two flags describe PHY
  property.  They will move out to ata_link later.

  If necessary, ata_std_prereset() waits for spinup until hotplug
  event timestamp + spinup wait time (currently 8s).  This mechanism
  will allow later PMP support to avoid excessive amount of waiting.

This patchset is against

  upstream (8d4ee71ff6de5255ebfdf44fb83419d27bd06368)
  + enforce-default-EH-actions patch [1]
  + scsi_implement_eh-patch [2]

Thanks.

--
tejun

[T] http://article.gmane.org/gmane.linux.ide/10530
[L] http://article.gmane.org/gmane.linux.ide/10073
[1] http://article.gmane.org/gmane.linux.ide/10317
[2] http://article.gmane.org/gmane.linux.ide/10529


^ permalink raw reply	[flat|nested] 35+ messages in thread
* [PATCH 10/14] libata-hp-prep: implement sata_phy_debounce()
@ 2006-05-19 13:06 Tejun Heo
  2006-05-19 13:06 ` [PATCH 11/14] libata-hp-prep: make ops->tf_read() optional Tejun Heo
  0 siblings, 1 reply; 35+ messages in thread
From: Tejun Heo @ 2006-05-19 13:06 UTC (permalink / raw)
  To: jgarzik, mlord, albertcc, alan, axboe, forrest.zhao, linux-ide; +Cc: Tejun Heo

With hotplug, PHY always needs to be debounced before a reset as any
reset might find new devices.  Extract PHY waiting code from
sata_phy_resume() and extend it to include SStatus debouncing.  Note
that sata_phy_debounce() is superset of what used to be done inside
sata_phy_resume().

Three default debounce timing parameters are defined to be used by
hot/boot plug.  As resume failure during probing will be properly
handled as errors, timeout doesn't have to be long as before.
probeinit() uses the same timeout to retain the original behavior.

Signed-off-by: Tejun Heo <htejun@gmail.com>

---

 drivers/scsi/libata-core.c |  104 ++++++++++++++++++++++++++++++++++++++------
 include/linux/libata.h     |    6 +++
 2 files changed, 95 insertions(+), 15 deletions(-)

fab1e57199f37d383773923278bc9ada10a3c60b
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 8b25cb5..8f18ced 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -61,6 +61,11 @@ #include <asm/byteorder.h>
 
 #include "libata.h"
 
+/* debounce timing parameters in msecs { interval, duration, timeout } */
+const unsigned long sata_deb_timing_boot[]		= {   5,  100, 2000 };
+const unsigned long sata_deb_timing_eh[]		= {  25,  500, 2000 };
+const unsigned long sata_deb_timing_before_fsrst[]	= { 100, 2000, 5000 };
+
 static unsigned int ata_dev_init_params(struct ata_device *dev,
 					u16 heads, u16 sectors);
 static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
@@ -2418,10 +2423,81 @@ err_out:
 	DPRINTK("EXIT\n");
 }
 
-static int sata_phy_resume(struct ata_port *ap)
+/**
+ *	sata_phy_debounce - debounce SATA phy status
+ *	@ap: ATA port to debounce SATA phy status for
+ *	@params: timing parameters { interval, duratinon, timeout } in msec
+ *
+ *	Make sure SStatus of @ap reaches stable state, determined by
+ *	holding the same value where DET is not 1 for @duration polled
+ *	every @interval, before @timeout.  Timeout constraints the
+ *	beginning of the stable state.  Because, after hot unplugging,
+ *	DET gets stuck at 1 on some controllers, this functions waits
+ *	until timeout then returns 0 if DET is stable at 1.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep)
+ *
+ *	RETURNS:
+ *	0 on success, -errno on failure.
+ */
+int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
 {
-	unsigned long timeout = jiffies + (HZ * 5);
-	u32 scontrol, sstatus;
+	unsigned long interval_msec = params[0];
+	unsigned long duration = params[1] * HZ / 1000;
+	unsigned long timeout = jiffies + params[2] * HZ / 1000;
+	unsigned long last_jiffies;
+	u32 last, cur;
+	int rc;
+
+	if ((rc = sata_scr_read(ap, SCR_STATUS, &cur)))
+		return rc;
+	cur &= 0xf;
+
+	last = cur;
+	last_jiffies = jiffies;
+
+	while (1) {
+		msleep(interval_msec);
+		if ((rc = sata_scr_read(ap, SCR_STATUS, &cur)))
+			return rc;
+		cur &= 0xf;
+
+		/* DET stable? */
+		if (cur == last) {
+			if (cur == 1 && time_before(jiffies, timeout))
+				continue;
+			if (time_after(jiffies, last_jiffies + duration))
+				return 0;
+			continue;
+		}
+
+		/* unstable, start over */
+		last = cur;
+		last_jiffies = jiffies;
+
+		/* check timeout */
+		if (time_after(jiffies, timeout))
+			return -EBUSY;
+	}
+}
+
+/**
+ *	sata_phy_resume - resume SATA phy
+ *	@ap: ATA port to resume SATA phy for
+ *	@params: timing parameters { interval, duratinon, timeout } in msec
+ *
+ *	Resume SATA phy of @ap and debounce it.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep)
+ *
+ *	RETURNS:
+ *	0 on success, -errno on failure.
+ */
+int sata_phy_resume(struct ata_port *ap, const unsigned long *params)
+{
+	u32 scontrol;
 	int rc;
 
 	if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
@@ -2432,16 +2508,7 @@ static int sata_phy_resume(struct ata_po
 	if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
 		return rc;
 
-	/* Wait for phy to become ready, if necessary. */
-	do {
-		msleep(200);
-		if ((rc = sata_scr_read(ap, SCR_STATUS, &sstatus)))
-			return rc;
-		if ((sstatus & 0xf) != 1)
-			return 0;
-	} while (time_before(jiffies, timeout));
-
-	return -EBUSY;
+	return sata_phy_debounce(ap, params);
 }
 
 /**
@@ -2459,8 +2526,10 @@ static int sata_phy_resume(struct ata_po
  */
 void ata_std_probeinit(struct ata_port *ap)
 {
+	static const unsigned long deb_timing[] = { 5, 100, 5000 };
+
 	/* resume link */
-	sata_phy_resume(ap);
+	sata_phy_resume(ap, deb_timing);
 
 	/* wait for device */
 	if (ata_port_online(ap))
@@ -2576,7 +2645,7 @@ int sata_std_hardreset(struct ata_port *
 	msleep(1);
 
 	/* bring phy back */
-	sata_phy_resume(ap);
+	sata_phy_resume(ap, sata_deb_timing_eh);
 
 	/* TODO: phy layer with polling, timeouts, etc. */
 	if (ata_port_offline(ap)) {
@@ -5683,6 +5752,9 @@ u32 ata_wait_register(void __iomem *reg,
  * Do not depend on ABI/API stability.
  */
 
+EXPORT_SYMBOL_GPL(sata_deb_timing_boot);
+EXPORT_SYMBOL_GPL(sata_deb_timing_eh);
+EXPORT_SYMBOL_GPL(sata_deb_timing_before_fsrst);
 EXPORT_SYMBOL_GPL(ata_std_bios_param);
 EXPORT_SYMBOL_GPL(ata_std_ports);
 EXPORT_SYMBOL_GPL(ata_device_add);
@@ -5719,6 +5791,8 @@ EXPORT_SYMBOL_GPL(ata_bmdma_error_handle
 EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
 EXPORT_SYMBOL_GPL(ata_port_probe);
 EXPORT_SYMBOL_GPL(sata_set_spd);
+EXPORT_SYMBOL_GPL(sata_phy_debounce);
+EXPORT_SYMBOL_GPL(sata_phy_resume);
 EXPORT_SYMBOL_GPL(sata_phy_reset);
 EXPORT_SYMBOL_GPL(__sata_phy_reset);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index dbc9602..3d7c3e3 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -601,11 +601,17 @@ struct ata_timing {
 
 #define FIT(v,vmin,vmax)	max_t(short,min_t(short,v,vmax),vmin)
 
+extern const unsigned long sata_deb_timing_boot[];
+extern const unsigned long sata_deb_timing_eh[];
+extern const unsigned long sata_deb_timing_before_fsrst[];
+
 extern void ata_port_probe(struct ata_port *);
 extern void __sata_phy_reset(struct ata_port *ap);
 extern void sata_phy_reset(struct ata_port *ap);
 extern void ata_bus_reset(struct ata_port *ap);
 extern int sata_set_spd(struct ata_port *ap);
+extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param);
+extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param);
 extern int ata_drive_probe_reset(struct ata_port *ap,
 			ata_probeinit_fn_t probeinit,
 			ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
-- 
1.3.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread
* [PATCHSET 07/11] prep LLDDs for hotplug support, take 1
@ 2006-05-11 15:11 Tejun Heo
  2006-05-11 15:12 ` [PATCH 11/14] libata-hp-prep: make ops->tf_read() optional Tejun Heo
  0 siblings, 1 reply; 35+ messages in thread
From: Tejun Heo @ 2006-05-11 15:11 UTC (permalink / raw)
  To: jgarzik, alan, axboe, albertcc, forrest.zhao, efalk, linux-ide,
	htejun

Hairu.

This is part of patchset series described in [T].

This is the first take of prep-LLDDs-for-hotplug-support patchset.
Some of patches in this patchset are from the first take of
add-hotplug-support patchset.

Things worth noting are

* Simply exporting ata_hsm_move() and calling the function with
  appropriate status is good enough for driving HSM for LLDDs
  implementing their own irq handlers.  sata_sil's new irq handler
  now uses it.

* TF faking is removed from sata_sil24.

This patchset is against

  upstream (acc696d93dcf993dec123d69d599979e1456ffec)
  + [1] prep-for-new-EH patchset
  + [2] new-EH-framework patchset, take 3
  + [3] new-EH-implementation patchset, take 3
  + [4] merge-irq-pio patchset
  + [5] add-NCQ-support patchset, take 3
  + [6] prep for hotplug support, take 2

--
tejun

[T] http://article.gmane.org/gmane.linux.ide/9957
[1] http://article.gmane.org/gmane.linux.ide/9959
[2] http://article.gmane.org/gmane.linux.ide/9984
[3] http://article.gmane.org/gmane.linux.ide/9995
[4] http://article.gmane.org/gmane.linux.ide/10005
[5] http://article.gmane.org/gmane.linux.ide/10011
[6] http://article.gmane.org/gmane.linux.ide/10028



^ permalink raw reply	[flat|nested] 35+ messages in thread
* [PATCHSET 06/11] prep for hotplug support, take 2
@ 2006-05-11 15:02 Tejun Heo
  2006-05-11 15:02 ` [PATCH 11/14] libata-hp-prep: make ops->tf_read() optional Tejun Heo
  0 siblings, 1 reply; 35+ messages in thread
From: Tejun Heo @ 2006-05-11 15:02 UTC (permalink / raw)
  To: jgarzik, alan, axboe, albertcc, forrest.zhao, efalk, linux-ide,
	htejun

Bang-Ga.

This is part of patchset series described in [T].

This is the second take of prep-for-hotplug-support patchset.  Changes
from the last take[L] are

* dev->flags is used for warm plug and synchronized with host_set
  lock.  ata_dev_init() is updated to clear non-persistent part of
  dev->flags while holding host_set lock.

* ap->orig_sata_spd_limit renamed to ap->hw_sata_spd_limit.

* sata_phy_debounce() implemented.  This function will be called
  before performing EH resets to settle devices instead of blind
  delay.  sata_phy_debounce() is superset of the wait used in
  sata_phy_resume() and sata_phy_resume() is converted to use it.

* TF access is made optional.  All probing (including boot probing)
  will be done via hotplug and hotplug probing is implemented such
  that ->tf_read/write() isn't necessary, so now drivers like
  sata_sil24 don't have to fake TF access.  As ->check_[alt]status()
  was embedded too deep, ata_noop_check_status() is added instead of
  making those methods optional.  In the long term, those low level
  methods should be separated from highlevel ops somehow.

* ops->prereset() added.  This function is the counterpart of
  postreset() and called before a series of resets.  This is quite
  similar to ->probe_init() except that it's called for all resets.
  prereset() can determine things like whether it's prepping for boot
  probing or not, and which reset will be performed by testing
  ap->flags and ehi.

* Followup-softreset handling implemented.

* hotplug will completely replace ->probe_init/reset().

This patchset is against

  upstream (acc696d93dcf993dec123d69d599979e1456ffec)
  + [1] prep-for-new-EH patchset
  + [2] new-EH-framework patchset, take 3
  + [3] new-EH-implementation patchset, take 3
  + [4] merge-irq-pio patchset
  + [5] add-NCQ-support patchset, take 3

--
tejun

[T] http://article.gmane.org/gmane.linux.ide/9957
[L] http://article.gmane.org/gmane.linux.ide/9579
[1] http://article.gmane.org/gmane.linux.ide/9959
[2] http://article.gmane.org/gmane.linux.ide/9984
[3] http://article.gmane.org/gmane.linux.ide/9995
[4] http://article.gmane.org/gmane.linux.ide/10005
[5] http://article.gmane.org/gmane.linux.ide/10011



^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2006-05-29  2:14 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-05-19 13:16 [PATCHSET 01/03] prep for hotplug support, take 3 Tejun Heo
2006-05-19 13:16 ` [PATCH 03/14] libata-hp-prep: make some ata_device fields persistent Tejun Heo
2006-05-19 15:00   ` Jeff Garzik
2006-05-19 13:16 ` [PATCH 01/14] libata-hp-prep: add flags and eh_info/context fields for hotplug Tejun Heo
2006-05-19 14:58   ` Jeff Garzik
2006-05-19 15:17     ` Tejun Heo
2006-05-19 15:28       ` Jeff Garzik
2006-05-19 13:16 ` [PATCH 04/14] libata-hp-prep: update ata_scsi_find_dev() and friends Tejun Heo
2006-05-19 15:03   ` Jeff Garzik
2006-05-23 14:25     ` Tejun Heo
2006-05-26  7:07       ` Jeff Garzik
2006-05-19 13:16 ` [PATCH 02/14] libata-hp-prep: implement ata_dev_init() Tejun Heo
2006-05-19 13:16 ` [PATCH 05/14] libata-hp-prep: use __ata_scsi_find_dev() Tejun Heo
2006-05-19 13:16 ` [PATCH 09/14] libata-hp-prep: make probing related functions global Tejun Heo
2006-05-19 13:16 ` [PATCH 06/14] libata-hp-prep: implement ap->hw_sata_spd_limit Tejun Heo
2006-05-19 13:16 ` [PATCH 07/14] libata-hp-prep: store attached SCSI device Tejun Heo
2006-05-19 15:04   ` Jeff Garzik
2006-05-19 13:16 ` [PATCH 12/14] libata-hp-prep: implement ata_noop_check_status() Tejun Heo
2006-05-19 15:12   ` Jeff Garzik
2006-05-19 13:16 ` [PATCH 11/14] libata-hp-prep: make ops->tf_read() optional Tejun Heo
2006-05-19 15:11   ` Jeff Garzik
2006-05-23 16:04     ` Tejun Heo
2006-05-19 13:16 ` [PATCH 08/14] libata-hp-prep: add ata_hotplug_wq Tejun Heo
2006-05-19 13:16 ` [PATCH 10/14] libata-hp-prep: implement sata_phy_debounce() Tejun Heo
2006-05-19 15:07   ` Jeff Garzik
2006-05-19 13:16 ` [PATCH 14/14] libata-hp-prep: implement followup softreset handling Tejun Heo
2006-05-19 15:21   ` Jeff Garzik
2006-05-19 13:16 ` [PATCH 13/14] libata-hp-prep: add prereset() method and implement ata_std_prereset() Tejun Heo
2006-05-19 15:20   ` Jeff Garzik
2006-05-23 14:44     ` Tejun Heo
2006-05-23 22:29       ` Alan Cox
2006-05-29  2:14         ` Tejun Heo
  -- strict thread matches above, loose matches on Subject: below --
2006-05-19 13:06 [PATCH 10/14] libata-hp-prep: implement sata_phy_debounce() Tejun Heo
2006-05-19 13:06 ` [PATCH 11/14] libata-hp-prep: make ops->tf_read() optional Tejun Heo
2006-05-11 15:11 [PATCHSET 07/11] prep LLDDs for hotplug support, take 1 Tejun Heo
2006-05-11 15:12 ` [PATCH 11/14] libata-hp-prep: make ops->tf_read() optional Tejun Heo
2006-05-11 15:02 [PATCHSET 06/11] prep for hotplug support, take 2 Tejun Heo
2006-05-11 15:02 ` [PATCH 11/14] libata-hp-prep: make ops->tf_read() optional Tejun Heo

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).