aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-10-31 10:17:07 +0900
committerJeff Garzik <jeff@garzik.org>2007-11-03 08:47:27 -0400
commit5270222f96608818e431b5c4029b1f12020ab719 (patch)
tree564f141932bc4740ebf3ea0a17f2a03427913a8c
parentdb64bcf387aae6c7afad122a529d7d0513d3c5db (diff)
libata: don't configure downstream links faster than the upstream link
There's nothing to be gained by configuring downstream links faster than the upstream link and such configurations cause problems on certain PMPs. Limit downstream link speed by the upstream link speed. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/libata-core.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3a1ec4e715e..164c7d9514f 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)
static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol)
{
- u32 spd, limit;
+ struct ata_link *host_link = &link->ap->link;
+ u32 limit, target, spd;
- if (link->sata_spd_limit == UINT_MAX)
- limit = 0;
+ limit = link->sata_spd_limit;
+
+ /* Don't configure downstream link faster than upstream link.
+ * It doesn't speed up anything and some PMPs choke on such
+ * configuration.
+ */
+ if (!ata_is_host_link(link) && host_link->sata_spd)
+ limit &= (1 << host_link->sata_spd) - 1;
+
+ if (limit == UINT_MAX)
+ target = 0;
else
- limit = fls(link->sata_spd_limit);
+ target = fls(limit);
spd = (*scontrol >> 4) & 0xf;
- *scontrol = (*scontrol & ~0xf0) | ((limit & 0xf) << 4);
+ *scontrol = (*scontrol & ~0xf0) | ((target & 0xf) << 4);
- return spd != limit;
+ return spd != target;
}
/**