summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorAdam Manzanares <adam.manzanares@wdc.com>2016-12-13 12:00:05 -0800
committerTejun Heo <tj@kernel.org>2016-12-13 17:20:17 -0500
commit9f56eca3aeeab699a7dbfb397661d2eca4430e94 (patch)
tree92de910b4b32d8ba9297f9dbc1fc6a5f5b979293 /drivers/ata
parentaecec8b60422118b52e3347430ba9382e57d6d76 (diff)
downloadlinux-stable-9f56eca3aeeab699a7dbfb397661d2eca4430e94.tar.gz
linux-stable-9f56eca3aeeab699a7dbfb397661d2eca4430e94.tar.bz2
linux-stable-9f56eca3aeeab699a7dbfb397661d2eca4430e94.zip
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>
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 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,
if (tf->flags & ATA_TFLAG_FUA)
tf->device |= 1 << 7;
- if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE) {
+ if (dev->flags & ATA_DFLAG_NCQ_PRIO) {
if (class == IOPRIO_CLASS_RT)
tf->hob_nsect |= ATA_PRIO_HIGH <<
ATA_SHIFT_PRIO;
@@ -2168,6 +2168,11 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
struct ata_port *ap = dev->link->ap;
unsigned int err_mask;
+ if (!(dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) {
+ dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
+ return;
+ }
+
err_mask = ata_read_log_page(dev,
ATA_LOG_SATA_ID_DEV_DATA,
ATA_LOG_SATA_SETTINGS,
@@ -2180,10 +2185,12 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
return;
}
- if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3))
+ if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3)) {
dev->flags |= ATA_DFLAG_NCQ_PRIO;
- else
+ } else {
+ dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
ata_dev_dbg(dev, "SATA page does not support priority\n");
+ }
}
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,
EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
static ssize_t ata_ncq_prio_enable_show(struct device *device,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
struct scsi_device *sdev = to_scsi_device(device);
struct ata_port *ap;
@@ -305,7 +306,6 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device,
struct ata_port *ap;
struct ata_device *dev;
long int input;
- unsigned long flags;
int rc;
rc = kstrtol(buf, 10, &input);
@@ -315,28 +315,32 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device,
return -EINVAL;
ap = ata_shost_to_port(sdev->host);
-
- spin_lock_irqsave(ap->lock, flags);
dev = ata_scsi_find_dev(ap, sdev);
- if (unlikely(!dev)) {
- rc = -ENODEV;
- goto unlock;
- }
+ if (unlikely(!dev))
+ return -ENODEV;
+
+ spin_lock_irq(ap->lock);
+ if (input)
+ dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
+ else
+ dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
+
+ dev->link->eh_info.action |= ATA_EH_REVALIDATE;
+ dev->link->eh_info.flags |= ATA_EHI_QUIET;
+ ata_port_schedule_eh(ap);
+ spin_unlock_irq(ap->lock);
+
+ ata_port_wait_eh(ap);
if (input) {
+ spin_lock_irq(ap->lock);
if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) {
- rc = -EOPNOTSUPP;
- goto unlock;
+ dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
+ rc = -EIO;
}
-
- dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
- } else {
- dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
+ spin_unlock_irq(ap->lock);
}
-unlock:
- spin_unlock_irqrestore(ap->lock, flags);
-
return rc ? rc : len;
}