aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Manzanares <adam.manzanares@hgst.com>2016-10-17 14:27:30 -0400
committerTejun Heo <tj@kernel.org>2016-10-19 14:34:36 -0400
commit84f95243b5439a20c33837075b88926bfa00c4ec (patch)
treec1a795666af16d26984bdfda3cfaef4dfc659c93
parent8e061784b51ec4a4efed0deaafb5bd9725bf5b06 (diff)
ata: ATA Command Priority Disabled By Default
Add a sysfs entry to turn on priority information being passed to a ATA device. By default this feature is turned off. This patch depends on ata: Enabling ATA Command Priorities tj: Renamed ncq_prio_on to ncq_prio_enable and removed trivial ata_ncq_prio_on() and open-coded the test. Signed-off-by: Adam Manzanares <adam.manzanares@hgst.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--drivers/ata/libahci.c1
-rw-r--r--drivers/ata/libata-core.c3
-rw-r--r--drivers/ata/libata-scsi.c68
-rw-r--r--include/linux/libata.h2
4 files changed, 73 insertions, 1 deletions
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 0d028ead99e8..ee7db3119b18 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -140,6 +140,7 @@ EXPORT_SYMBOL_GPL(ahci_shost_attrs);
140struct device_attribute *ahci_sdev_attrs[] = { 140struct device_attribute *ahci_sdev_attrs[] = {
141 &dev_attr_sw_activity, 141 &dev_attr_sw_activity,
142 &dev_attr_unload_heads, 142 &dev_attr_unload_heads,
143 &dev_attr_ncq_prio_enable,
143 NULL 144 NULL
144}; 145};
145EXPORT_SYMBOL_GPL(ahci_sdev_attrs); 146EXPORT_SYMBOL_GPL(ahci_sdev_attrs);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 8346faf63337..b294339159a4 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -787,7 +787,8 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
787 if (tf->flags & ATA_TFLAG_FUA) 787 if (tf->flags & ATA_TFLAG_FUA)
788 tf->device |= 1 << 7; 788 tf->device |= 1 << 7;
789 789
790 if (dev->flags & ATA_DFLAG_NCQ_PRIO) { 790 if ((dev->flags & ATA_DFLAG_NCQ_PRIO) &&
791 (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) {
791 if (class == IOPRIO_CLASS_RT) 792 if (class == IOPRIO_CLASS_RT)
792 tf->hob_nsect |= ATA_PRIO_HIGH << 793 tf->hob_nsect |= ATA_PRIO_HIGH <<
793 ATA_SHIFT_PRIO; 794 ATA_SHIFT_PRIO;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 2bccc3c7de48..87597a3f6149 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -271,6 +271,73 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
271 ata_scsi_park_show, ata_scsi_park_store); 271 ata_scsi_park_show, ata_scsi_park_store);
272EXPORT_SYMBOL_GPL(dev_attr_unload_heads); 272EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
273 273
274static ssize_t ata_ncq_prio_enable_show(struct device *device,
275 struct device_attribute *attr, char *buf)
276{
277 struct scsi_device *sdev = to_scsi_device(device);
278 struct ata_port *ap;
279 struct ata_device *dev;
280 bool ncq_prio_enable;
281 int rc = 0;
282
283 ap = ata_shost_to_port(sdev->host);
284
285 spin_lock_irq(ap->lock);
286 dev = ata_scsi_find_dev(ap, sdev);
287 if (!dev) {
288 rc = -ENODEV;
289 goto unlock;
290 }
291
292 ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE;
293
294unlock:
295 spin_unlock_irq(ap->lock);
296
297 return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable);
298}
299
300static ssize_t ata_ncq_prio_enable_store(struct device *device,
301 struct device_attribute *attr,
302 const char *buf, size_t len)
303{
304 struct scsi_device *sdev = to_scsi_device(device);
305 struct ata_port *ap;
306 struct ata_device *dev;
307 long int input;
308 unsigned long flags;
309 int rc;
310
311 rc = kstrtol(buf, 10, &input);
312 if (rc)
313 return rc;
314 if ((input < 0) || (input > 1))
315 return -EINVAL;
316
317 ap = ata_shost_to_port(sdev->host);
318
319 spin_lock_irqsave(ap->lock, flags);
320 dev = ata_scsi_find_dev(ap, sdev);
321 if (unlikely(!dev)) {
322 rc = -ENODEV;
323 goto unlock;
324 }
325
326 if (input)
327 dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
328 else
329 dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
330
331unlock:
332 spin_unlock_irqrestore(ap->lock, flags);
333
334 return rc ? rc : len;
335}
336
337DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR,
338 ata_ncq_prio_enable_show, ata_ncq_prio_enable_store);
339EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable);
340
274void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd, 341void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd,
275 u8 sk, u8 asc, u8 ascq) 342 u8 sk, u8 asc, u8 ascq)
276{ 343{
@@ -402,6 +469,7 @@ EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
402 469
403struct device_attribute *ata_common_sdev_attrs[] = { 470struct device_attribute *ata_common_sdev_attrs[] = {
404 &dev_attr_unload_heads, 471 &dev_attr_unload_heads,
472 &dev_attr_ncq_prio_enable,
405 NULL 473 NULL
406}; 474};
407EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); 475EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 90b69a6293a3..c170be548b7f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -167,6 +167,7 @@ enum {
167 ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */ 167 ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
168 ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */ 168 ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */
169 ATA_DFLAG_NCQ_PRIO = (1 << 20), /* device supports NCQ priority */ 169 ATA_DFLAG_NCQ_PRIO = (1 << 20), /* device supports NCQ priority */
170 ATA_DFLAG_NCQ_PRIO_ENABLE = (1 << 21), /* Priority cmds sent to dev */
170 ATA_DFLAG_INIT_MASK = (1 << 24) - 1, 171 ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
171 172
172 ATA_DFLAG_DETACH = (1 << 24), 173 ATA_DFLAG_DETACH = (1 << 24),
@@ -545,6 +546,7 @@ typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes)
545 546
546extern struct device_attribute dev_attr_link_power_management_policy; 547extern struct device_attribute dev_attr_link_power_management_policy;
547extern struct device_attribute dev_attr_unload_heads; 548extern struct device_attribute dev_attr_unload_heads;
549extern struct device_attribute dev_attr_ncq_prio_enable;
548extern struct device_attribute dev_attr_em_message_type; 550extern struct device_attribute dev_attr_em_message_type;
549extern struct device_attribute dev_attr_em_message; 551extern struct device_attribute dev_attr_em_message;
550extern struct device_attribute dev_attr_sw_activity; 552extern struct device_attribute dev_attr_sw_activity;