aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libata-core.c143
-rw-r--r--include/linux/libata.h1
2 files changed, 140 insertions, 4 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 3acf56200d8..63488673765 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -65,6 +65,7 @@ static unsigned int ata_dev_init_params(struct ata_port *ap,
65 struct ata_device *dev, 65 struct ata_device *dev,
66 u16 heads, 66 u16 heads,
67 u16 sectors); 67 u16 sectors);
68static int ata_down_sata_spd_limit(struct ata_port *ap);
68static int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev); 69static int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
69static unsigned int ata_dev_set_xfermode(struct ata_port *ap, 70static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
70 struct ata_device *dev); 71 struct ata_device *dev);
@@ -1596,6 +1597,120 @@ void ata_port_disable(struct ata_port *ap)
1596 ap->flags |= ATA_FLAG_PORT_DISABLED; 1597 ap->flags |= ATA_FLAG_PORT_DISABLED;
1597} 1598}
1598 1599
1600/**
1601 * ata_down_sata_spd_limit - adjust SATA spd limit downward
1602 * @ap: Port to adjust SATA spd limit for
1603 *
1604 * Adjust SATA spd limit of @ap downward. Note that this
1605 * function only adjusts the limit. The change must be applied
1606 * using ata_set_sata_spd().
1607 *
1608 * LOCKING:
1609 * Inherited from caller.
1610 *
1611 * RETURNS:
1612 * 0 on success, negative errno on failure
1613 */
1614static int ata_down_sata_spd_limit(struct ata_port *ap)
1615{
1616 u32 spd, mask;
1617 int highbit;
1618
1619 if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
1620 return -EOPNOTSUPP;
1621
1622 mask = ap->sata_spd_limit;
1623 if (mask <= 1)
1624 return -EINVAL;
1625 highbit = fls(mask) - 1;
1626 mask &= ~(1 << highbit);
1627
1628 spd = (scr_read(ap, SCR_STATUS) >> 4) & 0xf;
1629 if (spd <= 1)
1630 return -EINVAL;
1631 spd--;
1632 mask &= (1 << spd) - 1;
1633 if (!mask)
1634 return -EINVAL;
1635
1636 ap->sata_spd_limit = mask;
1637
1638 printk(KERN_WARNING "ata%u: limiting SATA link speed to %s\n",
1639 ap->id, sata_spd_string(fls(mask)));
1640
1641 return 0;
1642}
1643
1644static int __ata_set_sata_spd_needed(struct ata_port *ap, u32 *scontrol)
1645{
1646 u32 spd, limit;
1647
1648 if (ap->sata_spd_limit == UINT_MAX)
1649 limit = 0;
1650 else
1651 limit = fls(ap->sata_spd_limit);
1652
1653 spd = (*scontrol >> 4) & 0xf;
1654 *scontrol = (*scontrol & ~0xf0) | ((limit & 0xf) << 4);
1655
1656 return spd != limit;
1657}
1658
1659/**
1660 * ata_set_sata_spd_needed - is SATA spd configuration needed
1661 * @ap: Port in question
1662 *
1663 * Test whether the spd limit in SControl matches
1664 * @ap->sata_spd_limit. This function is used to determine
1665 * whether hardreset is necessary to apply SATA spd
1666 * configuration.
1667 *
1668 * LOCKING:
1669 * Inherited from caller.
1670 *
1671 * RETURNS:
1672 * 1 if SATA spd configuration is needed, 0 otherwise.
1673 */
1674static int ata_set_sata_spd_needed(struct ata_port *ap)
1675{
1676 u32 scontrol;
1677
1678 if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
1679 return 0;
1680
1681 scontrol = scr_read(ap, SCR_CONTROL);
1682
1683 return __ata_set_sata_spd_needed(ap, &scontrol);
1684}
1685
1686/**
1687 * ata_set_sata_spd - set SATA spd according to spd limit
1688 * @ap: Port to set SATA spd for
1689 *
1690 * Set SATA spd of @ap according to sata_spd_limit.
1691 *
1692 * LOCKING:
1693 * Inherited from caller.
1694 *
1695 * RETURNS:
1696 * 0 if spd doesn't need to be changed, 1 if spd has been
1697 * changed. -EOPNOTSUPP if SCR registers are inaccessible.
1698 */
1699static int ata_set_sata_spd(struct ata_port *ap)
1700{
1701 u32 scontrol;
1702
1703 if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read)
1704 return -EOPNOTSUPP;
1705
1706 scontrol = scr_read(ap, SCR_CONTROL);
1707 if (!__ata_set_sata_spd_needed(ap, &scontrol))
1708 return 0;
1709
1710 scr_write(ap, SCR_CONTROL, scontrol);
1711 return 1;
1712}
1713
1599/* 1714/*
1600 * This mode timing computation functionality is ported over from 1715 * This mode timing computation functionality is ported over from
1601 * drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik 1716 * drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik
@@ -2165,7 +2280,14 @@ static int sata_phy_resume(struct ata_port *ap)
2165void ata_std_probeinit(struct ata_port *ap) 2280void ata_std_probeinit(struct ata_port *ap)
2166{ 2281{
2167 if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) { 2282 if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) {
2283 u32 spd;
2284
2168 sata_phy_resume(ap); 2285 sata_phy_resume(ap);
2286
2287 spd = (scr_read(ap, SCR_CONTROL) & 0xf0) >> 4;
2288 if (spd)
2289 ap->sata_spd_limit &= (1 << spd) - 1;
2290
2169 if (sata_dev_present(ap)) 2291 if (sata_dev_present(ap))
2170 ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); 2292 ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
2171 } 2293 }
@@ -2253,18 +2375,30 @@ int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
2253 2375
2254 DPRINTK("ENTER\n"); 2376 DPRINTK("ENTER\n");
2255 2377
2256 /* Issue phy wake/reset */ 2378 if (ata_set_sata_spd_needed(ap)) {
2379 /* SATA spec says nothing about how to reconfigure
2380 * spd. To be on the safe side, turn off phy during
2381 * reconfiguration. This works for at least ICH7 AHCI
2382 * and Sil3124.
2383 */
2384 scontrol = scr_read(ap, SCR_CONTROL);
2385 scontrol = (scontrol & 0x0f0) | 0x302;
2386 scr_write_flush(ap, SCR_CONTROL, scontrol);
2387
2388 ata_set_sata_spd(ap);
2389 }
2390
2391 /* issue phy wake/reset */
2257 scontrol = scr_read(ap, SCR_CONTROL); 2392 scontrol = scr_read(ap, SCR_CONTROL);
2258 scontrol = (scontrol & 0x0f0) | 0x301; 2393 scontrol = (scontrol & 0x0f0) | 0x301;
2259 scr_write_flush(ap, SCR_CONTROL, scontrol); 2394 scr_write_flush(ap, SCR_CONTROL, scontrol);
2260 2395
2261 /* 2396 /* Couldn't find anything in SATA I/II specs, but AHCI-1.1
2262 * Couldn't find anything in SATA I/II specs, but AHCI-1.1
2263 * 10.4.2 says at least 1 ms. 2397 * 10.4.2 says at least 1 ms.
2264 */ 2398 */
2265 msleep(1); 2399 msleep(1);
2266 2400
2267 /* Bring phy back */ 2401 /* bring phy back */
2268 sata_phy_resume(ap); 2402 sata_phy_resume(ap);
2269 2403
2270 /* TODO: phy layer with polling, timeouts, etc. */ 2404 /* TODO: phy layer with polling, timeouts, etc. */
@@ -4454,6 +4588,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
4454 ap->flags |= ent->host_flags; 4588 ap->flags |= ent->host_flags;
4455 ap->ops = ent->port_ops; 4589 ap->ops = ent->port_ops;
4456 ap->cbl = ATA_CBL_NONE; 4590 ap->cbl = ATA_CBL_NONE;
4591 ap->sata_spd_limit = UINT_MAX;
4457 ap->active_tag = ATA_TAG_POISON; 4592 ap->active_tag = ATA_TAG_POISON;
4458 ap->last_ctl = 0xFF; 4593 ap->last_ctl = 0xFF;
4459 4594
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 0f8e3720edd..a5207e66ca5 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -397,6 +397,7 @@ struct ata_port {
397 unsigned int mwdma_mask; 397 unsigned int mwdma_mask;
398 unsigned int udma_mask; 398 unsigned int udma_mask;
399 unsigned int cbl; /* cable type; ATA_CBL_xxx */ 399 unsigned int cbl; /* cable type; ATA_CBL_xxx */
400 unsigned int sata_spd_limit; /* SATA PHY speed limit */
400 401
401 struct ata_device device[ATA_MAX_DEVICES]; 402 struct ata_device device[ATA_MAX_DEVICES];
402 403