aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Manzanares <adam.manzanares@wdc.com>2016-12-13 15:00:05 -0500
committerTejun Heo <tj@kernel.org>2016-12-13 17:20:17 -0500
commit9f56eca3aeeab699a7dbfb397661d2eca4430e94 (patch)
tree92de910b4b32d8ba9297f9dbc1fc6a5f5b979293
parentaecec8b60422118b52e3347430ba9382e57d6d76 (diff)
ata: avoid probing NCQ Prio Support if not explicitly requested
Previously, when the ata device was being initialized we were probing for NCQ prio support by checking the identify information and also checking the log page that holds information about ncq prio support. This caused an error on an Intel HBA so the code is now updated to only probe for NCQ prio support when the sysfs variable controlling NCQ prio support is enabled. tj: Update formatting, switch to spin_[un]lock_irq() and update locking a bit, use REVALIDATE instead of RESET, and return -EIO instead of -EINVAL on config failure. Signed-off-by: Adam Manzanares <adam.manzanares@wdc.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--drivers/ata/libata-core.c13
-rw-r--r--drivers/ata/libata-scsi.c38
2 files changed, 31 insertions, 20 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 43842fdcdc87..c2548ef89e48 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -787,7 +787,7 @@ 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_ENABLE) { 790 if (dev->flags & ATA_DFLAG_NCQ_PRIO) {
791 if (class == IOPRIO_CLASS_RT) 791 if (class == IOPRIO_CLASS_RT)
792 tf->hob_nsect |= ATA_PRIO_HIGH << 792 tf->hob_nsect |= ATA_PRIO_HIGH <<
793 ATA_SHIFT_PRIO; 793 ATA_SHIFT_PRIO;
@@ -2168,6 +2168,11 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
2168 struct ata_port *ap = dev->link->ap; 2168 struct ata_port *ap = dev->link->ap;
2169 unsigned int err_mask; 2169 unsigned int err_mask;
2170 2170
2171 if (!(dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) {
2172 dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
2173 return;
2174 }
2175
2171 err_mask = ata_read_log_page(dev, 2176 err_mask = ata_read_log_page(dev,
2172 ATA_LOG_SATA_ID_DEV_DATA, 2177 ATA_LOG_SATA_ID_DEV_DATA,
2173 ATA_LOG_SATA_SETTINGS, 2178 ATA_LOG_SATA_SETTINGS,
@@ -2180,10 +2185,12 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
2180 return; 2185 return;
2181 } 2186 }
2182 2187
2183 if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3)) 2188 if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3)) {
2184 dev->flags |= ATA_DFLAG_NCQ_PRIO; 2189 dev->flags |= ATA_DFLAG_NCQ_PRIO;
2185 else 2190 } else {
2191 dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
2186 ata_dev_dbg(dev, "SATA page does not support priority\n"); 2192 ata_dev_dbg(dev, "SATA page does not support priority\n");
2193 }
2187 2194
2188} 2195}
2189 2196
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 49c09d876358..3c64288df227 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -272,7 +272,8 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
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, 274static ssize_t ata_ncq_prio_enable_show(struct device *device,
275 struct device_attribute *attr, char *buf) 275 struct device_attribute *attr,
276 char *buf)
276{ 277{
277 struct scsi_device *sdev = to_scsi_device(device); 278 struct scsi_device *sdev = to_scsi_device(device);
278 struct ata_port *ap; 279 struct ata_port *ap;
@@ -305,7 +306,6 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device,
305 struct ata_port *ap; 306 struct ata_port *ap;
306 struct ata_device *dev; 307 struct ata_device *dev;
307 long int input; 308 long int input;
308 unsigned long flags;
309 int rc; 309 int rc;
310 310
311 rc = kstrtol(buf, 10, &input); 311 rc = kstrtol(buf, 10, &input);
@@ -315,28 +315,32 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device,
315 return -EINVAL; 315 return -EINVAL;
316 316
317 ap = ata_shost_to_port(sdev->host); 317 ap = ata_shost_to_port(sdev->host);
318
319 spin_lock_irqsave(ap->lock, flags);
320 dev = ata_scsi_find_dev(ap, sdev); 318 dev = ata_scsi_find_dev(ap, sdev);
321 if (unlikely(!dev)) { 319 if (unlikely(!dev))
322 rc = -ENODEV; 320 return -ENODEV;
323 goto unlock; 321
324 } 322 spin_lock_irq(ap->lock);
323 if (input)
324 dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
325 else
326 dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
327
328 dev->link->eh_info.action |= ATA_EH_REVALIDATE;
329 dev->link->eh_info.flags |= ATA_EHI_QUIET;
330 ata_port_schedule_eh(ap);
331 spin_unlock_irq(ap->lock);
332
333 ata_port_wait_eh(ap);
325 334
326 if (input) { 335 if (input) {
336 spin_lock_irq(ap->lock);
327 if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) { 337 if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) {
328 rc = -EOPNOTSUPP; 338 dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
329 goto unlock; 339 rc = -EIO;
330 } 340 }
331 341 spin_unlock_irq(ap->lock);
332 dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
333 } else {
334 dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
335 } 342 }
336 343
337unlock:
338 spin_unlock_irqrestore(ap->lock, flags);
339
340 return rc ? rc : len; 344 return rc ? rc : len;
341} 345}
342 346