summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-10-16 13:00:51 +0900
committerGreg Kroah-Hartman <gregkh@suse.de>2009-11-09 16:52:09 -0800
commit30aae6d58a0cc3447ca149de5b73769d6206477a (patch)
tree8418e89ff38b6294508d4911c8d3ab2b8f17d9e5 /drivers
parent506d32b08b4cf1c048c4908820bea6ce94592ea5 (diff)
libata: fix internal command failure handling
commit f4b31db92d163df8a639f5a8c8633bdeb6e8432d upstream. When an internal command fails, it should be failed directly without invoking EH. In the original implemetation, this was accomplished by letting internal command bypass failure handling in ata_qc_complete(). However, later changes added post-successful-completion handling to that code path and the success path is no longer adequate as internal command failure path. One of the visible problems is that internal command failure due to timeout or other freeze conditions would spuriously trigger WARN_ON_ONCE() in the success path. This patch updates failure path such that internal command failure handling is contained there. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-core.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 5cdd821df1b8..8afc2740f1dc 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4747,12 +4747,14 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
qc->flags |= ATA_QCFLAG_FAILED;
if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
- if (!ata_tag_internal(qc->tag)) {
- /* always fill result TF for failed qc */
- fill_result_tf(qc);
+ /* always fill result TF for failed qc */
+ fill_result_tf(qc);
+
+ if (!ata_tag_internal(qc->tag))
ata_qc_schedule_eh(qc);
- return;
- }
+ else
+ __ata_qc_complete(qc);
+ return;
}
/* read result TF if requested */