Commit b83ad9ee authored by Wenchao Hao's avatar Wenchao Hao Committed by Damien Le Moal

ata: libata-eh: Cleanup ata_scsi_cmd_error_handler()

If ap->ops->error_handler is NULL just return. This patch also
fixes some comment style issue.
Signed-off-by: default avatarWenchao Hao <haowenchao@huawei.com>
Reviewed-by: default avatarNiklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: default avatarDamien Le Moal <damien.lemoal@opensource.wdc.com>
parent f060ba18
......@@ -565,13 +565,19 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
{
int i;
unsigned long flags;
struct scsi_cmnd *scmd, *tmp;
int nr_timedout = 0;
/* make sure sff pio task is not running */
ata_sff_flush_pio_task(ap);
if (!ap->ops->error_handler)
return;
/* synchronize with host lock and sort out timeouts */
/* For new EH, all qcs are finished in one of three ways -
/*
* For new EH, all qcs are finished in one of three ways -
* normal completion, error completion, and SCSI timeout.
* Both completions can race against SCSI timeout. When normal
* completion wins, the qc never reaches EH. When error
......@@ -584,64 +590,61 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
* timed out iff its associated qc is active and not failed.
*/
spin_lock_irqsave(ap->lock, flags);
if (ap->ops->error_handler) {
struct scsi_cmnd *scmd, *tmp;
int nr_timedout = 0;
/* This must occur under the ap->lock as we don't want
a polled recovery to race the real interrupt handler
The lost_interrupt handler checks for any completed but
non-notified command and completes much like an IRQ handler.
We then fall into the error recovery code which will treat
this as if normal completion won the race */
if (ap->ops->lost_interrupt)
ap->ops->lost_interrupt(ap);
/*
* This must occur under the ap->lock as we don't want
* a polled recovery to race the real interrupt handler
*
* The lost_interrupt handler checks for any completed but
* non-notified command and completes much like an IRQ handler.
*
* We then fall into the error recovery code which will treat
* this as if normal completion won the race
*/
if (ap->ops->lost_interrupt)
ap->ops->lost_interrupt(ap);
list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) {
struct ata_queued_cmd *qc;
list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) {
struct ata_queued_cmd *qc;
ata_qc_for_each_raw(ap, qc, i) {
if (qc->flags & ATA_QCFLAG_ACTIVE &&
qc->scsicmd == scmd)
break;
}
ata_qc_for_each_raw(ap, qc, i) {
if (qc->flags & ATA_QCFLAG_ACTIVE &&
qc->scsicmd == scmd)
break;
}
if (i < ATA_MAX_QUEUE) {
/* the scmd has an associated qc */
if (!(qc->flags & ATA_QCFLAG_FAILED)) {
/* which hasn't failed yet, timeout */
qc->err_mask |= AC_ERR_TIMEOUT;
qc->flags |= ATA_QCFLAG_FAILED;
nr_timedout++;
}
} else {
/* Normal completion occurred after
* SCSI timeout but before this point.
* Successfully complete it.
*/
scmd->retries = scmd->allowed;
scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
if (i < ATA_MAX_QUEUE) {
/* the scmd has an associated qc */
if (!(qc->flags & ATA_QCFLAG_FAILED)) {
/* which hasn't failed yet, timeout */
qc->err_mask |= AC_ERR_TIMEOUT;
qc->flags |= ATA_QCFLAG_FAILED;
nr_timedout++;
}
} else {
/* Normal completion occurred after
* SCSI timeout but before this point.
* Successfully complete it.
*/
scmd->retries = scmd->allowed;
scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
}
}
/* If we have timed out qcs. They belong to EH from
* this point but the state of the controller is
* unknown. Freeze the port to make sure the IRQ
* handler doesn't diddle with those qcs. This must
* be done atomically w.r.t. setting QCFLAG_FAILED.
*/
if (nr_timedout)
__ata_port_freeze(ap);
/*
* If we have timed out qcs. They belong to EH from
* this point but the state of the controller is
* unknown. Freeze the port to make sure the IRQ
* handler doesn't diddle with those qcs. This must
* be done atomically w.r.t. setting QCFLAG_FAILED.
*/
if (nr_timedout)
__ata_port_freeze(ap);
/* initialize eh_tries */
ap->eh_tries = ATA_EH_MAX_TRIES;
/* initialize eh_tries */
ap->eh_tries = ATA_EH_MAX_TRIES;
}
spin_unlock_irqrestore(ap->lock, flags);
}
EXPORT_SYMBOL(ata_scsi_cmd_error_handler);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment