All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <htejun@gmail.com>
To: jgarzik@pobox.com, linux-ide@vger.kernel.org, albertcc@tw.ibm.com
Cc: Tejun Heo <htejun@gmail.com>
Subject: [PATCH 04/12] libata: implement ata_drive_probe_reset()
Date: Tue, 24 Jan 2006 17:05:22 +0900	[thread overview]
Message-ID: <11380899221448-git-send-email-htejun@gmail.com> (raw)
In-Reply-To: <1138089921565-git-send-email-htejun@gmail.com>

Most low level drivers share supported reset/classify actions and
sequence.  This patch implements ata_drive_probe_reset() which helps
constructing ->probe_reset from three component operations -
softreset, hardreset and postreset.  This minimizes duplicate code and
yet allows flexibility if needed. The three component operations can
also be shared by EH later.

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

---

 drivers/scsi/libata-core.c |   89 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/libata.h     |    5 ++
 2 files changed, 94 insertions(+), 0 deletions(-)

a0161772ae1a16f1a4ffb5f830752ccc3bf44e9f
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index c70151a..48aa57e 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2280,6 +2280,94 @@ err_out:
 	DPRINTK("EXIT\n");
 }
 
+static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset,
+			  ata_postreset_fn_t postreset,
+			  unsigned int *classes)
+{
+	int i, rc;
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++)
+		classes[i] = ATA_DEV_UNKNOWN;
+
+	rc = reset(ap, 0, classes);
+	if (rc)
+		return rc;
+
+	/* If any class isn't ATA_DEV_UNKNOWN, consider classification
+	 * is complete and convert all ATA_DEV_UNKNOWN to
+	 * ATA_DEV_NONE.
+	 */
+	for (i = 0; i < ATA_MAX_DEVICES; i++)
+		if (classes[i] != ATA_DEV_UNKNOWN)
+			break;
+
+	if (i < ATA_MAX_DEVICES)
+		for (i = 0; i < ATA_MAX_DEVICES; i++)
+			if (classes[i] == ATA_DEV_UNKNOWN)
+				classes[i] = ATA_DEV_NONE;
+
+	if (postreset)
+		postreset(ap, classes);
+
+	return classes[0] != ATA_DEV_UNKNOWN ? 0 : -ENODEV;
+}
+
+/**
+ *	ata_drive_probe_reset - Perform probe reset with given methods
+ *	@ap: port to reset
+ *	@softreset: softreset method (can be NULL)
+ *	@hardreset: hardreset method (can be NULL)
+ *	@postreset: postreset method (can be NULL)
+ *	@classes: resulting classes of attached devices
+ *
+ *	Reset the specified port and classify attached devices using
+ *	given methods.  This function prefers softreset but tries all
+ *	possible reset sequences to reset and classify devices.  This
+ *	function is intended to be used for constructing ->probe_reset
+ *	callback by low level drivers.
+ *
+ *	Reset methods should follow the following rules.
+ *
+ *	- Return 0 on sucess, -errno on failure.
+ *	- If classification is supported, fill classes[] with
+ *	  recognized class codes.
+ *	- If classification is not supported, leave classes[] alone.
+ *	- If verbose is non-zero, print error message on failure;
+ *	  otherwise, shut up.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep)
+ *
+ *	RETURNS:
+ *	0 on success, -EINVAL if no reset method is avaliable, -ENODEV
+ *	if classification fails, and any error code from reset
+ *	methods.
+ */
+int ata_drive_probe_reset(struct ata_port *ap,
+			  ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+			  ata_postreset_fn_t postreset, unsigned int *classes)
+{
+	int rc = -EINVAL;
+
+	if (softreset) {
+		rc = do_probe_reset(ap, softreset, postreset, classes);
+		if (rc == 0)
+			return 0;
+	}
+
+	if (!hardreset)
+		return rc;
+
+	rc = do_probe_reset(ap, hardreset, postreset, classes);
+	if (rc == 0 || rc != -ENODEV)
+		return rc;
+
+	if (softreset)
+		rc = do_probe_reset(ap, softreset, postreset, classes);
+
+	return rc;
+}
+
 static void ata_pr_blacklisted(const struct ata_port *ap,
 			       const struct ata_device *dev)
 {
@@ -5220,6 +5308,7 @@ EXPORT_SYMBOL_GPL(ata_port_probe);
 EXPORT_SYMBOL_GPL(sata_phy_reset);
 EXPORT_SYMBOL_GPL(__sata_phy_reset);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
+EXPORT_SYMBOL_GPL(ata_drive_probe_reset);
 EXPORT_SYMBOL_GPL(ata_port_disable);
 EXPORT_SYMBOL_GPL(ata_ratelimit);
 EXPORT_SYMBOL_GPL(ata_busy_sleep);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 6f36d9a..3d7392e 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -244,6 +244,8 @@ struct ata_queued_cmd;
 
 /* typedefs */
 typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
+typedef int (*ata_reset_fn_t)(struct ata_port *, int, unsigned int *);
+typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *);
 
 struct ata_ioports {
 	unsigned long		cmd_addr;
@@ -481,6 +483,9 @@ extern void ata_port_probe(struct ata_po
 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 ata_drive_probe_reset(struct ata_port *ap,
+			ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+			ata_postreset_fn_t postreset, unsigned int *classes);
 extern void ata_port_disable(struct ata_port *);
 extern void ata_std_ports(struct ata_ioports *ioaddr);
 #ifdef CONFIG_PCI
-- 
1.1.3



  parent reply	other threads:[~2006-01-24  8:05 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-24  8:05 [PATCHSET] libata: new reset mechanism, take#2 Tejun Heo
2006-01-24  8:05 ` [PATCH 01/12] libata: export ata_busy_sleep Tejun Heo
2006-01-27  4:18   ` Jeff Garzik
2006-01-24  8:05 ` [PATCH 08/12] sata_sil24: add hardreset Tejun Heo
2006-01-24  8:05 ` [PATCH 10/12] ata_piix: convert sata to new reset mechanism Tejun Heo
2006-01-24  8:05 ` [PATCH 12/12] ahci: add softreset Tejun Heo
2006-01-24  8:05 ` [PATCH 06/12] sata_sil: convert to new reset mechanism Tejun Heo
2006-01-28 18:09   ` Jeff Garzik
2006-01-28 18:27     ` Jeff Garzik
2006-01-28 23:17     ` Tejun
2006-01-29  2:41       ` Jeff Garzik
2006-01-24  8:05 ` [PATCH 07/12] sata_sil24: " Tejun Heo
2006-01-24  8:05 ` [PATCH 09/12] ata_piix: convert pata " Tejun Heo
2006-01-24  8:05 ` Tejun Heo [this message]
2006-01-28  1:58   ` [PATCH 04/12] libata: implement ata_drive_probe_reset() Jeff Garzik
2006-01-24  8:05 ` [PATCH 02/12] libata: modify ata_dev_try_classify Tejun Heo
2006-01-27  4:20   ` Jeff Garzik
2006-01-24  8:05 ` [PATCH 03/12] libata: new ->probe_reset operation Tejun Heo
2006-01-24  8:05 ` [PATCH 05/12] libata: implement standard reset component operations and ->probe_reset Tejun Heo
2006-01-28  1:58   ` Jeff Garzik
2006-01-24  8:05 ` [PATCH 11/12] ahci: convert to new reset mechanism Tejun Heo

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=11380899221448-git-send-email-htejun@gmail.com \
    --to=htejun@gmail.com \
    --cc=albertcc@tw.ibm.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.