diff options
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r-- | drivers/ata/libata-eh.c | 87 |
1 files changed, 79 insertions, 8 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 8147a8386370..ce2ef0475339 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -82,6 +82,10 @@ enum { | |||
82 | ATA_EH_FASTDRAIN_INTERVAL = 3000, | 82 | ATA_EH_FASTDRAIN_INTERVAL = 3000, |
83 | 83 | ||
84 | ATA_EH_UA_TRIES = 5, | 84 | ATA_EH_UA_TRIES = 5, |
85 | |||
86 | /* probe speed down parameters, see ata_eh_schedule_probe() */ | ||
87 | ATA_EH_PROBE_TRIAL_INTERVAL = 60000, /* 1 min */ | ||
88 | ATA_EH_PROBE_TRIALS = 2, | ||
85 | }; | 89 | }; |
86 | 90 | ||
87 | /* The following table determines how we sequence resets. Each entry | 91 | /* The following table determines how we sequence resets. Each entry |
@@ -1176,6 +1180,32 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc) | |||
1176 | } | 1180 | } |
1177 | 1181 | ||
1178 | /** | 1182 | /** |
1183 | * ata_dev_disable - disable ATA device | ||
1184 | * @dev: ATA device to disable | ||
1185 | * | ||
1186 | * Disable @dev. | ||
1187 | * | ||
1188 | * Locking: | ||
1189 | * EH context. | ||
1190 | */ | ||
1191 | void ata_dev_disable(struct ata_device *dev) | ||
1192 | { | ||
1193 | if (!ata_dev_enabled(dev)) | ||
1194 | return; | ||
1195 | |||
1196 | if (ata_msg_drv(dev->link->ap)) | ||
1197 | ata_dev_printk(dev, KERN_WARNING, "disabled\n"); | ||
1198 | ata_acpi_on_disable(dev); | ||
1199 | ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); | ||
1200 | dev->class++; | ||
1201 | |||
1202 | /* From now till the next successful probe, ering is used to | ||
1203 | * track probe failures. Clear accumulated device error info. | ||
1204 | */ | ||
1205 | ata_ering_clear(&dev->ering); | ||
1206 | } | ||
1207 | |||
1208 | /** | ||
1179 | * ata_eh_detach_dev - detach ATA device | 1209 | * ata_eh_detach_dev - detach ATA device |
1180 | * @dev: ATA device to detach | 1210 | * @dev: ATA device to detach |
1181 | * | 1211 | * |
@@ -1849,7 +1879,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, | |||
1849 | /* speed down? */ | 1879 | /* speed down? */ |
1850 | if (verdict & ATA_EH_SPDN_SPEED_DOWN) { | 1880 | if (verdict & ATA_EH_SPDN_SPEED_DOWN) { |
1851 | /* speed down SATA link speed if possible */ | 1881 | /* speed down SATA link speed if possible */ |
1852 | if (sata_down_spd_limit(link) == 0) { | 1882 | if (sata_down_spd_limit(link, 0) == 0) { |
1853 | action |= ATA_EH_RESET; | 1883 | action |= ATA_EH_RESET; |
1854 | goto done; | 1884 | goto done; |
1855 | } | 1885 | } |
@@ -2601,11 +2631,11 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2601 | } | 2631 | } |
2602 | 2632 | ||
2603 | if (try == max_tries - 1) { | 2633 | if (try == max_tries - 1) { |
2604 | sata_down_spd_limit(link); | 2634 | sata_down_spd_limit(link, 0); |
2605 | if (slave) | 2635 | if (slave) |
2606 | sata_down_spd_limit(slave); | 2636 | sata_down_spd_limit(slave, 0); |
2607 | } else if (rc == -EPIPE) | 2637 | } else if (rc == -EPIPE) |
2608 | sata_down_spd_limit(failed_link); | 2638 | sata_down_spd_limit(failed_link, 0); |
2609 | 2639 | ||
2610 | if (hardreset) | 2640 | if (hardreset) |
2611 | reset = hardreset; | 2641 | reset = hardreset; |
@@ -2744,6 +2774,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, | |||
2744 | readid_flags, dev->id); | 2774 | readid_flags, dev->id); |
2745 | switch (rc) { | 2775 | switch (rc) { |
2746 | case 0: | 2776 | case 0: |
2777 | /* clear error info accumulated during probe */ | ||
2778 | ata_ering_clear(&dev->ering); | ||
2747 | new_mask |= 1 << dev->devno; | 2779 | new_mask |= 1 << dev->devno; |
2748 | break; | 2780 | break; |
2749 | case -ENOENT: | 2781 | case -ENOENT: |
@@ -2947,9 +2979,24 @@ static int ata_eh_skip_recovery(struct ata_link *link) | |||
2947 | return 1; | 2979 | return 1; |
2948 | } | 2980 | } |
2949 | 2981 | ||
2982 | static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg) | ||
2983 | { | ||
2984 | u64 interval = msecs_to_jiffies(ATA_EH_PROBE_TRIAL_INTERVAL); | ||
2985 | u64 now = get_jiffies_64(); | ||
2986 | int *trials = void_arg; | ||
2987 | |||
2988 | if (ent->timestamp < now - min(now, interval)) | ||
2989 | return -1; | ||
2990 | |||
2991 | (*trials)++; | ||
2992 | return 0; | ||
2993 | } | ||
2994 | |||
2950 | static int ata_eh_schedule_probe(struct ata_device *dev) | 2995 | static int ata_eh_schedule_probe(struct ata_device *dev) |
2951 | { | 2996 | { |
2952 | struct ata_eh_context *ehc = &dev->link->eh_context; | 2997 | struct ata_eh_context *ehc = &dev->link->eh_context; |
2998 | struct ata_link *link = ata_dev_phys_link(dev); | ||
2999 | int trials = 0; | ||
2953 | 3000 | ||
2954 | if (!(ehc->i.probe_mask & (1 << dev->devno)) || | 3001 | if (!(ehc->i.probe_mask & (1 << dev->devno)) || |
2955 | (ehc->did_probe_mask & (1 << dev->devno))) | 3002 | (ehc->did_probe_mask & (1 << dev->devno))) |
@@ -2962,6 +3009,25 @@ static int ata_eh_schedule_probe(struct ata_device *dev) | |||
2962 | ehc->saved_xfer_mode[dev->devno] = 0; | 3009 | ehc->saved_xfer_mode[dev->devno] = 0; |
2963 | ehc->saved_ncq_enabled &= ~(1 << dev->devno); | 3010 | ehc->saved_ncq_enabled &= ~(1 << dev->devno); |
2964 | 3011 | ||
3012 | /* Record and count probe trials on the ering. The specific | ||
3013 | * error mask used is irrelevant. Because a successful device | ||
3014 | * detection clears the ering, this count accumulates only if | ||
3015 | * there are consecutive failed probes. | ||
3016 | * | ||
3017 | * If the count is equal to or higher than ATA_EH_PROBE_TRIALS | ||
3018 | * in the last ATA_EH_PROBE_TRIAL_INTERVAL, link speed is | ||
3019 | * forced to 1.5Gbps. | ||
3020 | * | ||
3021 | * This is to work around cases where failed link speed | ||
3022 | * negotiation results in device misdetection leading to | ||
3023 | * infinite DEVXCHG or PHRDY CHG events. | ||
3024 | */ | ||
3025 | ata_ering_record(&dev->ering, 0, AC_ERR_OTHER); | ||
3026 | ata_ering_map(&dev->ering, ata_count_probe_trials_cb, &trials); | ||
3027 | |||
3028 | if (trials > ATA_EH_PROBE_TRIALS) | ||
3029 | sata_down_spd_limit(link, 1); | ||
3030 | |||
2965 | return 1; | 3031 | return 1; |
2966 | } | 3032 | } |
2967 | 3033 | ||
@@ -2969,7 +3035,11 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err) | |||
2969 | { | 3035 | { |
2970 | struct ata_eh_context *ehc = &dev->link->eh_context; | 3036 | struct ata_eh_context *ehc = &dev->link->eh_context; |
2971 | 3037 | ||
2972 | ehc->tries[dev->devno]--; | 3038 | /* -EAGAIN from EH routine indicates retry without prejudice. |
3039 | * The requester is responsible for ensuring forward progress. | ||
3040 | */ | ||
3041 | if (err != -EAGAIN) | ||
3042 | ehc->tries[dev->devno]--; | ||
2973 | 3043 | ||
2974 | switch (err) { | 3044 | switch (err) { |
2975 | case -ENODEV: | 3045 | case -ENODEV: |
@@ -2979,12 +3049,13 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err) | |||
2979 | /* give it just one more chance */ | 3049 | /* give it just one more chance */ |
2980 | ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1); | 3050 | ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1); |
2981 | case -EIO: | 3051 | case -EIO: |
2982 | if (ehc->tries[dev->devno] == 1 && dev->pio_mode > XFER_PIO_0) { | 3052 | if (ehc->tries[dev->devno] == 1) { |
2983 | /* This is the last chance, better to slow | 3053 | /* This is the last chance, better to slow |
2984 | * down than lose it. | 3054 | * down than lose it. |
2985 | */ | 3055 | */ |
2986 | sata_down_spd_limit(ata_dev_phys_link(dev)); | 3056 | sata_down_spd_limit(ata_dev_phys_link(dev), 0); |
2987 | ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); | 3057 | if (dev->pio_mode > XFER_PIO_0) |
3058 | ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); | ||
2988 | } | 3059 | } |
2989 | } | 3060 | } |
2990 | 3061 | ||