diff options
-rw-r--r-- | drivers/ata/ahci.c | 3 | ||||
-rw-r--r-- | drivers/ata/ahci.h | 1 | ||||
-rw-r--r-- | drivers/ata/ahci_platform.c | 3 | ||||
-rw-r--r-- | drivers/ata/libahci.c | 158 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 201 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 164 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 11 | ||||
-rw-r--r-- | drivers/ata/libata.h | 4 | ||||
-rw-r--r-- | include/linux/libata.h | 17 |
9 files changed, 206 insertions, 356 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 68f7b4216501..328826381a2d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1208,9 +1208,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1208 | ata_port_pbar_desc(ap, AHCI_PCI_BAR, | 1208 | ata_port_pbar_desc(ap, AHCI_PCI_BAR, |
1209 | 0x100 + ap->port_no * 0x80, "port"); | 1209 | 0x100 + ap->port_no * 0x80, "port"); |
1210 | 1210 | ||
1211 | /* set initial link pm policy */ | ||
1212 | ap->lpm_policy = ATA_LPM_UNKNOWN; | ||
1213 | |||
1214 | /* set enclosure management message type */ | 1211 | /* set enclosure management message type */ |
1215 | if (ap->flags & ATA_FLAG_EM) | 1212 | if (ap->flags & ATA_FLAG_EM) |
1216 | ap->em_message_type = hpriv->em_msg_type; | 1213 | ap->em_message_type = hpriv->em_msg_type; |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 93867d3f8dd3..1a2aacfdebc5 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -201,7 +201,6 @@ enum { | |||
201 | AHCI_HFLAG_MV_PATA = (1 << 4), /* PATA port */ | 201 | AHCI_HFLAG_MV_PATA = (1 << 4), /* PATA port */ |
202 | AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */ | 202 | AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */ |
203 | AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ | 203 | AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ |
204 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ | ||
205 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ | 204 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ |
206 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ | 205 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ |
207 | AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ | 206 | AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ |
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 07556853c0d6..6fef1fa75c54 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
@@ -129,9 +129,6 @@ static int __init ahci_probe(struct platform_device *pdev) | |||
129 | ata_port_desc(ap, "mmio %pR", mem); | 129 | ata_port_desc(ap, "mmio %pR", mem); |
130 | ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80); | 130 | ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80); |
131 | 131 | ||
132 | /* set initial link pm policy */ | ||
133 | ap->lpm_policy = ATA_LPM_UNKNOWN; | ||
134 | |||
135 | /* set enclosure management message type */ | 132 | /* set enclosure management message type */ |
136 | if (ap->flags & ATA_FLAG_EM) | 133 | if (ap->flags & ATA_FLAG_EM) |
137 | ap->em_message_type = hpriv->em_msg_type; | 134 | ap->em_message_type = hpriv->em_msg_type; |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index ed7803f2b4f1..437f92597788 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -56,8 +56,8 @@ MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip) | |||
56 | module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); | 56 | module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); |
57 | MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); | 57 | MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); |
58 | 58 | ||
59 | static int ahci_enable_alpm(struct ata_port *ap, enum ata_lpm_policy policy); | 59 | static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, |
60 | static void ahci_disable_alpm(struct ata_port *ap); | 60 | unsigned hints); |
61 | static ssize_t ahci_led_show(struct ata_port *ap, char *buf); | 61 | static ssize_t ahci_led_show(struct ata_port *ap, char *buf); |
62 | static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, | 62 | static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, |
63 | size_t size); | 63 | size_t size); |
@@ -163,8 +163,7 @@ struct ata_port_operations ahci_ops = { | |||
163 | .pmp_attach = ahci_pmp_attach, | 163 | .pmp_attach = ahci_pmp_attach, |
164 | .pmp_detach = ahci_pmp_detach, | 164 | .pmp_detach = ahci_pmp_detach, |
165 | 165 | ||
166 | .enable_pm = ahci_enable_alpm, | 166 | .set_lpm = ahci_set_lpm, |
167 | .disable_pm = ahci_disable_alpm, | ||
168 | .em_show = ahci_led_show, | 167 | .em_show = ahci_led_show, |
169 | .em_store = ahci_led_store, | 168 | .em_store = ahci_led_store, |
170 | .sw_activity_show = ahci_activity_show, | 169 | .sw_activity_show = ahci_activity_show, |
@@ -641,126 +640,56 @@ static void ahci_power_up(struct ata_port *ap) | |||
641 | writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); | 640 | writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); |
642 | } | 641 | } |
643 | 642 | ||
644 | static void ahci_disable_alpm(struct ata_port *ap) | 643 | static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, |
644 | unsigned int hints) | ||
645 | { | 645 | { |
646 | struct ata_port *ap = link->ap; | ||
646 | struct ahci_host_priv *hpriv = ap->host->private_data; | 647 | struct ahci_host_priv *hpriv = ap->host->private_data; |
647 | void __iomem *port_mmio = ahci_port_base(ap); | ||
648 | u32 cmd; | ||
649 | struct ahci_port_priv *pp = ap->private_data; | 648 | struct ahci_port_priv *pp = ap->private_data; |
650 | |||
651 | /* LPM bits should be disabled by libata-core */ | ||
652 | /* get the existing command bits */ | ||
653 | cmd = readl(port_mmio + PORT_CMD); | ||
654 | |||
655 | /* disable ALPM and ASP */ | ||
656 | cmd &= ~PORT_CMD_ASP; | ||
657 | cmd &= ~PORT_CMD_ALPE; | ||
658 | |||
659 | /* force the interface back to active */ | ||
660 | cmd |= PORT_CMD_ICC_ACTIVE; | ||
661 | |||
662 | /* write out new cmd value */ | ||
663 | writel(cmd, port_mmio + PORT_CMD); | ||
664 | cmd = readl(port_mmio + PORT_CMD); | ||
665 | |||
666 | /* wait 10ms to be sure we've come out of any low power state */ | ||
667 | msleep(10); | ||
668 | |||
669 | /* clear out any PhyRdy stuff from interrupt status */ | ||
670 | writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT); | ||
671 | |||
672 | /* go ahead and clean out PhyRdy Change from Serror too */ | ||
673 | ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18))); | ||
674 | |||
675 | /* | ||
676 | * Clear flag to indicate that we should ignore all PhyRdy | ||
677 | * state changes | ||
678 | */ | ||
679 | hpriv->flags &= ~AHCI_HFLAG_NO_HOTPLUG; | ||
680 | |||
681 | /* | ||
682 | * Enable interrupts on Phy Ready. | ||
683 | */ | ||
684 | pp->intr_mask |= PORT_IRQ_PHYRDY; | ||
685 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
686 | |||
687 | /* | ||
688 | * don't change the link pm policy - we can be called | ||
689 | * just to turn of link pm temporarily | ||
690 | */ | ||
691 | } | ||
692 | |||
693 | static int ahci_enable_alpm(struct ata_port *ap, enum ata_lpm_policy policy) | ||
694 | { | ||
695 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
696 | void __iomem *port_mmio = ahci_port_base(ap); | 649 | void __iomem *port_mmio = ahci_port_base(ap); |
697 | u32 cmd; | ||
698 | struct ahci_port_priv *pp = ap->private_data; | ||
699 | u32 asp; | ||
700 | |||
701 | /* Make sure the host is capable of link power management */ | ||
702 | if (!(hpriv->cap & HOST_CAP_ALPM)) | ||
703 | return -EINVAL; | ||
704 | 650 | ||
705 | switch (policy) { | 651 | if (policy != ATA_LPM_MAX_POWER) { |
706 | case ATA_LPM_MAX_POWER: | ||
707 | case ATA_LPM_UNKNOWN: | ||
708 | /* | 652 | /* |
709 | * if we came here with ATA_LPM_UNKNOWN, | 653 | * Disable interrupts on Phy Ready. This keeps us from |
710 | * it just means this is the first time we | 654 | * getting woken up due to spurious phy ready |
711 | * have tried to enable - default to max performance, | 655 | * interrupts. |
712 | * and let the user go to lower power modes on request. | ||
713 | */ | 656 | */ |
714 | ahci_disable_alpm(ap); | 657 | pp->intr_mask &= ~PORT_IRQ_PHYRDY; |
715 | return 0; | 658 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); |
716 | case ATA_LPM_MIN_POWER: | 659 | |
717 | /* configure HBA to enter SLUMBER */ | 660 | sata_link_scr_lpm(link, policy, false); |
718 | asp = PORT_CMD_ASP; | ||
719 | break; | ||
720 | case ATA_LPM_MED_POWER: | ||
721 | /* configure HBA to enter PARTIAL */ | ||
722 | asp = 0; | ||
723 | break; | ||
724 | default: | ||
725 | return -EINVAL; | ||
726 | } | 661 | } |
727 | 662 | ||
728 | /* | 663 | if (hpriv->cap & HOST_CAP_ALPM) { |
729 | * Disable interrupts on Phy Ready. This keeps us from | 664 | u32 cmd = readl(port_mmio + PORT_CMD); |
730 | * getting woken up due to spurious phy ready interrupts | ||
731 | * TBD - Hot plug should be done via polling now, is | ||
732 | * that even supported? | ||
733 | */ | ||
734 | pp->intr_mask &= ~PORT_IRQ_PHYRDY; | ||
735 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
736 | 665 | ||
737 | /* | 666 | if (policy == ATA_LPM_MAX_POWER || !(hints & ATA_LPM_HIPM)) { |
738 | * Set a flag to indicate that we should ignore all PhyRdy | 667 | cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE); |
739 | * state changes since these can happen now whenever we | 668 | cmd |= PORT_CMD_ICC_ACTIVE; |
740 | * change link state | ||
741 | */ | ||
742 | hpriv->flags |= AHCI_HFLAG_NO_HOTPLUG; | ||
743 | 669 | ||
744 | /* get the existing command bits */ | 670 | writel(cmd, port_mmio + PORT_CMD); |
745 | cmd = readl(port_mmio + PORT_CMD); | 671 | readl(port_mmio + PORT_CMD); |
746 | 672 | ||
747 | /* | 673 | /* wait 10ms to be sure we've come out of LPM state */ |
748 | * Set ASP based on Policy | 674 | msleep(10); |
749 | */ | 675 | } else { |
750 | cmd |= asp; | 676 | cmd |= PORT_CMD_ALPE; |
677 | if (policy == ATA_LPM_MIN_POWER) | ||
678 | cmd |= PORT_CMD_ASP; | ||
751 | 679 | ||
752 | /* | 680 | /* write out new cmd value */ |
753 | * Setting this bit will instruct the HBA to aggressively | 681 | writel(cmd, port_mmio + PORT_CMD); |
754 | * enter a lower power link state when it's appropriate and | 682 | } |
755 | * based on the value set above for ASP | 683 | } |
756 | */ | ||
757 | cmd |= PORT_CMD_ALPE; | ||
758 | 684 | ||
759 | /* write out new cmd value */ | 685 | if (policy == ATA_LPM_MAX_POWER) { |
760 | writel(cmd, port_mmio + PORT_CMD); | 686 | sata_link_scr_lpm(link, policy, false); |
761 | 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 | } | ||
762 | 692 | ||
763 | /* LPM bits should be set by libata-core */ | ||
764 | return 0; | 693 | return 0; |
765 | } | 694 | } |
766 | 695 | ||
@@ -1658,15 +1587,10 @@ static void ahci_port_intr(struct ata_port *ap) | |||
1658 | if (unlikely(resetting)) | 1587 | if (unlikely(resetting)) |
1659 | status &= ~PORT_IRQ_BAD_PMP; | 1588 | status &= ~PORT_IRQ_BAD_PMP; |
1660 | 1589 | ||
1661 | /* If we are getting PhyRdy, this is | 1590 | /* if LPM is enabled, PHYRDY doesn't mean anything */ |
1662 | * just a power state change, we should | 1591 | if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) { |
1663 | * clear out this, plus the PhyRdy/Comm | ||
1664 | * Wake bits from Serror | ||
1665 | */ | ||
1666 | if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) && | ||
1667 | (status & PORT_IRQ_PHYRDY)) { | ||
1668 | status &= ~PORT_IRQ_PHYRDY; | 1592 | status &= ~PORT_IRQ_PHYRDY; |
1669 | ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18))); | 1593 | ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG); |
1670 | } | 1594 | } |
1671 | 1595 | ||
1672 | if (unlikely(status & PORT_IRQ_ERROR)) { | 1596 | if (unlikely(status & PORT_IRQ_ERROR)) { |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b8024451234c..7c5538b9fa3b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1028,182 +1028,6 @@ const char *sata_spd_string(unsigned int spd) | |||
1028 | return spd_str[spd - 1]; | 1028 | return spd_str[spd - 1]; |
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | static int ata_dev_set_dipm(struct ata_device *dev, enum ata_lpm_policy policy) | ||
1032 | { | ||
1033 | struct ata_link *link = dev->link; | ||
1034 | struct ata_port *ap = link->ap; | ||
1035 | u32 scontrol; | ||
1036 | unsigned int err_mask; | ||
1037 | int rc; | ||
1038 | |||
1039 | /* | ||
1040 | * disallow DIPM for drivers which haven't set | ||
1041 | * ATA_FLAG_LPM. This is because when DIPM is enabled, | ||
1042 | * phy ready will be set in the interrupt status on | ||
1043 | * state changes, which will cause some drivers to | ||
1044 | * think there are errors - additionally drivers will | ||
1045 | * need to disable hot plug. | ||
1046 | */ | ||
1047 | if (!(ap->flags & ATA_FLAG_LPM) || !ata_dev_enabled(dev)) { | ||
1048 | ap->lpm_policy = ATA_LPM_UNKNOWN; | ||
1049 | return -EINVAL; | ||
1050 | } | ||
1051 | |||
1052 | /* | ||
1053 | * For DIPM, we will only enable it for the | ||
1054 | * min_power setting. | ||
1055 | * | ||
1056 | * Why? Because Disks are too stupid to know that | ||
1057 | * If the host rejects a request to go to SLUMBER | ||
1058 | * they should retry at PARTIAL, and instead it | ||
1059 | * just would give up. So, for medium_power to | ||
1060 | * work at all, we need to only allow HIPM. | ||
1061 | */ | ||
1062 | rc = sata_scr_read(link, SCR_CONTROL, &scontrol); | ||
1063 | if (rc) | ||
1064 | return rc; | ||
1065 | |||
1066 | switch (policy) { | ||
1067 | case ATA_LPM_MIN_POWER: | ||
1068 | /* no restrictions on LPM transitions */ | ||
1069 | scontrol &= ~(0x3 << 8); | ||
1070 | rc = sata_scr_write(link, SCR_CONTROL, scontrol); | ||
1071 | if (rc) | ||
1072 | return rc; | ||
1073 | |||
1074 | /* enable DIPM */ | ||
1075 | if (dev->flags & ATA_DFLAG_DIPM) | ||
1076 | err_mask = ata_dev_set_feature(dev, | ||
1077 | SETFEATURES_SATA_ENABLE, SATA_DIPM); | ||
1078 | break; | ||
1079 | case ATA_LPM_MED_POWER: | ||
1080 | /* allow LPM to PARTIAL */ | ||
1081 | scontrol &= ~(0x1 << 8); | ||
1082 | scontrol |= (0x2 << 8); | ||
1083 | rc = sata_scr_write(link, SCR_CONTROL, scontrol); | ||
1084 | if (rc) | ||
1085 | return rc; | ||
1086 | |||
1087 | /* | ||
1088 | * we don't have to disable DIPM since LPM flags | ||
1089 | * disallow transitions to SLUMBER, which effectively | ||
1090 | * disable DIPM if it does not support PARTIAL | ||
1091 | */ | ||
1092 | break; | ||
1093 | case ATA_LPM_UNKNOWN: | ||
1094 | case ATA_LPM_MAX_POWER: | ||
1095 | /* disable all LPM transitions */ | ||
1096 | scontrol |= (0x3 << 8); | ||
1097 | rc = sata_scr_write(link, SCR_CONTROL, scontrol); | ||
1098 | if (rc) | ||
1099 | return rc; | ||
1100 | |||
1101 | /* | ||
1102 | * we don't have to disable DIPM since LPM flags | ||
1103 | * disallow all transitions which effectively | ||
1104 | * disable DIPM anyway. | ||
1105 | */ | ||
1106 | break; | ||
1107 | } | ||
1108 | |||
1109 | /* FIXME: handle SET FEATURES failure */ | ||
1110 | (void) err_mask; | ||
1111 | |||
1112 | return 0; | ||
1113 | } | ||
1114 | |||
1115 | /** | ||
1116 | * ata_dev_enable_pm - enable SATA interface power management | ||
1117 | * @dev: device to enable power management | ||
1118 | * @policy: the link power management policy | ||
1119 | * | ||
1120 | * Enable SATA Interface power management. This will enable | ||
1121 | * Device Interface Power Management (DIPM) for min_power | ||
1122 | * policy, and then call driver specific callbacks for | ||
1123 | * enabling Host Initiated Power management. | ||
1124 | * | ||
1125 | * Locking: Caller. | ||
1126 | * Returns: -EINVAL if LPM is not supported, 0 otherwise. | ||
1127 | */ | ||
1128 | void ata_dev_enable_pm(struct ata_device *dev, enum ata_lpm_policy policy) | ||
1129 | { | ||
1130 | int rc = 0; | ||
1131 | struct ata_port *ap = dev->link->ap; | ||
1132 | |||
1133 | /* set HIPM first, then DIPM */ | ||
1134 | if (ap->ops->enable_pm) | ||
1135 | rc = ap->ops->enable_pm(ap, policy); | ||
1136 | if (rc) | ||
1137 | goto enable_pm_out; | ||
1138 | rc = ata_dev_set_dipm(dev, policy); | ||
1139 | |||
1140 | enable_pm_out: | ||
1141 | if (rc) | ||
1142 | ap->lpm_policy = ATA_LPM_MAX_POWER; | ||
1143 | else | ||
1144 | ap->lpm_policy = policy; | ||
1145 | return /* rc */; /* hopefully we can use 'rc' eventually */ | ||
1146 | } | ||
1147 | |||
1148 | #ifdef CONFIG_PM | ||
1149 | /** | ||
1150 | * ata_dev_disable_pm - disable SATA interface power management | ||
1151 | * @dev: device to disable power management | ||
1152 | * | ||
1153 | * Disable SATA Interface power management. This will disable | ||
1154 | * Device Interface Power Management (DIPM) without changing | ||
1155 | * policy, call driver specific callbacks for disabling Host | ||
1156 | * Initiated Power management. | ||
1157 | * | ||
1158 | * Locking: Caller. | ||
1159 | * Returns: void | ||
1160 | */ | ||
1161 | static void ata_dev_disable_pm(struct ata_device *dev) | ||
1162 | { | ||
1163 | struct ata_port *ap = dev->link->ap; | ||
1164 | |||
1165 | ata_dev_set_dipm(dev, ATA_LPM_MAX_POWER); | ||
1166 | if (ap->ops->disable_pm) | ||
1167 | ap->ops->disable_pm(ap); | ||
1168 | } | ||
1169 | #endif /* CONFIG_PM */ | ||
1170 | |||
1171 | void ata_lpm_schedule(struct ata_port *ap, enum ata_lpm_policy policy) | ||
1172 | { | ||
1173 | ap->lpm_policy = policy; | ||
1174 | ap->link.eh_info.action |= ATA_EH_LPM; | ||
1175 | ap->link.eh_info.flags |= ATA_EHI_NO_AUTOPSY; | ||
1176 | ata_port_schedule_eh(ap); | ||
1177 | } | ||
1178 | |||
1179 | #ifdef CONFIG_PM | ||
1180 | static void ata_lpm_enable(struct ata_host *host) | ||
1181 | { | ||
1182 | struct ata_link *link; | ||
1183 | struct ata_port *ap; | ||
1184 | struct ata_device *dev; | ||
1185 | int i; | ||
1186 | |||
1187 | for (i = 0; i < host->n_ports; i++) { | ||
1188 | ap = host->ports[i]; | ||
1189 | ata_for_each_link(link, ap, EDGE) { | ||
1190 | ata_for_each_dev(dev, link, ALL) | ||
1191 | ata_dev_disable_pm(dev); | ||
1192 | } | ||
1193 | } | ||
1194 | } | ||
1195 | |||
1196 | static void ata_lpm_disable(struct ata_host *host) | ||
1197 | { | ||
1198 | int i; | ||
1199 | |||
1200 | for (i = 0; i < host->n_ports; i++) { | ||
1201 | struct ata_port *ap = host->ports[i]; | ||
1202 | ata_lpm_schedule(ap, ap->lpm_policy); | ||
1203 | } | ||
1204 | } | ||
1205 | #endif /* CONFIG_PM */ | ||
1206 | |||
1207 | /** | 1031 | /** |
1208 | * ata_dev_classify - determine device type based on ATA-spec signature | 1032 | * ata_dev_classify - determine device type based on ATA-spec signature |
1209 | * @tf: ATA taskfile register set for device to be identified | 1033 | * @tf: ATA taskfile register set for device to be identified |
@@ -2562,13 +2386,6 @@ int ata_dev_configure(struct ata_device *dev) | |||
2562 | if (dev->flags & ATA_DFLAG_LBA48) | 2386 | if (dev->flags & ATA_DFLAG_LBA48) |
2563 | dev->max_sectors = ATA_MAX_SECTORS_LBA48; | 2387 | dev->max_sectors = ATA_MAX_SECTORS_LBA48; |
2564 | 2388 | ||
2565 | if (!(dev->horkage & ATA_HORKAGE_LPM)) { | ||
2566 | if (ata_id_has_hipm(dev->id)) | ||
2567 | dev->flags |= ATA_DFLAG_HIPM; | ||
2568 | if (ata_id_has_dipm(dev->id)) | ||
2569 | dev->flags |= ATA_DFLAG_DIPM; | ||
2570 | } | ||
2571 | |||
2572 | /* Limit PATA drive on SATA cable bridge transfers to udma5, | 2389 | /* Limit PATA drive on SATA cable bridge transfers to udma5, |
2573 | 200 sectors */ | 2390 | 200 sectors */ |
2574 | if (ata_dev_knobble(dev)) { | 2391 | if (ata_dev_knobble(dev)) { |
@@ -2589,13 +2406,6 @@ int ata_dev_configure(struct ata_device *dev) | |||
2589 | dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, | 2406 | dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, |
2590 | dev->max_sectors); | 2407 | dev->max_sectors); |
2591 | 2408 | ||
2592 | if (ata_dev_blacklisted(dev) & ATA_HORKAGE_LPM) { | ||
2593 | dev->horkage |= ATA_HORKAGE_LPM; | ||
2594 | |||
2595 | /* reset link pm_policy for this port to no pm */ | ||
2596 | ap->lpm_policy = ATA_LPM_MAX_POWER; | ||
2597 | } | ||
2598 | |||
2599 | if (ap->ops->dev_config) | 2409 | if (ap->ops->dev_config) |
2600 | ap->ops->dev_config(dev); | 2410 | ap->ops->dev_config(dev); |
2601 | 2411 | ||
@@ -5495,12 +5305,6 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) | |||
5495 | int rc; | 5305 | int rc; |
5496 | 5306 | ||
5497 | /* | 5307 | /* |
5498 | * disable link pm on all ports before requesting | ||
5499 | * any pm activity | ||
5500 | */ | ||
5501 | ata_lpm_enable(host); | ||
5502 | |||
5503 | /* | ||
5504 | * On some hardware, device fails to respond after spun down | 5308 | * On some hardware, device fails to respond after spun down |
5505 | * for suspend. As the device won't be used before being | 5309 | * for suspend. As the device won't be used before being |
5506 | * resumed, we don't need to touch the device. Ask EH to skip | 5310 | * resumed, we don't need to touch the device. Ask EH to skip |
@@ -5533,9 +5337,6 @@ void ata_host_resume(struct ata_host *host) | |||
5533 | ata_host_request_pm(host, PMSG_ON, ATA_EH_RESET, | 5337 | ata_host_request_pm(host, PMSG_ON, ATA_EH_RESET, |
5534 | ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0); | 5338 | ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0); |
5535 | host->dev->power.power_state = PMSG_ON; | 5339 | host->dev->power.power_state = PMSG_ON; |
5536 | |||
5537 | /* reenable link pm */ | ||
5538 | ata_lpm_disable(host); | ||
5539 | } | 5340 | } |
5540 | #endif | 5341 | #endif |
5541 | 5342 | ||
@@ -6096,7 +5897,7 @@ static void async_port_probe(void *data, async_cookie_t cookie) | |||
6096 | spin_lock_irqsave(ap->lock, flags); | 5897 | spin_lock_irqsave(ap->lock, flags); |
6097 | 5898 | ||
6098 | ehi->probe_mask |= ATA_ALL_DEVICES; | 5899 | ehi->probe_mask |= ATA_ALL_DEVICES; |
6099 | ehi->action |= ATA_EH_RESET | ATA_EH_LPM; | 5900 | ehi->action |= ATA_EH_RESET; |
6100 | ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; | 5901 | ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; |
6101 | 5902 | ||
6102 | ap->pflags &= ~ATA_PFLAG_INITIALIZING; | 5903 | ap->pflags &= ~ATA_PFLAG_INITIALIZING; |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 96aa75ddf87f..a645cd3ab163 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -1580,9 +1580,9 @@ static void ata_eh_analyze_serror(struct ata_link *link) | |||
1580 | * host links. For disabled PMP links, only N bit is | 1580 | * host links. For disabled PMP links, only N bit is |
1581 | * considered as X bit is left at 1 for link plugging. | 1581 | * considered as X bit is left at 1 for link plugging. |
1582 | */ | 1582 | */ |
1583 | hotplug_mask = 0; | 1583 | if (link->lpm_policy != ATA_LPM_MAX_POWER) |
1584 | 1584 | hotplug_mask = 0; /* hotplug doesn't work w/ LPM */ | |
1585 | if (!(link->flags & ATA_LFLAG_DISABLED) || ata_is_host_link(link)) | 1585 | else if (!(link->flags & ATA_LFLAG_DISABLED) || ata_is_host_link(link)) |
1586 | hotplug_mask = SERR_PHYRDY_CHG | SERR_DEV_XCHG; | 1586 | hotplug_mask = SERR_PHYRDY_CHG | SERR_DEV_XCHG; |
1587 | else | 1587 | else |
1588 | hotplug_mask = SERR_PHYRDY_CHG; | 1588 | hotplug_mask = SERR_PHYRDY_CHG; |
@@ -2784,8 +2784,9 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2784 | ata_eh_done(link, NULL, ATA_EH_RESET); | 2784 | ata_eh_done(link, NULL, ATA_EH_RESET); |
2785 | if (slave) | 2785 | if (slave) |
2786 | ata_eh_done(slave, NULL, ATA_EH_RESET); | 2786 | ata_eh_done(slave, NULL, ATA_EH_RESET); |
2787 | ehc->last_reset = jiffies; /* update to completion time */ | 2787 | ehc->last_reset = jiffies; /* update to completion time */ |
2788 | ehc->i.action |= ATA_EH_REVALIDATE; | 2788 | ehc->i.action |= ATA_EH_REVALIDATE; |
2789 | link->lpm_policy = ATA_LPM_UNKNOWN; /* reset LPM state */ | ||
2789 | 2790 | ||
2790 | rc = 0; | 2791 | rc = 0; |
2791 | out: | 2792 | out: |
@@ -3211,6 +3212,121 @@ static int ata_eh_maybe_retry_flush(struct ata_device *dev) | |||
3211 | return rc; | 3212 | return rc; |
3212 | } | 3213 | } |
3213 | 3214 | ||
3215 | /** | ||
3216 | * ata_eh_set_lpm - configure SATA interface power management | ||
3217 | * @link: link to configure power management | ||
3218 | * @policy: the link power management policy | ||
3219 | * @r_failed_dev: out parameter for failed device | ||
3220 | * | ||
3221 | * Enable SATA Interface power management. This will enable | ||
3222 | * Device Interface Power Management (DIPM) for min_power | ||
3223 | * policy, and then call driver specific callbacks for | ||
3224 | * enabling Host Initiated Power management. | ||
3225 | * | ||
3226 | * LOCKING: | ||
3227 | * EH context. | ||
3228 | * | ||
3229 | * RETURNS: | ||
3230 | * 0 on success, -errno on failure. | ||
3231 | */ | ||
3232 | static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, | ||
3233 | struct ata_device **r_failed_dev) | ||
3234 | { | ||
3235 | struct ata_port *ap = link->ap; | ||
3236 | struct ata_eh_context *ehc = &link->eh_context; | ||
3237 | struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; | ||
3238 | unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; | ||
3239 | unsigned int err_mask; | ||
3240 | int rc; | ||
3241 | |||
3242 | /* if the link or host doesn't do LPM, noop */ | ||
3243 | if ((link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) | ||
3244 | return 0; | ||
3245 | |||
3246 | /* | ||
3247 | * DIPM is enabled only for MIN_POWER as some devices | ||
3248 | * misbehave when the host NACKs transition to SLUMBER. Order | ||
3249 | * device and link configurations such that the host always | ||
3250 | * allows DIPM requests. | ||
3251 | */ | ||
3252 | ata_for_each_dev(dev, link, ENABLED) { | ||
3253 | bool hipm = ata_id_has_hipm(dev->id); | ||
3254 | bool dipm = ata_id_has_dipm(dev->id); | ||
3255 | |||
3256 | /* find the first enabled and LPM enabled devices */ | ||
3257 | if (!link_dev) | ||
3258 | link_dev = dev; | ||
3259 | |||
3260 | if (!lpm_dev && (hipm || dipm)) | ||
3261 | lpm_dev = dev; | ||
3262 | |||
3263 | hints &= ~ATA_LPM_EMPTY; | ||
3264 | if (!hipm) | ||
3265 | hints &= ~ATA_LPM_HIPM; | ||
3266 | |||
3267 | /* disable DIPM before changing link config */ | ||
3268 | if (policy != ATA_LPM_MIN_POWER && dipm) { | ||
3269 | err_mask = ata_dev_set_feature(dev, | ||
3270 | SETFEATURES_SATA_DISABLE, SATA_DIPM); | ||
3271 | if (err_mask && err_mask != AC_ERR_DEV) { | ||
3272 | ata_dev_printk(dev, KERN_WARNING, | ||
3273 | "failed to disable DIPM, Emask 0x%x\n", | ||
3274 | err_mask); | ||
3275 | rc = -EIO; | ||
3276 | goto fail; | ||
3277 | } | ||
3278 | } | ||
3279 | } | ||
3280 | |||
3281 | rc = ap->ops->set_lpm(link, policy, hints); | ||
3282 | if (!rc && ap->slave_link) | ||
3283 | rc = ap->ops->set_lpm(ap->slave_link, policy, hints); | ||
3284 | |||
3285 | /* | ||
3286 | * Attribute link config failure to the first (LPM) enabled | ||
3287 | * device on the link. | ||
3288 | */ | ||
3289 | if (rc) { | ||
3290 | if (rc == -EOPNOTSUPP) { | ||
3291 | link->flags |= ATA_LFLAG_NO_LPM; | ||
3292 | return 0; | ||
3293 | } | ||
3294 | dev = lpm_dev ? lpm_dev : link_dev; | ||
3295 | goto fail; | ||
3296 | } | ||
3297 | |||
3298 | /* host config updated, enable DIPM if transitioning to MIN_POWER */ | ||
3299 | ata_for_each_dev(dev, link, ENABLED) { | ||
3300 | if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) { | ||
3301 | err_mask = ata_dev_set_feature(dev, | ||
3302 | SETFEATURES_SATA_ENABLE, SATA_DIPM); | ||
3303 | if (err_mask && err_mask != AC_ERR_DEV) { | ||
3304 | ata_dev_printk(dev, KERN_WARNING, | ||
3305 | "failed to enable DIPM, Emask 0x%x\n", | ||
3306 | err_mask); | ||
3307 | rc = -EIO; | ||
3308 | goto fail; | ||
3309 | } | ||
3310 | } | ||
3311 | } | ||
3312 | |||
3313 | link->lpm_policy = policy; | ||
3314 | if (ap && ap->slave_link) | ||
3315 | ap->slave_link->lpm_policy = policy; | ||
3316 | return 0; | ||
3317 | |||
3318 | fail: | ||
3319 | /* if no device or only one more chance is left, disable LPM */ | ||
3320 | if (!dev || ehc->tries[dev->devno] <= 2) { | ||
3321 | ata_link_printk(link, KERN_WARNING, | ||
3322 | "disabling LPM on the link\n"); | ||
3323 | link->flags |= ATA_LFLAG_NO_LPM; | ||
3324 | } | ||
3325 | if (r_failed_dev) | ||
3326 | *r_failed_dev = dev; | ||
3327 | return rc; | ||
3328 | } | ||
3329 | |||
3214 | static int ata_link_nr_enabled(struct ata_link *link) | 3330 | static int ata_link_nr_enabled(struct ata_link *link) |
3215 | { | 3331 | { |
3216 | struct ata_device *dev; | 3332 | struct ata_device *dev; |
@@ -3295,6 +3411,10 @@ static int ata_eh_schedule_probe(struct ata_device *dev) | |||
3295 | ehc->saved_xfer_mode[dev->devno] = 0; | 3411 | ehc->saved_xfer_mode[dev->devno] = 0; |
3296 | ehc->saved_ncq_enabled &= ~(1 << dev->devno); | 3412 | ehc->saved_ncq_enabled &= ~(1 << dev->devno); |
3297 | 3413 | ||
3414 | /* the link maybe in a deep sleep, wake it up */ | ||
3415 | if (link->lpm_policy > ATA_LPM_MAX_POWER) | ||
3416 | link->ap->ops->set_lpm(link, ATA_LPM_MAX_POWER, ATA_LPM_EMPTY); | ||
3417 | |||
3298 | /* Record and count probe trials on the ering. The specific | 3418 | /* Record and count probe trials on the ering. The specific |
3299 | * error mask used is irrelevant. Because a successful device | 3419 | * error mask used is irrelevant. Because a successful device |
3300 | * detection clears the ering, this count accumulates only if | 3420 | * detection clears the ering, this count accumulates only if |
@@ -3396,8 +3516,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
3396 | { | 3516 | { |
3397 | struct ata_link *link; | 3517 | struct ata_link *link; |
3398 | struct ata_device *dev; | 3518 | struct ata_device *dev; |
3399 | int nr_failed_devs; | 3519 | int rc, nr_fails; |
3400 | int rc; | ||
3401 | unsigned long flags, deadline; | 3520 | unsigned long flags, deadline; |
3402 | 3521 | ||
3403 | DPRINTK("ENTER\n"); | 3522 | DPRINTK("ENTER\n"); |
@@ -3438,7 +3557,6 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
3438 | 3557 | ||
3439 | retry: | 3558 | retry: |
3440 | rc = 0; | 3559 | rc = 0; |
3441 | nr_failed_devs = 0; | ||
3442 | 3560 | ||
3443 | /* if UNLOADING, finish immediately */ | 3561 | /* if UNLOADING, finish immediately */ |
3444 | if (ap->pflags & ATA_PFLAG_UNLOADING) | 3562 | if (ap->pflags & ATA_PFLAG_UNLOADING) |
@@ -3523,13 +3641,17 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
3523 | } | 3641 | } |
3524 | 3642 | ||
3525 | /* the rest */ | 3643 | /* the rest */ |
3526 | ata_for_each_link(link, ap, EDGE) { | 3644 | nr_fails = 0; |
3645 | ata_for_each_link(link, ap, PMP_FIRST) { | ||
3527 | struct ata_eh_context *ehc = &link->eh_context; | 3646 | struct ata_eh_context *ehc = &link->eh_context; |
3528 | 3647 | ||
3648 | if (sata_pmp_attached(ap) && ata_is_host_link(link)) | ||
3649 | goto config_lpm; | ||
3650 | |||
3529 | /* revalidate existing devices and attach new ones */ | 3651 | /* revalidate existing devices and attach new ones */ |
3530 | rc = ata_eh_revalidate_and_attach(link, &dev); | 3652 | rc = ata_eh_revalidate_and_attach(link, &dev); |
3531 | if (rc) | 3653 | if (rc) |
3532 | goto dev_fail; | 3654 | goto rest_fail; |
3533 | 3655 | ||
3534 | /* if PMP got attached, return, pmp EH will take care of it */ | 3656 | /* if PMP got attached, return, pmp EH will take care of it */ |
3535 | if (link->device->class == ATA_DEV_PMP) { | 3657 | if (link->device->class == ATA_DEV_PMP) { |
@@ -3541,7 +3663,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
3541 | if (ehc->i.flags & ATA_EHI_SETMODE) { | 3663 | if (ehc->i.flags & ATA_EHI_SETMODE) { |
3542 | rc = ata_set_mode(link, &dev); | 3664 | rc = ata_set_mode(link, &dev); |
3543 | if (rc) | 3665 | if (rc) |
3544 | goto dev_fail; | 3666 | goto rest_fail; |
3545 | ehc->i.flags &= ~ATA_EHI_SETMODE; | 3667 | ehc->i.flags &= ~ATA_EHI_SETMODE; |
3546 | } | 3668 | } |
3547 | 3669 | ||
@@ -3554,7 +3676,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
3554 | continue; | 3676 | continue; |
3555 | rc = atapi_eh_clear_ua(dev); | 3677 | rc = atapi_eh_clear_ua(dev); |
3556 | if (rc) | 3678 | if (rc) |
3557 | goto dev_fail; | 3679 | goto rest_fail; |
3558 | } | 3680 | } |
3559 | } | 3681 | } |
3560 | 3682 | ||
@@ -3564,21 +3686,25 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
3564 | continue; | 3686 | continue; |
3565 | rc = ata_eh_maybe_retry_flush(dev); | 3687 | rc = ata_eh_maybe_retry_flush(dev); |
3566 | if (rc) | 3688 | if (rc) |
3567 | goto dev_fail; | 3689 | goto rest_fail; |
3568 | } | 3690 | } |
3569 | 3691 | ||
3692 | config_lpm: | ||
3570 | /* configure link power saving */ | 3693 | /* configure link power saving */ |
3571 | if (ehc->i.action & ATA_EH_LPM) | 3694 | if (link->lpm_policy != ap->target_lpm_policy) { |
3572 | ata_for_each_dev(dev, link, ALL) | 3695 | rc = ata_eh_set_lpm(link, ap->target_lpm_policy, &dev); |
3573 | ata_dev_enable_pm(dev, ap->lpm_policy); | 3696 | if (rc) |
3697 | goto rest_fail; | ||
3698 | } | ||
3574 | 3699 | ||
3575 | /* this link is okay now */ | 3700 | /* this link is okay now */ |
3576 | ehc->i.flags = 0; | 3701 | ehc->i.flags = 0; |
3577 | continue; | 3702 | continue; |
3578 | 3703 | ||
3579 | dev_fail: | 3704 | rest_fail: |
3580 | nr_failed_devs++; | 3705 | nr_fails++; |
3581 | ata_eh_handle_dev_fail(dev, rc); | 3706 | if (dev) |
3707 | ata_eh_handle_dev_fail(dev, rc); | ||
3582 | 3708 | ||
3583 | if (ap->pflags & ATA_PFLAG_FROZEN) { | 3709 | if (ap->pflags & ATA_PFLAG_FROZEN) { |
3584 | /* PMP reset requires working host port. | 3710 | /* PMP reset requires working host port. |
@@ -3590,7 +3716,7 @@ dev_fail: | |||
3590 | } | 3716 | } |
3591 | } | 3717 | } |
3592 | 3718 | ||
3593 | if (nr_failed_devs) | 3719 | if (nr_fails) |
3594 | goto retry; | 3720 | goto retry; |
3595 | 3721 | ||
3596 | out: | 3722 | out: |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index aa56681f68db..56f6224fd6e6 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -117,6 +117,7 @@ static ssize_t ata_scsi_lpm_store(struct device *dev, | |||
117 | struct Scsi_Host *shost = class_to_shost(dev); | 117 | struct Scsi_Host *shost = class_to_shost(dev); |
118 | struct ata_port *ap = ata_shost_to_port(shost); | 118 | struct ata_port *ap = ata_shost_to_port(shost); |
119 | enum ata_lpm_policy policy; | 119 | enum ata_lpm_policy policy; |
120 | unsigned long flags; | ||
120 | 121 | ||
121 | /* UNKNOWN is internal state, iterate from MAX_POWER */ | 122 | /* UNKNOWN is internal state, iterate from MAX_POWER */ |
122 | for (policy = ATA_LPM_MAX_POWER; | 123 | for (policy = ATA_LPM_MAX_POWER; |
@@ -129,7 +130,11 @@ static ssize_t ata_scsi_lpm_store(struct device *dev, | |||
129 | if (policy == ARRAY_SIZE(ata_lpm_policy_names)) | 130 | if (policy == ARRAY_SIZE(ata_lpm_policy_names)) |
130 | return -EINVAL; | 131 | return -EINVAL; |
131 | 132 | ||
132 | ata_lpm_schedule(ap, policy); | 133 | spin_lock_irqsave(ap->lock, flags); |
134 | ap->target_lpm_policy = policy; | ||
135 | ata_port_schedule_eh(ap); | ||
136 | spin_unlock_irqrestore(ap->lock, flags); | ||
137 | |||
133 | return count; | 138 | return count; |
134 | } | 139 | } |
135 | 140 | ||
@@ -139,11 +144,11 @@ static ssize_t ata_scsi_lpm_show(struct device *dev, | |||
139 | struct Scsi_Host *shost = class_to_shost(dev); | 144 | struct Scsi_Host *shost = class_to_shost(dev); |
140 | struct ata_port *ap = ata_shost_to_port(shost); | 145 | struct ata_port *ap = ata_shost_to_port(shost); |
141 | 146 | ||
142 | if (ap->lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) | 147 | if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) |
143 | return -EINVAL; | 148 | return -EINVAL; |
144 | 149 | ||
145 | return snprintf(buf, PAGE_SIZE, "%s\n", | 150 | return snprintf(buf, PAGE_SIZE, "%s\n", |
146 | ata_lpm_policy_names[ap->lpm_policy]); | 151 | ata_lpm_policy_names[ap->target_lpm_policy]); |
147 | } | 152 | } |
148 | DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, | 153 | DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, |
149 | ata_scsi_lpm_show, ata_scsi_lpm_store); | 154 | ata_scsi_lpm_show, ata_scsi_lpm_store); |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 65b6a73c3ac7..55a6f413a550 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -102,10 +102,6 @@ extern int sata_link_init_spd(struct ata_link *link); | |||
102 | extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); | 102 | extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); |
103 | extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); | 103 | extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); |
104 | extern struct ata_port *ata_port_alloc(struct ata_host *host); | 104 | extern struct ata_port *ata_port_alloc(struct ata_host *host); |
105 | extern void ata_dev_enable_pm(struct ata_device *dev, | ||
106 | enum ata_lpm_policy policy); | ||
107 | extern void ata_lpm_schedule(struct ata_port *ap, | ||
108 | enum ata_lpm_policy policy); | ||
109 | extern const char *sata_spd_string(unsigned int spd); | 105 | extern const char *sata_spd_string(unsigned int spd); |
110 | 106 | ||
111 | /* libata-acpi.c */ | 107 | /* libata-acpi.c */ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 7770eeb21039..bc4ee218b185 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -172,6 +172,7 @@ enum { | |||
172 | ATA_LFLAG_NO_RETRY = (1 << 5), /* don't retry this link */ | 172 | ATA_LFLAG_NO_RETRY = (1 << 5), /* don't retry this link */ |
173 | ATA_LFLAG_DISABLED = (1 << 6), /* link is disabled */ | 173 | ATA_LFLAG_DISABLED = (1 << 6), /* link is disabled */ |
174 | ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */ | 174 | ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */ |
175 | ATA_LFLAG_NO_LPM = (1 << 8), /* disable LPM on this link */ | ||
175 | 176 | ||
176 | /* struct ata_port flags */ | 177 | /* struct ata_port flags */ |
177 | ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ | 178 | ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ |
@@ -324,12 +325,11 @@ enum { | |||
324 | ATA_EH_HARDRESET = (1 << 2), /* meaningful only in ->prereset */ | 325 | ATA_EH_HARDRESET = (1 << 2), /* meaningful only in ->prereset */ |
325 | ATA_EH_RESET = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, | 326 | ATA_EH_RESET = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, |
326 | ATA_EH_ENABLE_LINK = (1 << 3), | 327 | ATA_EH_ENABLE_LINK = (1 << 3), |
327 | ATA_EH_LPM = (1 << 4), /* link power management action */ | ||
328 | ATA_EH_PARK = (1 << 5), /* unload heads and stop I/O */ | 328 | ATA_EH_PARK = (1 << 5), /* unload heads and stop I/O */ |
329 | 329 | ||
330 | ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK, | 330 | ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK, |
331 | ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET | | 331 | ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET | |
332 | ATA_EH_ENABLE_LINK | ATA_EH_LPM, | 332 | ATA_EH_ENABLE_LINK, |
333 | 333 | ||
334 | /* ata_eh_info->flags */ | 334 | /* ata_eh_info->flags */ |
335 | ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ | 335 | ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ |
@@ -377,7 +377,6 @@ enum { | |||
377 | ATA_HORKAGE_BROKEN_HPA = (1 << 4), /* Broken HPA */ | 377 | ATA_HORKAGE_BROKEN_HPA = (1 << 4), /* Broken HPA */ |
378 | ATA_HORKAGE_DISABLE = (1 << 5), /* Disable it */ | 378 | ATA_HORKAGE_DISABLE = (1 << 5), /* Disable it */ |
379 | ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ | 379 | ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ |
380 | ATA_HORKAGE_LPM = (1 << 7), /* Link PM problems */ | ||
381 | ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ | 380 | ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ |
382 | ATA_HORKAGE_STUCK_ERR = (1 << 9), /* stuck ERR on next PACKET */ | 381 | ATA_HORKAGE_STUCK_ERR = (1 << 9), /* stuck ERR on next PACKET */ |
383 | ATA_HORKAGE_BRIDGE_OK = (1 << 10), /* no bridge limits */ | 382 | ATA_HORKAGE_BRIDGE_OK = (1 << 10), /* no bridge limits */ |
@@ -475,6 +474,11 @@ enum ata_lpm_policy { | |||
475 | ATA_LPM_MIN_POWER, | 474 | ATA_LPM_MIN_POWER, |
476 | }; | 475 | }; |
477 | 476 | ||
477 | enum ata_lpm_hints { | ||
478 | ATA_LPM_EMPTY = (1 << 0), /* port empty/probing */ | ||
479 | ATA_LPM_HIPM = (1 << 1), /* may use HIPM */ | ||
480 | }; | ||
481 | |||
478 | /* forward declarations */ | 482 | /* forward declarations */ |
479 | struct scsi_device; | 483 | struct scsi_device; |
480 | struct ata_port_operations; | 484 | struct ata_port_operations; |
@@ -702,6 +706,7 @@ struct ata_link { | |||
702 | unsigned int hw_sata_spd_limit; | 706 | unsigned int hw_sata_spd_limit; |
703 | unsigned int sata_spd_limit; | 707 | unsigned int sata_spd_limit; |
704 | unsigned int sata_spd; /* current SATA PHY speed */ | 708 | unsigned int sata_spd; /* current SATA PHY speed */ |
709 | enum ata_lpm_policy lpm_policy; | ||
705 | 710 | ||
706 | /* record runtime error info, protected by host_set lock */ | 711 | /* record runtime error info, protected by host_set lock */ |
707 | struct ata_eh_info eh_info; | 712 | struct ata_eh_info eh_info; |
@@ -773,7 +778,7 @@ struct ata_port { | |||
773 | 778 | ||
774 | pm_message_t pm_mesg; | 779 | pm_message_t pm_mesg; |
775 | int *pm_result; | 780 | int *pm_result; |
776 | enum ata_lpm_policy lpm_policy; | 781 | enum ata_lpm_policy target_lpm_policy; |
777 | 782 | ||
778 | struct timer_list fastdrain_timer; | 783 | struct timer_list fastdrain_timer; |
779 | unsigned long fastdrain_cnt; | 784 | unsigned long fastdrain_cnt; |
@@ -839,8 +844,8 @@ struct ata_port_operations { | |||
839 | int (*scr_write)(struct ata_link *link, unsigned int sc_reg, u32 val); | 844 | int (*scr_write)(struct ata_link *link, unsigned int sc_reg, u32 val); |
840 | void (*pmp_attach)(struct ata_port *ap); | 845 | void (*pmp_attach)(struct ata_port *ap); |
841 | void (*pmp_detach)(struct ata_port *ap); | 846 | void (*pmp_detach)(struct ata_port *ap); |
842 | int (*enable_pm)(struct ata_port *ap, enum ata_lpm_policy policy); | 847 | int (*set_lpm)(struct ata_link *link, enum ata_lpm_policy policy, |
843 | void (*disable_pm)(struct ata_port *ap); | 848 | unsigned hints); |
844 | 849 | ||
845 | /* | 850 | /* |
846 | * Start, stop, suspend and resume | 851 | * Start, stop, suspend and resume |