aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c66
1 files changed, 22 insertions, 44 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index f1c0118c6d4..aa56681f68d 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
106static const struct { 106static 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
116static const char *ata_scsi_lpm_get(enum link_pm policy) 113static 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
127static 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
157static ssize_t 136static ssize_t ata_scsi_lpm_show(struct device *dev,
158ata_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}
170DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, 148DEVICE_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);
172EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); 150EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy);
173 151
174static ssize_t ata_scsi_park_show(struct device *device, 152static ssize_t ata_scsi_park_show(struct device *device,