diff options
-rw-r--r-- | drivers/scsi/libata-core.c | 30 |
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 | ||