summaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-03-20 15:24:11 +0900
committerJeff Garzik <jeff@garzik.org>2007-04-28 14:16:02 -0400
commita51d644af6eb0a93bc383e5f005faa445c87f335 (patch)
treeb1392796d9766e86e7a87d57dd0f7d62e0fa0dfa /drivers/ata/libata-eh.c
parent55a6adeea4077521b4bba1dfe674f5835157a00b (diff)
libata: improve AC_ERR_DEV handling for ->post_internal_cmd
->post_internal_cmd is simplified EH for internal commands. Its primary mission is to stop the controller such that no rogue memory access or other activities occur after the internal command is released. It may provide error diagnostics by setting qc->err_mask but this hasn't been a requirement. To ignore SETXFER failure for CFA devices, libata needs to know whether a command was failed by the device or for any other reason. ie. internal command needs to get AC_ERR_DEV right. This patch makes the following changes to AC_ERR_DEV handling and ->post_internal_cmd semantics to accomodate this need and simplify callback implementation. 1. As long as the correct bits in the result TF registers are set, there is no need to set AC_ERR_DEV explicitly. libata EH core takes care of that for both normal and internal commands. 2. The only requirement for ->post_internal_cmd() is to put the controller into quiescent state. It needs not to set any err_mask. 3. ata_exec_internal_sg() performs minimal error analysis such that AC_ERR_DEV is automatically set as long as result_tf is filled correctly. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r--drivers/ata/libata-eh.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 185876aba64..0dbee550f9e 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1151,7 +1151,9 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
return ATA_EH_SOFTRESET;
}
- if (!(qc->err_mask & AC_ERR_DEV))
+ if (stat & (ATA_ERR | ATA_DF))
+ qc->err_mask |= AC_ERR_DEV;
+ else
return 0;
switch (qc->dev->class) {