From: Tejun Heo <htejun@gmail.com>
To: jeff@garzik.org, alan@lxorguk.ukuu.org.uk, linux-ide@vger.kernel.org
Cc: Tejun Heo <htejun@gmail.com>
Subject: [PATCH 07/12] libata-pmp-prep: implement ATA_LFLAG_NO_SRST, ASSUME_ATA and ASSUME_SEMB
Date: Sun, 23 Sep 2007 13:14:12 +0900 [thread overview]
Message-ID: <11905208522729-git-send-email-htejun@gmail.com> (raw)
In-Reply-To: <11905208513747-git-send-email-htejun@gmail.com>
Some links on some PMPs locks up on SRST and/or report incorrect
device signature. Implement ATA_LFLAG_NO_SRST, ASSUME_ATA and
ASSUME_SEMB to handle these quirky links. NO_SRST makes EH avoid
SRST. ASSUME_ATA and SEMB forces class code to ATA and SEMB_UNSUP
respectively. Note that SEMB isn't currently supported yet so the
_UNSUP variant is used.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/ata/libata-eh.c | 42 ++++++++++++++++++++++++++++++++----------
include/linux/libata.h | 4 ++++
2 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 5244723..7be04bd 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1906,14 +1906,18 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
return 0;
}
-static int ata_eh_followup_srst_needed(int rc, int classify,
+static int ata_eh_followup_srst_needed(struct ata_link *link,
+ int rc, int classify,
const unsigned int *classes)
{
+ if (link->flags & ATA_LFLAG_NO_SRST)
+ return 0;
if (rc == -EAGAIN)
return 1;
if (rc != 0)
return 0;
- if (classify && classes[0] == ATA_DEV_UNKNOWN)
+ if (classify && !(link->flags & ATA_LFLAG_ASSUME_CLASS) &&
+ classes[0] == ATA_DEV_UNKNOWN)
return 1;
return 0;
}
@@ -1940,7 +1944,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
*/
action = ehc->i.action;
ehc->i.action &= ~ATA_EH_RESET_MASK;
- if (softreset && (!hardreset || (!sata_set_spd_needed(link) &&
+ if (softreset && (!hardreset || (!(link->flags & ATA_LFLAG_NO_SRST) &&
+ !sata_set_spd_needed(link) &&
!(action & ATA_EH_HARDRESET))))
ehc->i.action |= ATA_EH_SOFTRESET;
else
@@ -2003,7 +2008,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
rc = ata_do_reset(link, reset, classes, deadline);
if (reset == hardreset &&
- ata_eh_followup_srst_needed(rc, classify, classes)) {
+ ata_eh_followup_srst_needed(link, rc, classify, classes)) {
/* okay, let's do follow-up softreset */
reset = softreset;
@@ -2018,8 +2023,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
ata_eh_about_to_do(link, NULL, ATA_EH_RESET_MASK);
rc = ata_do_reset(link, reset, classes, deadline);
- if (rc == 0 && classify &&
- classes[0] == ATA_DEV_UNKNOWN) {
+ if (rc == 0 && classify && classes[0] == ATA_DEV_UNKNOWN &&
+ !(link->flags & ATA_LFLAG_ASSUME_CLASS)) {
ata_link_printk(link, KERN_ERR,
"classification failed\n");
rc = -EINVAL;
@@ -2027,6 +2032,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
}
}
+ /* if we skipped follow-up srst, clear rc */
+ if (rc == -EAGAIN)
+ rc = 0;
+
if (rc && try < ARRAY_SIZE(ata_eh_reset_timeouts)) {
unsigned long now = jiffies;
@@ -2051,12 +2060,25 @@ int ata_eh_reset(struct ata_link *link, int classify,
if (rc == 0) {
u32 sstatus;
- /* After the reset, the device state is PIO 0 and the
- * controller state is undefined. Record the mode.
- */
- ata_link_for_each_dev(dev, link)
+ ata_link_for_each_dev(dev, link) {
+ /* After the reset, the device state is PIO 0
+ * and the controller state is undefined.
+ * Record the mode.
+ */
dev->pio_mode = XFER_PIO_0;
+ if (ata_link_offline(link))
+ continue;
+
+ /* apply class override and convert UNKNOWN to NONE */
+ if (link->flags & ATA_LFLAG_ASSUME_ATA)
+ classes[dev->devno] = ATA_DEV_ATA;
+ else if (link->flags & ATA_LFLAG_ASSUME_SEMB)
+ classes[dev->devno] = ATA_DEV_SEMB_UNSUP; /* not yet */
+ else if (classes[dev->devno] == ATA_DEV_UNKNOWN)
+ classes[dev->devno] = ATA_DEV_NONE;
+ }
+
/* record current link speed */
if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0)
link->sata_spd = (sstatus >> 4) & 0xf;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index f9f81fd..6266fff 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -165,6 +165,10 @@ enum {
ATA_LFLAG_HRST_TO_RESUME = (1 << 0), /* hardreset to resume link */
ATA_LFLAG_SKIP_D2H_BSY = (1 << 1), /* can't wait for the first D2H
* Register FIS clearing BSY */
+ ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */
+ ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */
+ ATA_LFLAG_ASSUME_SEMB = (1 << 4), /* assume SEMB class */
+ ATA_LFLAG_ASSUME_CLASS = ATA_LFLAG_ASSUME_ATA | ATA_LFLAG_ASSUME_SEMB,
/* struct ata_port flags */
ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */
--
1.5.0.3
next prev parent reply other threads:[~2007-09-23 4:14 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-23 4:14 [PATCHSET 1/2] libata: prep for PMP support, take 6 Tejun Heo
2007-09-23 4:14 ` [PATCH 01/12] libata: misc updates for AN Tejun Heo
2007-09-26 2:27 ` Jeff Garzik
2007-09-23 4:14 ` [PATCH 03/12] libata-pmp-prep: add @new_class to ata_dev_revalidate() Tejun Heo
2007-09-23 4:14 ` [PATCH 02/12] libata-pmp-prep: add PMP related constants, fields, ops and update helpers Tejun Heo
2007-09-23 4:14 ` [PATCH 06/12] libata-pmp-prep: implement qc_defer helpers Tejun Heo
2007-09-23 4:14 ` [PATCH 05/12] libata-pmp-prep: implement ops->qc_defer() Tejun Heo
2007-09-23 4:14 ` Tejun Heo [this message]
2007-09-23 4:14 ` [PATCH 04/12] libata-pmp-prep: make a number of functions global to libata Tejun Heo
2007-09-23 4:14 ` [PATCH 08/12] libata-pmp-prep: implement ATA_LFLAG_NO_RETRY Tejun Heo
2007-09-23 4:14 ` [PATCH 11/12] libata-pmp-prep: implement ATA_HORKAGE_SKIP_PM Tejun Heo
2007-09-23 4:14 ` [PATCH 09/12] libata-pmp-prep: implement ATA_LFLAG_DISABLED Tejun Heo
2007-09-23 4:14 ` [PATCH 12/12] libata-pmp-prep: implement sata_async_notification() Tejun Heo
2007-09-23 4:14 ` [PATCH 10/12] libata-pmp-prep: implement EH fast-fail path Tejun Heo
-- strict thread matches above, loose matches on Subject: below --
2007-07-01 10:26 [PATCHSET 3/4] libata: prep for PMP support, take 4 Tejun Heo
2007-07-01 10:26 ` [PATCH 07/12] libata-pmp-prep: implement ATA_LFLAG_NO_SRST, ASSUME_ATA and ASSUME_SEMB 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=11905208522729-git-send-email-htejun@gmail.com \
--to=htejun@gmail.com \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=jeff@garzik.org \
--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).