diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/libata-core.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3a1ec4e715ed..164c7d9514f9 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2751,17 +2751,27 @@ int sata_down_spd_limit(struct ata_link *link) | |||
2751 | 2751 | ||
2752 | static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) | 2752 | static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) |
2753 | { | 2753 | { |
2754 | u32 spd, limit; | 2754 | struct ata_link *host_link = &link->ap->link; |
2755 | u32 limit, target, spd; | ||
2755 | 2756 | ||
2756 | if (link->sata_spd_limit == UINT_MAX) | 2757 | limit = link->sata_spd_limit; |
2757 | limit = 0; | 2758 | |
2759 | /* Don't configure downstream link faster than upstream link. | ||
2760 | * It doesn't speed up anything and some PMPs choke on such | ||
2761 | * configuration. | ||
2762 | */ | ||
2763 | if (!ata_is_host_link(link) && host_link->sata_spd) | ||
2764 | limit &= (1 << host_link->sata_spd) - 1; | ||
2765 | |||
2766 | if (limit == UINT_MAX) | ||
2767 | target = 0; | ||
2758 | else | 2768 | else |
2759 | limit = fls(link->sata_spd_limit); | 2769 | target = fls(limit); |
2760 | 2770 | ||
2761 | spd = (*scontrol >> 4) & 0xf; | 2771 | spd = (*scontrol >> 4) & 0xf; |
2762 | *scontrol = (*scontrol & ~0xf0) | ((limit & 0xf) << 4); | 2772 | *scontrol = (*scontrol & ~0xf0) | ((target & 0xf) << 4); |
2763 | 2773 | ||
2764 | return spd != limit; | 2774 | return spd != target; |
2765 | } | 2775 | } |
2766 | 2776 | ||
2767 | /** | 2777 | /** |