summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-13 18:30:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-13 18:30:50 -0500
commit7b882cb800095f216c9da6b6735d10d26df8168b (patch)
tree4c240a0ecdce63f4c48da2da7e5538facdbd86a5 /drivers/ata
parentb92e09bb5bf4db65aeb8ca0094fdd5142ed54451 (diff)
parent9f56eca3aeeab699a7dbfb397661d2eca4430e94 (diff)
Merge branch 'for-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull another libata patch from Tejun Heo: "One more patch from Adam added. It makes libata skip probing for NCQ prio unless the feature is explicitly requested by the user. This is necessary because some controllers lock up after the optional feature is probed" * 'for-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: ata: avoid probing NCQ Prio Support if not explicitly requested
Diffstat (limited to 'drivers/ata')
-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 f79d09c9419b..9cd0a2d41816 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 c9abb87a09ea..1f863e757ee4 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