All of lore.kernel.org
 help / color / mirror / Atom feed
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



  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 ` Tejun Heo [this message]
2007-09-23  4:14 ` [PATCH 06/12] libata-pmp-prep: implement qc_defer helpers Tejun Heo
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 05/12] libata-pmp-prep: implement ops->qc_defer() 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 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 12/12] libata-pmp-prep: implement sata_async_notification() 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 11/12] libata-pmp-prep: implement ATA_HORKAGE_SKIP_PM 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 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.