aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libahci.c')
-rw-r--r--drivers/ata/libahci.c194
1 files changed, 64 insertions, 130 deletions
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 8eea309ea212..ebc08d65b3dd 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -56,9 +56,8 @@ MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)
56module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); 56module_param_named(ignore_sss, ahci_ignore_sss, int, 0444);
57MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); 57MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)");
58 58
59static int ahci_enable_alpm(struct ata_port *ap, 59static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
60 enum link_pm policy); 60 unsigned hints);
61static void ahci_disable_alpm(struct ata_port *ap);
62static ssize_t ahci_led_show(struct ata_port *ap, char *buf); 61static ssize_t ahci_led_show(struct ata_port *ap, char *buf);
63static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, 62static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,
64 size_t size); 63 size_t size);
@@ -164,8 +163,7 @@ struct ata_port_operations ahci_ops = {
164 .pmp_attach = ahci_pmp_attach, 163 .pmp_attach = ahci_pmp_attach,
165 .pmp_detach = ahci_pmp_detach, 164 .pmp_detach = ahci_pmp_detach,
166 165
167 .enable_pm = ahci_enable_alpm, 166 .set_lpm = ahci_set_lpm,
168 .disable_pm = ahci_disable_alpm,
169 .em_show = ahci_led_show, 167 .em_show = ahci_led_show,
170 .em_store = ahci_led_store, 168 .em_store = ahci_led_store,
171 .sw_activity_show = ahci_activity_show, 169 .sw_activity_show = ahci_activity_show,
@@ -569,7 +567,7 @@ int ahci_stop_engine(struct ata_port *ap)
569 writel(tmp, port_mmio + PORT_CMD); 567 writel(tmp, port_mmio + PORT_CMD);
570 568
571 /* wait for engine to stop. This could be as long as 500 msec */ 569 /* wait for engine to stop. This could be as long as 500 msec */
572 tmp = ata_wait_register(port_mmio + PORT_CMD, 570 tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
573 PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); 571 PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
574 if (tmp & PORT_CMD_LIST_ON) 572 if (tmp & PORT_CMD_LIST_ON)
575 return -EIO; 573 return -EIO;
@@ -616,7 +614,7 @@ static int ahci_stop_fis_rx(struct ata_port *ap)
616 writel(tmp, port_mmio + PORT_CMD); 614 writel(tmp, port_mmio + PORT_CMD);
617 615
618 /* wait for completion, spec says 500ms, give it 1000 */ 616 /* wait for completion, spec says 500ms, give it 1000 */
619 tmp = ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_FIS_ON, 617 tmp = ata_wait_register(ap, port_mmio + PORT_CMD, PORT_CMD_FIS_ON,
620 PORT_CMD_FIS_ON, 10, 1000); 618 PORT_CMD_FIS_ON, 10, 1000);
621 if (tmp & PORT_CMD_FIS_ON) 619 if (tmp & PORT_CMD_FIS_ON)
622 return -EBUSY; 620 return -EBUSY;
@@ -642,127 +640,56 @@ static void ahci_power_up(struct ata_port *ap)
642 writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); 640 writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD);
643} 641}
644 642
645static void ahci_disable_alpm(struct ata_port *ap) 643static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
644 unsigned int hints)
646{ 645{
646 struct ata_port *ap = link->ap;
647 struct ahci_host_priv *hpriv = ap->host->private_data; 647 struct ahci_host_priv *hpriv = ap->host->private_data;
648 void __iomem *port_mmio = ahci_port_base(ap);
649 u32 cmd;
650 struct ahci_port_priv *pp = ap->private_data; 648 struct ahci_port_priv *pp = ap->private_data;
651
652 /* IPM bits should be disabled by libata-core */
653 /* get the existing command bits */
654 cmd = readl(port_mmio + PORT_CMD);
655
656 /* disable ALPM and ASP */
657 cmd &= ~PORT_CMD_ASP;
658 cmd &= ~PORT_CMD_ALPE;
659
660 /* force the interface back to active */
661 cmd |= PORT_CMD_ICC_ACTIVE;
662
663 /* write out new cmd value */
664 writel(cmd, port_mmio + PORT_CMD);
665 cmd = readl(port_mmio + PORT_CMD);
666
667 /* wait 10ms to be sure we've come out of any low power state */
668 msleep(10);
669
670 /* clear out any PhyRdy stuff from interrupt status */
671 writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT);
672
673 /* go ahead and clean out PhyRdy Change from Serror too */
674 ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
675
676 /*
677 * Clear flag to indicate that we should ignore all PhyRdy
678 * state changes
679 */
680 hpriv->flags &= ~AHCI_HFLAG_NO_HOTPLUG;
681
682 /*
683 * Enable interrupts on Phy Ready.
684 */
685 pp->intr_mask |= PORT_IRQ_PHYRDY;
686 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
687
688 /*
689 * don't change the link pm policy - we can be called
690 * just to turn of link pm temporarily
691 */
692}
693
694static int ahci_enable_alpm(struct ata_port *ap,
695 enum link_pm policy)
696{
697 struct ahci_host_priv *hpriv = ap->host->private_data;
698 void __iomem *port_mmio = ahci_port_base(ap); 649 void __iomem *port_mmio = ahci_port_base(ap);
699 u32 cmd;
700 struct ahci_port_priv *pp = ap->private_data;
701 u32 asp;
702 650
703 /* Make sure the host is capable of link power management */ 651 if (policy != ATA_LPM_MAX_POWER) {
704 if (!(hpriv->cap & HOST_CAP_ALPM))
705 return -EINVAL;
706
707 switch (policy) {
708 case MAX_PERFORMANCE:
709 case NOT_AVAILABLE:
710 /* 652 /*
711 * if we came here with NOT_AVAILABLE, 653 * Disable interrupts on Phy Ready. This keeps us from
712 * it just means this is the first time we 654 * getting woken up due to spurious phy ready
713 * have tried to enable - default to max performance, 655 * interrupts.
714 * and let the user go to lower power modes on request.
715 */ 656 */
716 ahci_disable_alpm(ap); 657 pp->intr_mask &= ~PORT_IRQ_PHYRDY;
717 return 0; 658 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
718 case MIN_POWER: 659
719 /* configure HBA to enter SLUMBER */ 660 sata_link_scr_lpm(link, policy, false);
720 asp = PORT_CMD_ASP;
721 break;
722 case MEDIUM_POWER:
723 /* configure HBA to enter PARTIAL */
724 asp = 0;
725 break;
726 default:
727 return -EINVAL;
728 } 661 }
729 662
730 /* 663 if (hpriv->cap & HOST_CAP_ALPM) {
731 * Disable interrupts on Phy Ready. This keeps us from 664 u32 cmd = readl(port_mmio + PORT_CMD);
732 * getting woken up due to spurious phy ready interrupts
733 * TBD - Hot plug should be done via polling now, is
734 * that even supported?
735 */
736 pp->intr_mask &= ~PORT_IRQ_PHYRDY;
737 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
738 665
739 /* 666 if (policy == ATA_LPM_MAX_POWER || !(hints & ATA_LPM_HIPM)) {
740 * Set a flag to indicate that we should ignore all PhyRdy 667 cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE);
741 * state changes since these can happen now whenever we 668 cmd |= PORT_CMD_ICC_ACTIVE;
742 * change link state
743 */
744 hpriv->flags |= AHCI_HFLAG_NO_HOTPLUG;
745 669
746 /* get the existing command bits */ 670 writel(cmd, port_mmio + PORT_CMD);
747 cmd = readl(port_mmio + PORT_CMD); 671 readl(port_mmio + PORT_CMD);
748 672
749 /* 673 /* wait 10ms to be sure we've come out of LPM state */
750 * Set ASP based on Policy 674 ata_msleep(ap, 10);
751 */ 675 } else {
752 cmd |= asp; 676 cmd |= PORT_CMD_ALPE;
677 if (policy == ATA_LPM_MIN_POWER)
678 cmd |= PORT_CMD_ASP;
753 679
754 /* 680 /* write out new cmd value */
755 * Setting this bit will instruct the HBA to aggressively 681 writel(cmd, port_mmio + PORT_CMD);
756 * enter a lower power link state when it's appropriate and 682 }
757 * based on the value set above for ASP 683 }
758 */
759 cmd |= PORT_CMD_ALPE;
760 684
761 /* write out new cmd value */ 685 if (policy == ATA_LPM_MAX_POWER) {
762 writel(cmd, port_mmio + PORT_CMD); 686 sata_link_scr_lpm(link, policy, false);
763 cmd = readl(port_mmio + PORT_CMD); 687
688 /* turn PHYRDY IRQ back on */
689 pp->intr_mask |= PORT_IRQ_PHYRDY;
690 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
691 }
764 692
765 /* IPM bits should be set by libata-core */
766 return 0; 693 return 0;
767} 694}
768 695
@@ -813,7 +740,7 @@ static void ahci_start_port(struct ata_port *ap)
813 emp->led_state, 740 emp->led_state,
814 4); 741 4);
815 if (rc == -EBUSY) 742 if (rc == -EBUSY)
816 msleep(1); 743 ata_msleep(ap, 1);
817 else 744 else
818 break; 745 break;
819 } 746 }
@@ -872,7 +799,7 @@ int ahci_reset_controller(struct ata_host *host)
872 * reset must complete within 1 second, or 799 * reset must complete within 1 second, or
873 * the hardware should be considered fried. 800 * the hardware should be considered fried.
874 */ 801 */
875 tmp = ata_wait_register(mmio + HOST_CTL, HOST_RESET, 802 tmp = ata_wait_register(NULL, mmio + HOST_CTL, HOST_RESET,
876 HOST_RESET, 10, 1000); 803 HOST_RESET, 10, 1000);
877 804
878 if (tmp & HOST_RESET) { 805 if (tmp & HOST_RESET) {
@@ -1252,7 +1179,7 @@ int ahci_kick_engine(struct ata_port *ap)
1252 writel(tmp, port_mmio + PORT_CMD); 1179 writel(tmp, port_mmio + PORT_CMD);
1253 1180
1254 rc = 0; 1181 rc = 0;
1255 tmp = ata_wait_register(port_mmio + PORT_CMD, 1182 tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
1256 PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); 1183 PORT_CMD_CLO, PORT_CMD_CLO, 1, 500);
1257 if (tmp & PORT_CMD_CLO) 1184 if (tmp & PORT_CMD_CLO)
1258 rc = -EIO; 1185 rc = -EIO;
@@ -1282,8 +1209,8 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
1282 writel(1, port_mmio + PORT_CMD_ISSUE); 1209 writel(1, port_mmio + PORT_CMD_ISSUE);
1283 1210
1284 if (timeout_msec) { 1211 if (timeout_msec) {
1285 tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1212 tmp = ata_wait_register(ap, port_mmio + PORT_CMD_ISSUE,
1286 1, timeout_msec); 1213 0x1, 0x1, 1, timeout_msec);
1287 if (tmp & 0x1) { 1214 if (tmp & 0x1) {
1288 ahci_kick_engine(ap); 1215 ahci_kick_engine(ap);
1289 return -EBUSY; 1216 return -EBUSY;
@@ -1330,7 +1257,7 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
1330 } 1257 }
1331 1258
1332 /* spec says at least 5us, but be generous and sleep for 1ms */ 1259 /* spec says at least 5us, but be generous and sleep for 1ms */
1333 msleep(1); 1260 ata_msleep(ap, 1);
1334 1261
1335 /* issue the second D2H Register FIS */ 1262 /* issue the second D2H Register FIS */
1336 tf.ctl &= ~ATA_SRST; 1263 tf.ctl &= ~ATA_SRST;
@@ -1660,15 +1587,10 @@ static void ahci_port_intr(struct ata_port *ap)
1660 if (unlikely(resetting)) 1587 if (unlikely(resetting))
1661 status &= ~PORT_IRQ_BAD_PMP; 1588 status &= ~PORT_IRQ_BAD_PMP;
1662 1589
1663 /* If we are getting PhyRdy, this is 1590 /* if LPM is enabled, PHYRDY doesn't mean anything */
1664 * just a power state change, we should 1591 if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) {
1665 * clear out this, plus the PhyRdy/Comm
1666 * Wake bits from Serror
1667 */
1668 if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) &&
1669 (status & PORT_IRQ_PHYRDY)) {
1670 status &= ~PORT_IRQ_PHYRDY; 1592 status &= ~PORT_IRQ_PHYRDY;
1671 ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18))); 1593 ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG);
1672 } 1594 }
1673 1595
1674 if (unlikely(status & PORT_IRQ_ERROR)) { 1596 if (unlikely(status & PORT_IRQ_ERROR)) {
@@ -1830,12 +1752,24 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
1830static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) 1752static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
1831{ 1753{
1832 struct ahci_port_priv *pp = qc->ap->private_data; 1754 struct ahci_port_priv *pp = qc->ap->private_data;
1833 u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; 1755 u8 *rx_fis = pp->rx_fis;
1834 1756
1835 if (pp->fbs_enabled) 1757 if (pp->fbs_enabled)
1836 d2h_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ; 1758 rx_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ;
1759
1760 /*
1761 * After a successful execution of an ATA PIO data-in command,
1762 * the device doesn't send D2H Reg FIS to update the TF and
1763 * the host should take TF and E_Status from the preceding PIO
1764 * Setup FIS.
1765 */
1766 if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE &&
1767 !(qc->flags & ATA_QCFLAG_FAILED)) {
1768 ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf);
1769 qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15];
1770 } else
1771 ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);
1837 1772
1838 ata_tf_from_fis(d2h_fis, &qc->result_tf);
1839 return true; 1773 return true;
1840} 1774}
1841 1775