aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-core.c29
-rw-r--r--drivers/ata/libata-eh.c6
-rw-r--r--include/linux/libata.h1
3 files changed, 29 insertions, 7 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 5718c247e23a..c325b7a4246a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2389,21 +2389,35 @@ int sata_down_spd_limit(struct ata_port *ap)
2389 u32 sstatus, spd, mask; 2389 u32 sstatus, spd, mask;
2390 int rc, highbit; 2390 int rc, highbit;
2391 2391
2392 if (!sata_scr_valid(ap))
2393 return -EOPNOTSUPP;
2394
2395 /* If SCR can be read, use it to determine the current SPD.
2396 * If not, use cached value in ap->sata_spd.
2397 */
2392 rc = sata_scr_read(ap, SCR_STATUS, &sstatus); 2398 rc = sata_scr_read(ap, SCR_STATUS, &sstatus);
2393 if (rc) 2399 if (rc == 0)
2394 return rc; 2400 spd = (sstatus >> 4) & 0xf;
2401 else
2402 spd = ap->sata_spd;
2395 2403
2396 mask = ap->sata_spd_limit; 2404 mask = ap->sata_spd_limit;
2397 if (mask <= 1) 2405 if (mask <= 1)
2398 return -EINVAL; 2406 return -EINVAL;
2407
2408 /* unconditionally mask off the highest bit */
2399 highbit = fls(mask) - 1; 2409 highbit = fls(mask) - 1;
2400 mask &= ~(1 << highbit); 2410 mask &= ~(1 << highbit);
2401 2411
2402 spd = (sstatus >> 4) & 0xf; 2412 /* Mask off all speeds higher than or equal to the current
2403 if (spd <= 1) 2413 * one. Force 1.5Gbps if current SPD is not available.
2404 return -EINVAL; 2414 */
2405 spd--; 2415 if (spd > 1)
2406 mask &= (1 << spd) - 1; 2416 mask &= (1 << (spd - 1)) - 1;
2417 else
2418 mask &= 1;
2419
2420 /* were we already at the bottom? */
2407 if (!mask) 2421 if (!mask)
2408 return -EINVAL; 2422 return -EINVAL;
2409 2423
@@ -5995,6 +6009,7 @@ void ata_dev_init(struct ata_device *dev)
5995 6009
5996 /* SATA spd limit is bound to the first device */ 6010 /* SATA spd limit is bound to the first device */
5997 ap->sata_spd_limit = ap->hw_sata_spd_limit; 6011 ap->sata_spd_limit = ap->hw_sata_spd_limit;
6012 ap->sata_spd = 0;
5998 6013
5999 /* High bits of dev->flags are used to record warm plug 6014 /* High bits of dev->flags are used to record warm plug
6000 * requests which occur asynchronously. Synchronize using 6015 * requests which occur asynchronously. Synchronize using
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 19f9947bd96b..183eaf466d4f 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1799,12 +1799,18 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
1799 } 1799 }
1800 1800
1801 if (rc == 0) { 1801 if (rc == 0) {
1802 u32 sstatus;
1803
1802 /* After the reset, the device state is PIO 0 and the 1804 /* After the reset, the device state is PIO 0 and the
1803 * controller state is undefined. Record the mode. 1805 * controller state is undefined. Record the mode.
1804 */ 1806 */
1805 for (i = 0; i < ATA_MAX_DEVICES; i++) 1807 for (i = 0; i < ATA_MAX_DEVICES; i++)
1806 ap->device[i].pio_mode = XFER_PIO_0; 1808 ap->device[i].pio_mode = XFER_PIO_0;
1807 1809
1810 /* record current link speed */
1811 if (sata_scr_read(ap, SCR_STATUS, &sstatus) == 0)
1812 ap->sata_spd = (sstatus >> 4) & 0xf;
1813
1808 if (postreset) 1814 if (postreset)
1809 postreset(ap, classes); 1815 postreset(ap, classes);
1810 1816
diff --git a/include/linux/libata.h b/include/linux/libata.h
index c732b3e78e28..16ebdf152c75 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -531,6 +531,7 @@ struct ata_port {
531 unsigned int cbl; /* cable type; ATA_CBL_xxx */ 531 unsigned int cbl; /* cable type; ATA_CBL_xxx */
532 unsigned int hw_sata_spd_limit; 532 unsigned int hw_sata_spd_limit;
533 unsigned int sata_spd_limit; /* SATA PHY speed limit */ 533 unsigned int sata_spd_limit; /* SATA PHY speed limit */
534 unsigned int sata_spd; /* current SATA PHY speed */
534 535
535 /* record runtime error info, protected by host lock */ 536 /* record runtime error info, protected by host lock */
536 struct ata_eh_info eh_info; 537 struct ata_eh_info eh_info;