|
@@ -2389,21 +2389,35 @@ int sata_down_spd_limit(struct ata_port *ap)
|
|
|
u32 sstatus, spd, mask;
|
|
|
int rc, highbit;
|
|
|
|
|
|
+ if (!sata_scr_valid(ap))
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ /* If SCR can be read, use it to determine the current SPD.
|
|
|
+ * If not, use cached value in ap->sata_spd.
|
|
|
+ */
|
|
|
rc = sata_scr_read(ap, SCR_STATUS, &sstatus);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
+ if (rc == 0)
|
|
|
+ spd = (sstatus >> 4) & 0xf;
|
|
|
+ else
|
|
|
+ spd = ap->sata_spd;
|
|
|
|
|
|
mask = ap->sata_spd_limit;
|
|
|
if (mask <= 1)
|
|
|
return -EINVAL;
|
|
|
+
|
|
|
+ /* unconditionally mask off the highest bit */
|
|
|
highbit = fls(mask) - 1;
|
|
|
mask &= ~(1 << highbit);
|
|
|
|
|
|
- spd = (sstatus >> 4) & 0xf;
|
|
|
- if (spd <= 1)
|
|
|
- return -EINVAL;
|
|
|
- spd--;
|
|
|
- mask &= (1 << spd) - 1;
|
|
|
+ /* Mask off all speeds higher than or equal to the current
|
|
|
+ * one. Force 1.5Gbps if current SPD is not available.
|
|
|
+ */
|
|
|
+ if (spd > 1)
|
|
|
+ mask &= (1 << (spd - 1)) - 1;
|
|
|
+ else
|
|
|
+ mask &= 1;
|
|
|
+
|
|
|
+ /* were we already at the bottom? */
|
|
|
if (!mask)
|
|
|
return -EINVAL;
|
|
|
|
|
@@ -5995,6 +6009,7 @@ void ata_dev_init(struct ata_device *dev)
|
|
|
|
|
|
/* SATA spd limit is bound to the first device */
|
|
|
ap->sata_spd_limit = ap->hw_sata_spd_limit;
|
|
|
+ ap->sata_spd = 0;
|
|
|
|
|
|
/* High bits of dev->flags are used to record warm plug
|
|
|
* requests which occur asynchronously. Synchronize using
|