Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f56eca3 authored by Adam Manzanares's avatar Adam Manzanares Committed by Tejun Heo
Browse files

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: default avatarAdam Manzanares <adam.manzanares@wdc.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent aecec8b6
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -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");
	}

}

+21 −17
Original line number Diff line number Diff line
@@ -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,27 +315,31 @@ 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;
	} else {
			dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
			rc = -EIO;
		}
		spin_unlock_irq(ap->lock);
	}

unlock:
	spin_unlock_irqrestore(ap->lock, flags);

	return rc ? rc : len;
}