diff options
| -rw-r--r-- | drivers/ata/ahci.c | 2 | ||||
| -rw-r--r-- | drivers/ata/ahci.h | 2 | ||||
| -rw-r--r-- | drivers/ata/ahci_platform.c | 2 | ||||
| -rw-r--r-- | drivers/ata/libahci.c | 20 | ||||
| -rw-r--r-- | drivers/ata/libata-core.c | 50 | ||||
| -rw-r--r-- | drivers/ata/libata-eh.c | 2 | ||||
| -rw-r--r-- | drivers/ata/libata-scsi.c | 66 | ||||
| -rw-r--r-- | drivers/ata/libata.h | 6 | ||||
| -rw-r--r-- | include/linux/libata.h | 29 |
9 files changed, 79 insertions, 100 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 99d0e5a51148..68f7b4216501 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -1209,7 +1209,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1209 | 0x100 + ap->port_no * 0x80, "port"); | 1209 | 0x100 + ap->port_no * 0x80, "port"); |
| 1210 | 1210 | ||
| 1211 | /* set initial link pm policy */ | 1211 | /* set initial link pm policy */ |
| 1212 | ap->pm_policy = NOT_AVAILABLE; | 1212 | ap->lpm_policy = ATA_LPM_UNKNOWN; |
| 1213 | 1213 | ||
| 1214 | /* set enclosure management message type */ | 1214 | /* set enclosure management message type */ |
| 1215 | if (ap->flags & ATA_FLAG_EM) | 1215 | if (ap->flags & ATA_FLAG_EM) |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index e5fdeebf9ef0..93867d3f8dd3 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
| @@ -216,7 +216,7 @@ enum { | |||
| 216 | AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 216 | AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
| 217 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | 217 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | |
| 218 | ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | | 218 | ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | |
| 219 | ATA_FLAG_IPM, | 219 | ATA_FLAG_LPM, |
| 220 | 220 | ||
| 221 | ICH_MAP = 0x90, /* ICH MAP register */ | 221 | ICH_MAP = 0x90, /* ICH MAP register */ |
| 222 | 222 | ||
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 84b643270e7a..07556853c0d6 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
| @@ -130,7 +130,7 @@ static int __init ahci_probe(struct platform_device *pdev) | |||
| 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 */ | 132 | /* set initial link pm policy */ |
| 133 | ap->pm_policy = NOT_AVAILABLE; | 133 | ap->lpm_policy = ATA_LPM_UNKNOWN; |
| 134 | 134 | ||
| 135 | /* set enclosure management message type */ | 135 | /* set enclosure management message type */ |
| 136 | if (ap->flags & ATA_FLAG_EM) | 136 | if (ap->flags & ATA_FLAG_EM) |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 8eea309ea212..ed7803f2b4f1 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
| @@ -56,8 +56,7 @@ 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, | 59 | static int ahci_enable_alpm(struct ata_port *ap, enum ata_lpm_policy policy); |
| 60 | enum link_pm policy); | ||
| 61 | static void ahci_disable_alpm(struct ata_port *ap); | 60 | static void ahci_disable_alpm(struct ata_port *ap); |
| 62 | 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); |
| 63 | 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, |
| @@ -649,7 +648,7 @@ static void ahci_disable_alpm(struct ata_port *ap) | |||
| 649 | u32 cmd; | 648 | u32 cmd; |
| 650 | struct ahci_port_priv *pp = ap->private_data; | 649 | struct ahci_port_priv *pp = ap->private_data; |
| 651 | 650 | ||
| 652 | /* IPM bits should be disabled by libata-core */ | 651 | /* LPM bits should be disabled by libata-core */ |
| 653 | /* get the existing command bits */ | 652 | /* get the existing command bits */ |
| 654 | cmd = readl(port_mmio + PORT_CMD); | 653 | cmd = readl(port_mmio + PORT_CMD); |
| 655 | 654 | ||
| @@ -691,8 +690,7 @@ static void ahci_disable_alpm(struct ata_port *ap) | |||
| 691 | */ | 690 | */ |
| 692 | } | 691 | } |
| 693 | 692 | ||
| 694 | static int ahci_enable_alpm(struct ata_port *ap, | 693 | static int ahci_enable_alpm(struct ata_port *ap, enum ata_lpm_policy policy) |
| 695 | enum link_pm policy) | ||
| 696 | { | 694 | { |
| 697 | struct ahci_host_priv *hpriv = ap->host->private_data; | 695 | struct ahci_host_priv *hpriv = ap->host->private_data; |
| 698 | void __iomem *port_mmio = ahci_port_base(ap); | 696 | void __iomem *port_mmio = ahci_port_base(ap); |
| @@ -705,21 +703,21 @@ static int ahci_enable_alpm(struct ata_port *ap, | |||
| 705 | return -EINVAL; | 703 | return -EINVAL; |
| 706 | 704 | ||
| 707 | switch (policy) { | 705 | switch (policy) { |
| 708 | case MAX_PERFORMANCE: | 706 | case ATA_LPM_MAX_POWER: |
| 709 | case NOT_AVAILABLE: | 707 | case ATA_LPM_UNKNOWN: |
| 710 | /* | 708 | /* |
| 711 | * if we came here with NOT_AVAILABLE, | 709 | * if we came here with ATA_LPM_UNKNOWN, |
| 712 | * it just means this is the first time we | 710 | * it just means this is the first time we |
| 713 | * have tried to enable - default to max performance, | 711 | * have tried to enable - default to max performance, |
| 714 | * and let the user go to lower power modes on request. | 712 | * and let the user go to lower power modes on request. |
| 715 | */ | 713 | */ |
| 716 | ahci_disable_alpm(ap); | 714 | ahci_disable_alpm(ap); |
| 717 | return 0; | 715 | return 0; |
| 718 | case MIN_POWER: | 716 | case ATA_LPM_MIN_POWER: |
| 719 | /* configure HBA to enter SLUMBER */ | 717 | /* configure HBA to enter SLUMBER */ |
| 720 | asp = PORT_CMD_ASP; | 718 | asp = PORT_CMD_ASP; |
| 721 | break; | 719 | break; |
| 722 | case MEDIUM_POWER: | 720 | case ATA_LPM_MED_POWER: |
| 723 | /* configure HBA to enter PARTIAL */ | 721 | /* configure HBA to enter PARTIAL */ |
| 724 | asp = 0; | 722 | asp = 0; |
| 725 | break; | 723 | break; |
| @@ -762,7 +760,7 @@ static int ahci_enable_alpm(struct ata_port *ap, | |||
| 762 | writel(cmd, port_mmio + PORT_CMD); | 760 | writel(cmd, port_mmio + PORT_CMD); |
| 763 | cmd = readl(port_mmio + PORT_CMD); | 761 | cmd = readl(port_mmio + PORT_CMD); |
| 764 | 762 | ||
| 765 | /* IPM bits should be set by libata-core */ | 763 | /* LPM bits should be set by libata-core */ |
| 766 | return 0; | 764 | return 0; |
| 767 | } | 765 | } |
| 768 | 766 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 92cd5f375b8f..380ceb000aad 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -1030,7 +1030,7 @@ const char *sata_spd_string(unsigned int spd) | |||
| 1030 | return spd_str[spd - 1]; | 1030 | return spd_str[spd - 1]; |
| 1031 | } | 1031 | } |
| 1032 | 1032 | ||
| 1033 | static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) | 1033 | static int ata_dev_set_dipm(struct ata_device *dev, enum ata_lpm_policy policy) |
| 1034 | { | 1034 | { |
| 1035 | struct ata_link *link = dev->link; | 1035 | struct ata_link *link = dev->link; |
| 1036 | struct ata_port *ap = link->ap; | 1036 | struct ata_port *ap = link->ap; |
| @@ -1040,14 +1040,14 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) | |||
| 1040 | 1040 | ||
| 1041 | /* | 1041 | /* |
| 1042 | * disallow DIPM for drivers which haven't set | 1042 | * disallow DIPM for drivers which haven't set |
| 1043 | * ATA_FLAG_IPM. This is because when DIPM is enabled, | 1043 | * ATA_FLAG_LPM. This is because when DIPM is enabled, |
| 1044 | * phy ready will be set in the interrupt status on | 1044 | * phy ready will be set in the interrupt status on |
| 1045 | * state changes, which will cause some drivers to | 1045 | * state changes, which will cause some drivers to |
| 1046 | * think there are errors - additionally drivers will | 1046 | * think there are errors - additionally drivers will |
| 1047 | * need to disable hot plug. | 1047 | * need to disable hot plug. |
| 1048 | */ | 1048 | */ |
| 1049 | if (!(ap->flags & ATA_FLAG_IPM) || !ata_dev_enabled(dev)) { | 1049 | if (!(ap->flags & ATA_FLAG_LPM) || !ata_dev_enabled(dev)) { |
| 1050 | ap->pm_policy = NOT_AVAILABLE; | 1050 | ap->lpm_policy = ATA_LPM_UNKNOWN; |
| 1051 | return -EINVAL; | 1051 | return -EINVAL; |
| 1052 | } | 1052 | } |
| 1053 | 1053 | ||
| @@ -1066,8 +1066,8 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) | |||
| 1066 | return rc; | 1066 | return rc; |
| 1067 | 1067 | ||
| 1068 | switch (policy) { | 1068 | switch (policy) { |
| 1069 | case MIN_POWER: | 1069 | case ATA_LPM_MIN_POWER: |
| 1070 | /* no restrictions on IPM transitions */ | 1070 | /* no restrictions on LPM transitions */ |
| 1071 | scontrol &= ~(0x3 << 8); | 1071 | scontrol &= ~(0x3 << 8); |
| 1072 | rc = sata_scr_write(link, SCR_CONTROL, scontrol); | 1072 | rc = sata_scr_write(link, SCR_CONTROL, scontrol); |
| 1073 | if (rc) | 1073 | if (rc) |
| @@ -1078,8 +1078,8 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) | |||
| 1078 | err_mask = ata_dev_set_feature(dev, | 1078 | err_mask = ata_dev_set_feature(dev, |
| 1079 | SETFEATURES_SATA_ENABLE, SATA_DIPM); | 1079 | SETFEATURES_SATA_ENABLE, SATA_DIPM); |
| 1080 | break; | 1080 | break; |
| 1081 | case MEDIUM_POWER: | 1081 | case ATA_LPM_MED_POWER: |
| 1082 | /* allow IPM to PARTIAL */ | 1082 | /* allow LPM to PARTIAL */ |
| 1083 | scontrol &= ~(0x1 << 8); | 1083 | scontrol &= ~(0x1 << 8); |
| 1084 | scontrol |= (0x2 << 8); | 1084 | scontrol |= (0x2 << 8); |
| 1085 | rc = sata_scr_write(link, SCR_CONTROL, scontrol); | 1085 | rc = sata_scr_write(link, SCR_CONTROL, scontrol); |
| @@ -1087,21 +1087,21 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) | |||
| 1087 | return rc; | 1087 | return rc; |
| 1088 | 1088 | ||
| 1089 | /* | 1089 | /* |
| 1090 | * we don't have to disable DIPM since IPM flags | 1090 | * we don't have to disable DIPM since LPM flags |
| 1091 | * disallow transitions to SLUMBER, which effectively | 1091 | * disallow transitions to SLUMBER, which effectively |
| 1092 | * disable DIPM if it does not support PARTIAL | 1092 | * disable DIPM if it does not support PARTIAL |
| 1093 | */ | 1093 | */ |
| 1094 | break; | 1094 | break; |
| 1095 | case NOT_AVAILABLE: | 1095 | case ATA_LPM_UNKNOWN: |
| 1096 | case MAX_PERFORMANCE: | 1096 | case ATA_LPM_MAX_POWER: |
| 1097 | /* disable all IPM transitions */ | 1097 | /* disable all LPM transitions */ |
| 1098 | scontrol |= (0x3 << 8); | 1098 | scontrol |= (0x3 << 8); |
| 1099 | rc = sata_scr_write(link, SCR_CONTROL, scontrol); | 1099 | rc = sata_scr_write(link, SCR_CONTROL, scontrol); |
| 1100 | if (rc) | 1100 | if (rc) |
| 1101 | return rc; | 1101 | return rc; |
| 1102 | 1102 | ||
| 1103 | /* | 1103 | /* |
| 1104 | * we don't have to disable DIPM since IPM flags | 1104 | * we don't have to disable DIPM since LPM flags |
| 1105 | * disallow all transitions which effectively | 1105 | * disallow all transitions which effectively |
| 1106 | * disable DIPM anyway. | 1106 | * disable DIPM anyway. |
| 1107 | */ | 1107 | */ |
| @@ -1125,9 +1125,9 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) | |||
| 1125 | * enabling Host Initiated Power management. | 1125 | * enabling Host Initiated Power management. |
| 1126 | * | 1126 | * |
| 1127 | * Locking: Caller. | 1127 | * Locking: Caller. |
| 1128 | * Returns: -EINVAL if IPM is not supported, 0 otherwise. | 1128 | * Returns: -EINVAL if LPM is not supported, 0 otherwise. |
| 1129 | */ | 1129 | */ |
| 1130 | void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy) | 1130 | void ata_dev_enable_pm(struct ata_device *dev, enum ata_lpm_policy policy) |
| 1131 | { | 1131 | { |
| 1132 | int rc = 0; | 1132 | int rc = 0; |
| 1133 | struct ata_port *ap = dev->link->ap; | 1133 | struct ata_port *ap = dev->link->ap; |
| @@ -1141,9 +1141,9 @@ void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy) | |||
| 1141 | 1141 | ||
| 1142 | enable_pm_out: | 1142 | enable_pm_out: |
| 1143 | if (rc) | 1143 | if (rc) |
| 1144 | ap->pm_policy = MAX_PERFORMANCE; | 1144 | ap->lpm_policy = ATA_LPM_MAX_POWER; |
| 1145 | else | 1145 | else |
| 1146 | ap->pm_policy = policy; | 1146 | ap->lpm_policy = policy; |
| 1147 | return /* rc */; /* hopefully we can use 'rc' eventually */ | 1147 | return /* rc */; /* hopefully we can use 'rc' eventually */ |
| 1148 | } | 1148 | } |
| 1149 | 1149 | ||
| @@ -1164,15 +1164,15 @@ static void ata_dev_disable_pm(struct ata_device *dev) | |||
| 1164 | { | 1164 | { |
| 1165 | struct ata_port *ap = dev->link->ap; | 1165 | struct ata_port *ap = dev->link->ap; |
| 1166 | 1166 | ||
| 1167 | ata_dev_set_dipm(dev, MAX_PERFORMANCE); | 1167 | ata_dev_set_dipm(dev, ATA_LPM_MAX_POWER); |
| 1168 | if (ap->ops->disable_pm) | 1168 | if (ap->ops->disable_pm) |
| 1169 | ap->ops->disable_pm(ap); | 1169 | ap->ops->disable_pm(ap); |
| 1170 | } | 1170 | } |
| 1171 | #endif /* CONFIG_PM */ | 1171 | #endif /* CONFIG_PM */ |
| 1172 | 1172 | ||
| 1173 | void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy) | 1173 | void ata_lpm_schedule(struct ata_port *ap, enum ata_lpm_policy policy) |
| 1174 | { | 1174 | { |
| 1175 | ap->pm_policy = policy; | 1175 | ap->lpm_policy = policy; |
| 1176 | ap->link.eh_info.action |= ATA_EH_LPM; | 1176 | ap->link.eh_info.action |= ATA_EH_LPM; |
| 1177 | ap->link.eh_info.flags |= ATA_EHI_NO_AUTOPSY; | 1177 | ap->link.eh_info.flags |= ATA_EHI_NO_AUTOPSY; |
| 1178 | ata_port_schedule_eh(ap); | 1178 | ata_port_schedule_eh(ap); |
| @@ -1201,7 +1201,7 @@ static void ata_lpm_disable(struct ata_host *host) | |||
| 1201 | 1201 | ||
| 1202 | for (i = 0; i < host->n_ports; i++) { | 1202 | for (i = 0; i < host->n_ports; i++) { |
| 1203 | struct ata_port *ap = host->ports[i]; | 1203 | struct ata_port *ap = host->ports[i]; |
| 1204 | ata_lpm_schedule(ap, ap->pm_policy); | 1204 | ata_lpm_schedule(ap, ap->lpm_policy); |
| 1205 | } | 1205 | } |
| 1206 | } | 1206 | } |
| 1207 | #endif /* CONFIG_PM */ | 1207 | #endif /* CONFIG_PM */ |
| @@ -2564,7 +2564,7 @@ int ata_dev_configure(struct ata_device *dev) | |||
| 2564 | if (dev->flags & ATA_DFLAG_LBA48) | 2564 | if (dev->flags & ATA_DFLAG_LBA48) |
| 2565 | dev->max_sectors = ATA_MAX_SECTORS_LBA48; | 2565 | dev->max_sectors = ATA_MAX_SECTORS_LBA48; |
| 2566 | 2566 | ||
| 2567 | if (!(dev->horkage & ATA_HORKAGE_IPM)) { | 2567 | if (!(dev->horkage & ATA_HORKAGE_LPM)) { |
| 2568 | if (ata_id_has_hipm(dev->id)) | 2568 | if (ata_id_has_hipm(dev->id)) |
| 2569 | dev->flags |= ATA_DFLAG_HIPM; | 2569 | dev->flags |= ATA_DFLAG_HIPM; |
| 2570 | if (ata_id_has_dipm(dev->id)) | 2570 | if (ata_id_has_dipm(dev->id)) |
| @@ -2591,11 +2591,11 @@ int ata_dev_configure(struct ata_device *dev) | |||
| 2591 | dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, | 2591 | dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, |
| 2592 | dev->max_sectors); | 2592 | dev->max_sectors); |
| 2593 | 2593 | ||
| 2594 | if (ata_dev_blacklisted(dev) & ATA_HORKAGE_IPM) { | 2594 | if (ata_dev_blacklisted(dev) & ATA_HORKAGE_LPM) { |
| 2595 | dev->horkage |= ATA_HORKAGE_IPM; | 2595 | dev->horkage |= ATA_HORKAGE_LPM; |
| 2596 | 2596 | ||
| 2597 | /* reset link pm_policy for this port to no pm */ | 2597 | /* reset link pm_policy for this port to no pm */ |
| 2598 | ap->pm_policy = MAX_PERFORMANCE; | 2598 | ap->lpm_policy = ATA_LPM_MAX_POWER; |
| 2599 | } | 2599 | } |
| 2600 | 2600 | ||
| 2601 | if (ap->ops->dev_config) | 2601 | if (ap->ops->dev_config) |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 95838b382231..96aa75ddf87f 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -3570,7 +3570,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
| 3570 | /* configure link power saving */ | 3570 | /* configure link power saving */ |
| 3571 | if (ehc->i.action & ATA_EH_LPM) | 3571 | if (ehc->i.action & ATA_EH_LPM) |
| 3572 | ata_for_each_dev(dev, link, ALL) | 3572 | ata_for_each_dev(dev, link, ALL) |
| 3573 | ata_dev_enable_pm(dev, ap->pm_policy); | 3573 | ata_dev_enable_pm(dev, ap->lpm_policy); |
| 3574 | 3574 | ||
| 3575 | /* this link is okay now */ | 3575 | /* this link is okay now */ |
| 3576 | ehc->i.flags = 0; | 3576 | ehc->i.flags = 0; |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index f1c0118c6d4b..aa56681f68db 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -103,72 +103,50 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { | |||
| 103 | 0, 30 /* extended self test time, see 05-359r1 */ | 103 | 0, 30 /* extended self test time, see 05-359r1 */ |
| 104 | }; | 104 | }; |
| 105 | 105 | ||
| 106 | static const struct { | 106 | static const char *ata_lpm_policy_names[] = { |
| 107 | enum link_pm value; | 107 | [ATA_LPM_UNKNOWN] = "max_performance", |
| 108 | const char *name; | 108 | [ATA_LPM_MAX_POWER] = "max_performance", |
| 109 | } link_pm_policy[] = { | 109 | [ATA_LPM_MED_POWER] = "medium_power", |
| 110 | { NOT_AVAILABLE, "max_performance" }, | 110 | [ATA_LPM_MIN_POWER] = "min_power", |
| 111 | { MIN_POWER, "min_power" }, | ||
| 112 | { MAX_PERFORMANCE, "max_performance" }, | ||
| 113 | { MEDIUM_POWER, "medium_power" }, | ||
| 114 | }; | 111 | }; |
| 115 | 112 | ||
| 116 | static const char *ata_scsi_lpm_get(enum link_pm policy) | 113 | static ssize_t ata_scsi_lpm_store(struct device *dev, |
| 117 | { | 114 | struct device_attribute *attr, |
| 118 | int i; | 115 | const char *buf, size_t count) |
| 119 | |||
| 120 | for (i = 0; i < ARRAY_SIZE(link_pm_policy); i++) | ||
| 121 | if (link_pm_policy[i].value == policy) | ||
| 122 | return link_pm_policy[i].name; | ||
| 123 | |||
| 124 | return NULL; | ||
| 125 | } | ||
| 126 | |||
| 127 | static ssize_t ata_scsi_lpm_put(struct device *dev, | ||
| 128 | struct device_attribute *attr, | ||
| 129 | const char *buf, size_t count) | ||
| 130 | { | 116 | { |
| 131 | struct Scsi_Host *shost = class_to_shost(dev); | 117 | struct Scsi_Host *shost = class_to_shost(dev); |
| 132 | struct ata_port *ap = ata_shost_to_port(shost); | 118 | struct ata_port *ap = ata_shost_to_port(shost); |
| 133 | enum link_pm policy = 0; | 119 | enum ata_lpm_policy policy; |
| 134 | int i; | ||
| 135 | 120 | ||
| 136 | /* | 121 | /* UNKNOWN is internal state, iterate from MAX_POWER */ |
| 137 | * we are skipping array location 0 on purpose - this | 122 | for (policy = ATA_LPM_MAX_POWER; |
| 138 | * is because a value of NOT_AVAILABLE is displayed | 123 | policy < ARRAY_SIZE(ata_lpm_policy_names); policy++) { |
| 139 | * to the user as max_performance, but when the user | 124 | const char *name = ata_lpm_policy_names[policy]; |
| 140 | * writes "max_performance", they actually want the | 125 | |
| 141 | * value to match MAX_PERFORMANCE. | 126 | if (strncmp(name, buf, strlen(name)) == 0) |
| 142 | */ | ||
| 143 | for (i = 1; i < ARRAY_SIZE(link_pm_policy); i++) { | ||
| 144 | const int len = strlen(link_pm_policy[i].name); | ||
| 145 | if (strncmp(link_pm_policy[i].name, buf, len) == 0) { | ||
| 146 | policy = link_pm_policy[i].value; | ||
| 147 | break; | 127 | break; |
| 148 | } | ||
| 149 | } | 128 | } |
| 150 | if (!policy) | 129 | if (policy == ARRAY_SIZE(ata_lpm_policy_names)) |
| 151 | return -EINVAL; | 130 | return -EINVAL; |
| 152 | 131 | ||
| 153 | ata_lpm_schedule(ap, policy); | 132 | ata_lpm_schedule(ap, policy); |
| 154 | return count; | 133 | return count; |
| 155 | } | 134 | } |
| 156 | 135 | ||
| 157 | static ssize_t | 136 | static ssize_t ata_scsi_lpm_show(struct device *dev, |
| 158 | ata_scsi_lpm_show(struct device *dev, struct device_attribute *attr, char *buf) | 137 | struct device_attribute *attr, char *buf) |
| 159 | { | 138 | { |
| 160 | struct Scsi_Host *shost = class_to_shost(dev); | 139 | struct Scsi_Host *shost = class_to_shost(dev); |
| 161 | struct ata_port *ap = ata_shost_to_port(shost); | 140 | struct ata_port *ap = ata_shost_to_port(shost); |
| 162 | const char *policy = | ||
| 163 | ata_scsi_lpm_get(ap->pm_policy); | ||
| 164 | 141 | ||
| 165 | if (!policy) | 142 | if (ap->lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) |
| 166 | return -EINVAL; | 143 | return -EINVAL; |
| 167 | 144 | ||
| 168 | return snprintf(buf, 23, "%s\n", policy); | 145 | return snprintf(buf, PAGE_SIZE, "%s\n", |
| 146 | ata_lpm_policy_names[ap->lpm_policy]); | ||
| 169 | } | 147 | } |
| 170 | DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, | 148 | DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, |
| 171 | ata_scsi_lpm_show, ata_scsi_lpm_put); | 149 | ata_scsi_lpm_show, ata_scsi_lpm_store); |
| 172 | EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); | 150 | EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); |
| 173 | 151 | ||
| 174 | static ssize_t ata_scsi_park_show(struct device *device, | 152 | static ssize_t ata_scsi_park_show(struct device *device, |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 142102b94df5..1471462e3e3c 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
| @@ -100,8 +100,10 @@ extern int sata_link_init_spd(struct ata_link *link); | |||
| 100 | extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); | 100 | extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); |
| 101 | extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); | 101 | extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); |
| 102 | extern struct ata_port *ata_port_alloc(struct ata_host *host); | 102 | extern struct ata_port *ata_port_alloc(struct ata_host *host); |
| 103 | extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy); | 103 | extern void ata_dev_enable_pm(struct ata_device *dev, |
| 104 | extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm); | 104 | enum ata_lpm_policy policy); |
| 105 | extern void ata_lpm_schedule(struct ata_port *ap, | ||
| 106 | enum ata_lpm_policy policy); | ||
| 105 | extern const char *sata_spd_string(unsigned int spd); | 107 | extern const char *sata_spd_string(unsigned int spd); |
| 106 | 108 | ||
| 107 | /* libata-acpi.c */ | 109 | /* libata-acpi.c */ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index c50f66d4382c..c5bdc90fd319 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -196,7 +196,7 @@ enum { | |||
| 196 | ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */ | 196 | ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */ |
| 197 | ATA_FLAG_AN = (1 << 18), /* controller supports AN */ | 197 | ATA_FLAG_AN = (1 << 18), /* controller supports AN */ |
| 198 | ATA_FLAG_PMP = (1 << 19), /* controller supports PMP */ | 198 | ATA_FLAG_PMP = (1 << 19), /* controller supports PMP */ |
| 199 | ATA_FLAG_IPM = (1 << 20), /* driver can handle IPM */ | 199 | ATA_FLAG_LPM = (1 << 20), /* driver can handle LPM */ |
| 200 | ATA_FLAG_EM = (1 << 21), /* driver supports enclosure | 200 | ATA_FLAG_EM = (1 << 21), /* driver supports enclosure |
| 201 | * management */ | 201 | * management */ |
| 202 | ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity | 202 | ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity |
| @@ -377,7 +377,7 @@ 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_IPM = (1 << 7), /* Link PM problems */ | 380 | ATA_HORKAGE_LPM = (1 << 7), /* Link PM problems */ |
| 381 | ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ | 381 | ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ |
| 382 | ATA_HORKAGE_STUCK_ERR = (1 << 9), /* stuck ERR on next PACKET */ | 382 | ATA_HORKAGE_STUCK_ERR = (1 << 9), /* stuck ERR on next PACKET */ |
| 383 | ATA_HORKAGE_BRIDGE_OK = (1 << 10), /* no bridge limits */ | 383 | ATA_HORKAGE_BRIDGE_OK = (1 << 10), /* no bridge limits */ |
| @@ -464,6 +464,17 @@ enum ata_completion_errors { | |||
| 464 | AC_ERR_NCQ = (1 << 10), /* marker for offending NCQ qc */ | 464 | AC_ERR_NCQ = (1 << 10), /* marker for offending NCQ qc */ |
| 465 | }; | 465 | }; |
| 466 | 466 | ||
| 467 | /* | ||
| 468 | * Link power management policy: If you alter this, you also need to | ||
| 469 | * alter libata-scsi.c (for the ascii descriptions) | ||
| 470 | */ | ||
| 471 | enum ata_lpm_policy { | ||
| 472 | ATA_LPM_UNKNOWN, | ||
| 473 | ATA_LPM_MAX_POWER, | ||
| 474 | ATA_LPM_MED_POWER, | ||
| 475 | ATA_LPM_MIN_POWER, | ||
| 476 | }; | ||
| 477 | |||
| 467 | /* forward declarations */ | 478 | /* forward declarations */ |
| 468 | struct scsi_device; | 479 | struct scsi_device; |
| 469 | struct ata_port_operations; | 480 | struct ata_port_operations; |
| @@ -478,16 +489,6 @@ typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes, | |||
| 478 | unsigned long deadline); | 489 | unsigned long deadline); |
| 479 | typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes); | 490 | typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes); |
| 480 | 491 | ||
| 481 | /* | ||
| 482 | * host pm policy: If you alter this, you also need to alter libata-scsi.c | ||
| 483 | * (for the ascii descriptions) | ||
| 484 | */ | ||
| 485 | enum link_pm { | ||
| 486 | NOT_AVAILABLE, | ||
| 487 | MIN_POWER, | ||
| 488 | MAX_PERFORMANCE, | ||
| 489 | MEDIUM_POWER, | ||
| 490 | }; | ||
| 491 | extern struct device_attribute dev_attr_link_power_management_policy; | 492 | extern struct device_attribute dev_attr_link_power_management_policy; |
| 492 | extern struct device_attribute dev_attr_unload_heads; | 493 | extern struct device_attribute dev_attr_unload_heads; |
| 493 | extern struct device_attribute dev_attr_em_message_type; | 494 | extern struct device_attribute dev_attr_em_message_type; |
| @@ -772,7 +773,7 @@ struct ata_port { | |||
| 772 | 773 | ||
| 773 | pm_message_t pm_mesg; | 774 | pm_message_t pm_mesg; |
| 774 | int *pm_result; | 775 | int *pm_result; |
| 775 | enum link_pm pm_policy; | 776 | enum ata_lpm_policy lpm_policy; |
| 776 | 777 | ||
| 777 | struct timer_list fastdrain_timer; | 778 | struct timer_list fastdrain_timer; |
| 778 | unsigned long fastdrain_cnt; | 779 | unsigned long fastdrain_cnt; |
| @@ -838,7 +839,7 @@ struct ata_port_operations { | |||
| 838 | int (*scr_write)(struct ata_link *link, unsigned int sc_reg, u32 val); | 839 | int (*scr_write)(struct ata_link *link, unsigned int sc_reg, u32 val); |
| 839 | void (*pmp_attach)(struct ata_port *ap); | 840 | void (*pmp_attach)(struct ata_port *ap); |
| 840 | void (*pmp_detach)(struct ata_port *ap); | 841 | void (*pmp_detach)(struct ata_port *ap); |
| 841 | int (*enable_pm)(struct ata_port *ap, enum link_pm policy); | 842 | int (*enable_pm)(struct ata_port *ap, enum ata_lpm_policy policy); |
| 842 | void (*disable_pm)(struct ata_port *ap); | 843 | void (*disable_pm)(struct ata_port *ap); |
| 843 | 844 | ||
| 844 | /* | 845 | /* |
