mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00
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: Wenchao Hao <haowenchao@huawei.com> Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
This commit is contained in:
parent
f060ba1882
commit
b83ad9eec3
|
@ -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
|
||||
/*
|
||||
* 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);
|
||||
|
||||
The lost_interrupt handler checks for any completed but
|
||||
non-notified command and completes much like an IRQ handler.
|
||||
list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) {
|
||||
struct ata_queued_cmd *qc;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
ata_qc_for_each_raw(ap, qc, i) {
|
||||
if (qc->flags & ATA_QCFLAG_ACTIVE &&
|
||||
qc->scsicmd == scmd)
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(ata_scsi_cmd_error_handler);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user