All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <htejun@gmail.com>
To: jgarzik@pobox.com, alan@lxorguk.ukuu.org.uk, axboe@suse.de,
	albertcc@tw.ibm.com, lkosewsk@gmail.com,
	linux-ide@vger.kernel.org
Cc: Tejun Heo <htejun@gmail.com>
Subject: [PATCH 10/16] libata-eh-fw: implement ata_eh_schedule_port()
Date: Tue, 11 Apr 2006 22:42:54 +0900	[thread overview]
Message-ID: <11447629744155-git-send-email-htejun@gmail.com> (raw)
In-Reply-To: <11447629733305-git-send-email-htejun@gmail.com>

ata_eh_schedule_port() is the gateway to EH and does one of the
followings depending on how it's invoked.

* Without any flag: It simply schedules EH.  EH will kick in after all
  commands are drained (unless another event occurs, of course).

* ATA_EH_ABORT: EH is scheduled and all currently active qc's get
  aborted.  The caller is responsible for making sure the controller
  and devices are in stable state in this case.

* ATA_EH_FREEZE: It does everything ATA_EH_ABORT does and then freezes
  the port; thus, making the port inaccessible until it gets reset.
  This can be used to safely schedule EH when an HSM violation event
  occurs.

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

---

 drivers/scsi/libata-core.c |    1 +
 drivers/scsi/libata-eh.c   |   53 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/libata.h     |    5 ++++
 3 files changed, 59 insertions(+), 0 deletions(-)

a46608a256d68fd1e1e68a3e73f0be45c752c6a8
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 2a5d3f6..b6f6815 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5300,5 +5300,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_device_resume
 
 EXPORT_SYMBOL_GPL(ata_scsi_error);
 EXPORT_SYMBOL_GPL(ata_eng_timeout);
+EXPORT_SYMBOL_GPL(ata_eh_schedule_port);
 EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
 EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index a1fe14f..e731c04 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -239,6 +239,59 @@ void ata_eh_schedule_qc(struct ata_queue
 	scsi_eh_schedule_cmd(qc->scsicmd);
 }
 
