diff options
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r-- | drivers/ata/libata-eh.c | 104 |
1 files changed, 102 insertions, 2 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index bba2ae5df1c2..228740f356c9 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -110,6 +110,13 @@ static const unsigned long ata_eh_identify_timeouts[] = { | |||
110 | ULONG_MAX, | 110 | ULONG_MAX, |
111 | }; | 111 | }; |
112 | 112 | ||
113 | static const unsigned long ata_eh_flush_timeouts[] = { | ||
114 | 15000, /* be generous with flush */ | ||
115 | 15000, /* ditto */ | ||
116 | 30000, /* and even more generous */ | ||
117 | ULONG_MAX, | ||
118 | }; | ||
119 | |||
113 | static const unsigned long ata_eh_other_timeouts[] = { | 120 | static const unsigned long ata_eh_other_timeouts[] = { |
114 | 5000, /* same rationale as identify timeout */ | 121 | 5000, /* same rationale as identify timeout */ |
115 | 10000, /* ditto */ | 122 | 10000, /* ditto */ |
@@ -147,6 +154,8 @@ ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { | |||
147 | .timeouts = ata_eh_other_timeouts, }, | 154 | .timeouts = ata_eh_other_timeouts, }, |
148 | { .commands = CMDS(ATA_CMD_INIT_DEV_PARAMS), | 155 | { .commands = CMDS(ATA_CMD_INIT_DEV_PARAMS), |
149 | .timeouts = ata_eh_other_timeouts, }, | 156 | .timeouts = ata_eh_other_timeouts, }, |
157 | { .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT), | ||
158 | .timeouts = ata_eh_flush_timeouts }, | ||
150 | }; | 159 | }; |
151 | #undef CMDS | 160 | #undef CMDS |
152 | 161 | ||
@@ -870,6 +879,8 @@ static void ata_eh_set_pending(struct ata_port *ap, int fastdrain) | |||
870 | void ata_qc_schedule_eh(struct ata_queued_cmd *qc) | 879 | void ata_qc_schedule_eh(struct ata_queued_cmd *qc) |
871 | { | 880 | { |
872 | struct ata_port *ap = qc->ap; | 881 | struct ata_port *ap = qc->ap; |
882 | struct request_queue *q = qc->scsicmd->device->request_queue; | ||
883 | unsigned long flags; | ||
873 | 884 | ||
874 | WARN_ON(!ap->ops->error_handler); | 885 | WARN_ON(!ap->ops->error_handler); |
875 | 886 | ||
@@ -881,7 +892,9 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc) | |||
881 | * Note that ATA_QCFLAG_FAILED is unconditionally set after | 892 | * Note that ATA_QCFLAG_FAILED is unconditionally set after |
882 | * this function completes. | 893 | * this function completes. |
883 | */ | 894 | */ |
895 | spin_lock_irqsave(q->queue_lock, flags); | ||
884 | blk_abort_request(qc->scsicmd->request); | 896 | blk_abort_request(qc->scsicmd->request); |
897 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
885 | } | 898 | } |
886 | 899 | ||
887 | /** | 900 | /** |
@@ -1615,6 +1628,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) | |||
1615 | } | 1628 | } |
1616 | 1629 | ||
1617 | /* okay, this error is ours */ | 1630 | /* okay, this error is ours */ |
1631 | memset(&tf, 0, sizeof(tf)); | ||
1618 | rc = ata_eh_read_log_10h(dev, &tag, &tf); | 1632 | rc = ata_eh_read_log_10h(dev, &tag, &tf); |
1619 | if (rc) { | 1633 | if (rc) { |
1620 | ata_link_printk(link, KERN_ERR, "failed to read log page 10h " | 1634 | ata_link_printk(link, KERN_ERR, "failed to read log page 10h " |
@@ -2019,8 +2033,9 @@ static void ata_eh_link_autopsy(struct ata_link *link) | |||
2019 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); | 2033 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); |
2020 | 2034 | ||
2021 | /* determine whether the command is worth retrying */ | 2035 | /* determine whether the command is worth retrying */ |
2022 | if (!(qc->err_mask & AC_ERR_INVALID) && | 2036 | if (qc->flags & ATA_QCFLAG_IO || |
2023 | ((qc->flags & ATA_QCFLAG_IO) || qc->err_mask != AC_ERR_DEV)) | 2037 | (!(qc->err_mask & AC_ERR_INVALID) && |
2038 | qc->err_mask != AC_ERR_DEV)) | ||
2024 | qc->flags |= ATA_QCFLAG_RETRY; | 2039 | qc->flags |= ATA_QCFLAG_RETRY; |
2025 | 2040 | ||
2026 | /* accumulate error info */ | 2041 | /* accumulate error info */ |
@@ -3112,6 +3127,82 @@ static int atapi_eh_clear_ua(struct ata_device *dev) | |||
3112 | return 0; | 3127 | return 0; |
3113 | } | 3128 | } |
3114 | 3129 | ||
3130 | /** | ||
3131 | * ata_eh_maybe_retry_flush - Retry FLUSH if necessary | ||
3132 | * @dev: ATA device which may need FLUSH retry | ||
3133 | * | ||
3134 | * If @dev failed FLUSH, it needs to be reported upper layer | ||
3135 | * immediately as it means that @dev failed to remap and already | ||
3136 | * lost at least a sector and further FLUSH retrials won't make | ||
3137 | * any difference to the lost sector. However, if FLUSH failed | ||
3138 | * for other reasons, for example transmission error, FLUSH needs | ||
3139 | * to be retried. | ||
3140 | * | ||
3141 | * This function determines whether FLUSH failure retry is | ||
3142 | * necessary and performs it if so. | ||
3143 | * | ||
3144 | * RETURNS: | ||
3145 | * 0 if EH can continue, -errno if EH needs to be repeated. | ||
3146 | */ | ||
3147 | static int ata_eh_maybe_retry_flush(struct ata_device *dev) | ||
3148 | { | ||
3149 | struct ata_link *link = dev->link; | ||
3150 | struct ata_port *ap = link->ap; | ||
3151 | struct ata_queued_cmd *qc; | ||
3152 | struct ata_taskfile tf; | ||
3153 | unsigned int err_mask; | ||
3154 | int rc = 0; | ||
3155 | |||
3156 | /* did flush fail for this device? */ | ||
3157 | if (!ata_tag_valid(link->active_tag)) | ||
3158 | return 0; | ||
3159 | |||
3160 | qc = __ata_qc_from_tag(ap, link->active_tag); | ||
3161 | if (qc->dev != dev || (qc->tf.command != ATA_CMD_FLUSH_EXT && | ||
3162 | qc->tf.command != ATA_CMD_FLUSH)) | ||
3163 | return 0; | ||
3164 | |||
3165 | /* if the device failed it, it should be reported to upper layers */ | ||
3166 | if (qc->err_mask & AC_ERR_DEV) | ||
3167 | return 0; | ||
3168 | |||
3169 | /* flush failed for some other reason, give it another shot */ | ||
3170 | ata_tf_init(dev, &tf); | ||
3171 | |||
3172 | tf.command = qc->tf.command; | ||
3173 | tf.flags |= ATA_TFLAG_DEVICE; | ||
3174 | tf.protocol = ATA_PROT_NODATA; | ||
3175 | |||
3176 | ata_dev_printk(dev, KERN_WARNING, "retrying FLUSH 0x%x Emask 0x%x\n", | ||
3177 | tf.command, qc->err_mask); | ||
3178 | |||
3179 | err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); | ||
3180 | if (!err_mask) { | ||
3181 | /* | ||
3182 | * FLUSH is complete but there's no way to | ||
3183 | * successfully complete a failed command from EH. | ||
3184 | * Making sure retry is allowed at least once and | ||
3185 | * retrying it should do the trick - whatever was in | ||
3186 | * the cache is already on the platter and this won't | ||
3187 | * cause infinite loop. | ||
3188 | */ | ||
3189 | qc->scsicmd->allowed = max(qc->scsicmd->allowed, 1); | ||
3190 | } else { | ||
3191 | ata_dev_printk(dev, KERN_WARNING, "FLUSH failed Emask 0x%x\n", | ||
3192 | err_mask); | ||
3193 | rc = -EIO; | ||
3194 | |||
3195 | /* if device failed it, report it to upper layers */ | ||
3196 | if (err_mask & AC_ERR_DEV) { | ||
3197 | qc->err_mask |= AC_ERR_DEV; | ||
3198 | qc->result_tf = tf; | ||
3199 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | ||
3200 | rc = 0; | ||
3201 | } | ||
3202 | } | ||
3203 | return rc; | ||
3204 | } | ||
3205 | |||
3115 | static int ata_link_nr_enabled(struct ata_link *link) | 3206 | static int ata_link_nr_enabled(struct ata_link *link) |
3116 | { | 3207 | { |
3117 | struct ata_device *dev; | 3208 | struct ata_device *dev; |
@@ -3455,6 +3546,15 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
3455 | } | 3546 | } |
3456 | } | 3547 | } |
3457 | 3548 | ||
3549 | /* retry flush if necessary */ | ||
3550 | ata_for_each_dev(dev, link, ALL) { | ||
3551 | if (dev->class != ATA_DEV_ATA) | ||
3552 | continue; | ||
3553 | rc = ata_eh_maybe_retry_flush(dev); | ||
3554 | if (rc) | ||
3555 | goto dev_fail; | ||
3556 | } | ||
3557 | |||
3458 | /* configure link power saving */ | 3558 | /* configure link power saving */ |
3459 | if (ehc->i.action & ATA_EH_LPM) | 3559 | if (ehc->i.action & ATA_EH_LPM) |
3460 | ata_for_each_dev(dev, link, ALL) | 3560 | ata_for_each_dev(dev, link, ALL) |