diff options
author | Tejun Heo <htejun@gmail.com> | 2006-05-15 07:58:05 -0400 |
---|---|---|
committer | Tejun Heo <htejun@gmail.com> | 2006-05-15 07:58:05 -0400 |
commit | f686bcb8078ac7505ec88818886c2c72639f4fc5 (patch) | |
tree | 7c563e0032b2d85b631b617b8bb2a7a648607468 /include/linux/libata.h | |
parent | f69499f42caf74194df678c9c293f2ee0fe90bc3 (diff) |
[PATCH] libata-eh-fw: implement new EH scheduling via error completion
There are several ways a qc can get schedule for EH in new EH. This
patch implements one of them - completing a qc with ATA_QCFLAG_FAILED
set or with non-zero qc->err_mask. ALL such qc's are examined by EH.
New EH schedules a qc for EH from completion iff ->error_handler is
implemented, qc is marked as failed or qc->err_mask is non-zero and
the command is not an internal command (internal cmd is handled via
->post_internal_cmd). The EH scheduling itself is performed by asking
SCSI midlayer to schedule EH for the specified scmd.
For drivers implementing old-EH, nothing changes. As this change
makes ata_qc_complete() rather large, it's not inlined anymore and
__ata_qc_complete() is exported to other parts of libata for later
use.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'include/linux/libata.h')
-rw-r--r-- | include/linux/libata.h | 27 |
1 files changed, 1 insertions, 26 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h index bfcefdca0616..6023f324e68e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -605,7 +605,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc); | |||
605 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); | 605 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); |
606 | extern u8 ata_bmdma_status(struct ata_port *ap); | 606 | extern u8 ata_bmdma_status(struct ata_port *ap); |
607 | extern void ata_bmdma_irq_clear(struct ata_port *ap); | 607 | extern void ata_bmdma_irq_clear(struct ata_port *ap); |
608 | extern void __ata_qc_complete(struct ata_queued_cmd *qc); | 608 | extern void ata_qc_complete(struct ata_queued_cmd *qc); |
609 | extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, | 609 | extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, |
610 | void (*done)(struct scsi_cmnd *)); | 610 | void (*done)(struct scsi_cmnd *)); |
611 | extern int ata_std_bios_param(struct scsi_device *sdev, | 611 | extern int ata_std_bios_param(struct scsi_device *sdev, |
@@ -883,31 +883,6 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) | |||
883 | } | 883 | } |
884 | 884 | ||
885 | /** | 885 | /** |
886 | * ata_qc_complete - Complete an active ATA command | ||
887 | * @qc: Command to complete | ||
888 | * @err_mask: ATA Status register contents | ||
889 | * | ||
890 | * Indicate to the mid and upper layers that an ATA | ||
891 | * command has completed, with either an ok or not-ok status. | ||
892 | * | ||
893 | * LOCKING: | ||
894 | * spin_lock_irqsave(host_set lock) | ||
895 | */ | ||
896 | static inline void ata_qc_complete(struct ata_queued_cmd *qc) | ||
897 | { | ||
898 | struct ata_port *ap = qc->ap; | ||
899 | |||
900 | if (unlikely(qc->flags & ATA_QCFLAG_EH_SCHEDULED)) | ||
901 | return; | ||
902 | |||
903 | /* read result TF if failed or requested */ | ||
904 | if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF) | ||
905 | ap->ops->tf_read(ap, &qc->result_tf); | ||
906 | |||
907 | __ata_qc_complete(qc); | ||
908 | } | ||
909 | |||
910 | /** | ||
911 | * ata_irq_on - Enable interrupts on a port. | 886 | * ata_irq_on - Enable interrupts on a port. |
912 | * @ap: Port on which interrupts are enabled. | 887 | * @ap: Port on which interrupts are enabled. |
913 | * | 888 | * |