Update ata_exec_internal() such that it uses new EH framework. ->post_internal_cmd() is always invoked regardless of completion status. Also, when ata_exec_internal() detects a timeout condition and new EH is in place, it freezes the port as timeout for normal commands would do. Signed-off-by: Tejun Heo <htejun@xxxxxxxxx> --- drivers/scsi/libata-core.c | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-) 4e9465fdf6b1bbd2eca5116144724500739239c3 diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 1069aa9..2e80930 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -1043,13 +1043,17 @@ unsigned ata_exec_internal(struct ata_po /* We're racing with irq here. If we lose, the * following test prevents us from completing the qc - * again. If completion irq occurs after here but - * before the caller cleans up, it will result in a - * spurious interrupt. We can live with that. + * twice. If we win, the port is frozen and will be + * cleaned up by ->post_internal_cmd(). */ if (qc->flags & ATA_QCFLAG_ACTIVE) { - qc->err_mask = AC_ERR_TIMEOUT; - ata_qc_complete(qc); + qc->err_mask |= AC_ERR_TIMEOUT; + + if (ap->ops->error_handler) + ata_eh_schedule_port(ap, ATA_EH_FREEZE); + else + ata_qc_complete(qc); + printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n", ap->id, command); } @@ -1057,6 +1061,9 @@ unsigned ata_exec_internal(struct ata_po spin_unlock_irqrestore(&ap->host_set->lock, flags); } + if (ap->ops->post_internal_cmd) + ap->ops->post_internal_cmd(qc); + *tf = qc->tf; err_mask = qc->err_mask; -- 1.2.4 - : send the line "unsubscribe linux-ide" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html