diff options
-rw-r--r-- | drivers/ata/libata-eh.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index d1fbd59ead16..6d53cf9b3b6e 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -2047,6 +2047,26 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, | |||
2047 | } | 2047 | } |
2048 | 2048 | ||
2049 | /** | 2049 | /** |
2050 | * ata_eh_worth_retry - analyze error and decide whether to retry | ||
2051 | * @qc: qc to possibly retry | ||
2052 | * | ||
2053 | * Look at the cause of the error and decide if a retry | ||
2054 | * might be useful or not. We don't want to retry media errors | ||
2055 | * because the drive itself has probably already taken 10-30 seconds | ||
2056 | * doing its own internal retries before reporting the failure. | ||
2057 | */ | ||
2058 | static inline int ata_eh_worth_retry(struct ata_queued_cmd *qc) | ||
2059 | { | ||
2060 | if (qc->flags & AC_ERR_MEDIA) | ||
2061 | return 0; /* don't retry media errors */ | ||
2062 | if (qc->flags & ATA_QCFLAG_IO) | ||
2063 | return 1; /* otherwise retry anything from fs stack */ | ||
2064 | if (qc->err_mask & AC_ERR_INVALID) | ||
2065 | return 0; /* don't retry these */ | ||
2066 | return qc->err_mask != AC_ERR_DEV; /* retry if not dev error */ | ||
2067 | } | ||
2068 | |||
2069 | /** | ||
2050 | * ata_eh_link_autopsy - analyze error and determine recovery action | 2070 | * ata_eh_link_autopsy - analyze error and determine recovery action |
2051 | * @link: host link to perform autopsy on | 2071 | * @link: host link to perform autopsy on |
2052 | * | 2072 | * |
@@ -2120,9 +2140,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) | |||
2120 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); | 2140 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); |
2121 | 2141 | ||
2122 | /* determine whether the command is worth retrying */ | 2142 | /* determine whether the command is worth retrying */ |
2123 | if (qc->flags & ATA_QCFLAG_IO || | 2143 | if (ata_eh_worth_retry(qc)) |
2124 | (!(qc->err_mask & AC_ERR_INVALID) && | ||
2125 | qc->err_mask != AC_ERR_DEV)) | ||
2126 | qc->flags |= ATA_QCFLAG_RETRY; | 2144 | qc->flags |= ATA_QCFLAG_RETRY; |
2127 | 2145 | ||
2128 | /* accumulate error info */ | 2146 | /* accumulate error info */ |