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
next prev 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 03/12] libata: new ->probe_reset operation 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 12/12] ahci: add softreset Tejun Heo
2006-01-24 8:05 ` [PATCH 09/12] ata_piix: convert pata to new reset mechanism 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 07/12] sata_sil24: convert to new reset mechanism Tejun Heo
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 11/12] ahci: convert to new reset mechanism Tejun Heo
2006-01-24 8:05 ` [PATCH 10/12] ata_piix: convert sata " 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 08/12] sata_sil24: add hardreset 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 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).