aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-15 07:58:14 -0400
committerTejun Heo <htejun@gmail.com>2006-05-15 07:58:14 -0400
commitd95a717f579e81061830a308125c89f5858f740a (patch)
treeefa4b35ffcd1f8f3eabe5cb27ffc128313378064 /drivers/scsi
parentad9e27624479bd167dd7eac0cea4bb3ad13bc926 (diff)
[PATCH] libata-eh-fw: update ata_exec_internal() for new EH
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. Note that ata_port_flush_task() is called regardless of wait_for_completion status. This is necessary as exceptions unrelated to the qc can abort the qc, in which case PIO task could still be running after the wait for completion returns. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/libata-core.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 35ae5b41f66..4def48ed6f4 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -984,6 +984,7 @@ unsigned ata_exec_internal(struct ata_device *dev,
984 DECLARE_COMPLETION(wait); 984 DECLARE_COMPLETION(wait);
985 unsigned long flags; 985 unsigned long flags;
986 unsigned int err_mask; 986 unsigned int err_mask;
987 int rc;
987 988
988 spin_lock_irqsave(&ap->host_set->lock, flags); 989 spin_lock_irqsave(&ap->host_set->lock, flags);
989 990
@@ -1036,20 +1037,25 @@ unsigned ata_exec_internal(struct ata_device *dev,
1036 1037
1037 spin_unlock_irqrestore(&ap->host_set->lock, flags); 1038 spin_unlock_irqrestore(&ap->host_set->lock, flags);
1038 1039
1039 if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) { 1040 rc = wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL);
1040 ata_port_flush_task(ap); 1041
1042 ata_port_flush_task(ap);
1041 1043
1044 if (!rc) {
1042 spin_lock_irqsave(&ap->host_set->lock, flags); 1045 spin_lock_irqsave(&ap->host_set->lock, flags);
1043 1046
1044 /* We're racing with irq here. If we lose, the 1047 /* We're racing with irq here. If we lose, the
1045 * following test prevents us from completing the qc 1048 * following test prevents us from completing the qc
1046 * again. If completion irq occurs after here but 1049 * twice. If we win, the port is frozen and will be
1047 * before the caller cleans up, it will result in a 1050 * cleaned up by ->post_internal_cmd().
1048 * spurious interrupt. We can live with that.
1049 */ 1051 */
1050 if (qc->flags & ATA_QCFLAG_ACTIVE) { 1052 if (qc->flags & ATA_QCFLAG_ACTIVE) {
1051 qc->err_mask = AC_ERR_TIMEOUT; 1053 qc->err_mask |= AC_ERR_TIMEOUT;
1052 ata_qc_complete(qc); 1054
1055 if (ap->ops->error_handler)
1056 ata_port_freeze(ap);
1057 else
1058 ata_qc_complete(qc);
1053 1059
1054 ata_dev_printk(dev, KERN_WARNING, 1060 ata_dev_printk(dev, KERN_WARNING,
1055 "qc timeout (cmd 0x%x)\n", command); 1061 "qc timeout (cmd 0x%x)\n", command);
@@ -1058,6 +1064,16 @@ unsigned ata_exec_internal(struct ata_device *dev,
1058 spin_unlock_irqrestore(&ap->host_set->lock, flags); 1064 spin_unlock_irqrestore(&ap->host_set->lock, flags);
1059 } 1065 }
1060 1066
1067 /* do post_internal_cmd */
1068 if (ap->ops->post_internal_cmd)
1069 ap->ops->post_internal_cmd(qc);
1070
1071 if (qc->flags & ATA_QCFLAG_FAILED && !qc->err_mask) {
1072 ata_dev_printk(dev, KERN_WARNING, "zero err_mask for failed "
1073 "internal command, assuming AC_ERR_OTHER\n");
1074 qc->err_mask |= AC_ERR_OTHER;
1075 }
1076
1061 /* finish up */ 1077 /* finish up */
1062 spin_lock_irqsave(&ap->host_set->lock, flags); 1078 spin_lock_irqsave(&ap->host_set->lock, flags);
1063 1079