[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>
This commit is contained in:
Tejun Heo 2006-05-15 20:58:05 +09:00
parent f69499f42c
commit f686bcb807
4 changed files with 91 additions and 27 deletions

View file

@ -605,7 +605,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc);
extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
extern u8 ata_bmdma_status(struct ata_port *ap);
extern void ata_bmdma_irq_clear(struct ata_port *ap);
extern void __ata_qc_complete(struct ata_queued_cmd *qc);
extern void ata_qc_complete(struct ata_queued_cmd *qc);
extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *));
extern int ata_std_bios_param(struct scsi_device *sdev,
@ -882,31 +882,6 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
qc->result_tf.feature = 0;
}
/**
* ata_qc_complete - Complete an active ATA command
* @qc: Command to complete
* @err_mask: ATA Status register contents
*
* Indicate to the mid and upper layers that an ATA
* command has completed, with either an ok or not-ok status.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
static inline void ata_qc_complete(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
if (unlikely(qc->flags & ATA_QCFLAG_EH_SCHEDULED))
return;
/* read result TF if failed or requested */
if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
ap->ops->tf_read(ap, &qc->result_tf);
__ata_qc_complete(qc);
}
/**
* ata_irq_on - Enable interrupts on a port.
* @ap: Port on which interrupts are enabled.