+/**
+ *	ata_eh_schedule_port - schedule error handling without a qc
+ *	@ap: ATA port to schedule EH for
+ *	@flags: ATA_EH_* flags
+ *
+ *	Schedule error hanlding for the speficied ATA port.  EH will
+ *	kick in as soon as all commands are drained.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
+void ata_eh_schedule_port(struct ata_port *ap, unsigned int flags)
+{
+	int internal_cmd = ata_tag_internal(ap->active_tag);
+	int i;
+
+	WARN_ON(!ap->ops->error_handler);
+
+	/* SHOST_RUNNING test is to avoid invoking EH during boot probing */
+	if (!internal_cmd && ap->host->shost_state == SHOST_RUNNING)
+		scsi_eh_schedule_host(ap->host);
+
+	/* abort if requested */
+	if (!(flags & (ATA_EH_ABORT | ATA_EH_FREEZE)))
+		return;
+
+	for (i = 0; i < ATA_MAX_QUEUE; i++) {
+		struct ata_queued_cmd *qc = ata_qc_from_tag(ap, i);
+		if (qc) {
+			if (!internal_cmd)
+				ata_eh_schedule_qc(qc);
+			else {
+				qc->flags |= ATA_QCFLAG_FAILED;
+				__ata_qc_complete(qc);
+			}
+		}
+	}
+
+	/* freeze if requested */
+	if (!(flags & ATA_EH_FREEZE))
+		return;
+
+	/* Timeout handler might try to freeze an already frozen port
+	 * if it races against interrupt handler or another timeout.
+	 * Such conditions should be rare.  Whine.
+	 */
+	if (ap->flags & ATA_FLAG_FROZEN && ata_ratelimit())
+		printk(KERN_INFO "ata%u: ata_eh_schedule_port invoked on "
+		       "a frozen port\n", ap->id);
+
+	ata_port_freeze(ap);
+}
+
 static void ata_eh_scsidone(struct scsi_cmnd *scmd)
 {
 	/* nada */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 8aeead3..47fbd68 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -222,6 +222,10 @@ enum {
 	ATA_PORT_PRIMARY	= (1 << 0),
 	ATA_PORT_SECONDARY	= (1 << 1),
 
+	/* flags for ata_eh_shduled_port */
+	ATA_EH_ABORT		= (1 << 0), /* abort all active commands */
+	ATA_EH_FREEZE		= (1 << 1), /* freeze port (implies ABORT) */
+
 	/* how hard are we gonna try to probe/recover devices */
 	ATA_PROBE_MAX_TRIES	= 3,
 };
@@ -653,6 +657,7 @@ extern unsigned long ata_pci_default_fil
  */
 extern int ata_scsi_error(struct Scsi_Host *host);
 extern void ata_eng_timeout(struct ata_port *ap);
+extern void ata_eh_schedule_port(struct ata_port *ap, unsigned int flags);
 extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
 extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
 
-- 
1.2.4



  parent reply	other threads:[~2006-04-11 13:43 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-11 13:42 [PATCHSET 5/9] new EH framework, take 2 Tejun Heo
2006-04-11 13:42 ` [PATCH 02/16] libata-eh-fw: add new EH operations Tejun Heo
2006-04-11 13:42 ` [PATCH 01/16] libata-eh-fw: add flags for new EH Tejun Heo
2006-04-11 13:42 ` [PATCH 04/16] libata-eh-fw: clear IRQ in ata_std_postreset() Tejun Heo
2006-04-11 13:42 ` [PATCH 09/16] libata-eh-fw: implement new EH scheduling via error completion Tejun Heo
2006-04-11 13:42 ` [PATCH 11/16] libata-eh-fw: implement new EH scheduling via timeout Tejun Heo
2006-04-12 22:36   ` Jeff Garzik
2006-04-13  2:40     ` Tejun Heo
2006-04-13  3:18       ` Jeff Garzik
2006-04-13  3:36         ` Tejun Heo
2006-04-27 11:33           ` Jeff Garzik
2006-04-29 21:13             ` Alan Cox
2006-04-11 13:42 ` [PATCH 06/16] libata-eh-fw: use special reserved tag and qc for internal commands Tejun Heo
2006-04-11 13:42 ` [PATCH 05/16] libata-eh-fw: clear SError in ata_std_postreset() Tejun Heo
2006-04-11 13:42 ` Tejun Heo [this message]
2006-04-11 13:42 ` [PATCH 07/16] libata-eh-fw: implement ata_port_freeze() Tejun Heo
2006-04-11 13:42 ` [PATCH 03/16] libata-eh-fw: hold host_set lock while finishing internal qc Tejun Heo
2006-04-11 13:42 ` [PATCH 12/16] libata-eh-fw: implement new EH scheduling from PIO Tejun Heo
2006-04-11 13:42 ` [PATCH 08/16] libata-eh-fw: update ata_qc_from_tag() to enforce normal/EH qc ownership Tejun Heo
2006-04-11 13:42 ` [PATCH 14/16] libata-eh-fw: activate ->post_internal_cmd Tejun Heo
2006-04-11 13:42 ` [PATCH 16/16] libata-eh-fw: update ata_interrupt() to handle frozen port properly Tejun Heo
2006-04-12 22:40   ` Jeff Garzik
2006-04-13  2:59     ` Tejun Heo
2006-04-11 13:42 ` [PATCH 15/16] libata-eh-fw: update SCSI command completion path for new EH Tejun Heo
2006-04-11 13:42 ` [PATCH 13/16] libata-eh-fw: activate ->error_handler Tejun Heo
2006-04-12 22:41 ` [PATCHSET 5/9] new EH framework, take 2 Jeff Garzik

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=11447629744155-git-send-email-htejun@gmail.com \
    --to=htejun@gmail.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=albertcc@tw.ibm.com \
    --cc=axboe@suse.de \
    --cc=jgarzik@pobox.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=lkosewsk@gmail.com \
    /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.