aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 35ae5b41f662..4def48ed6f46 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