Skip to content

Commit

Permalink
ata: avoid probing NCQ Prio Support if not explicitly requested
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Adam Manzanares authored and Tejun Heo committed Dec 13, 2016
1 parent aecec8b commit 9f56eca
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
13 changes: 10 additions & 3 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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");
}

}

Expand Down
38 changes: 21 additions & 17 deletions drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down

0 comments on commit 9f56eca

Please sign in to comment.