diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f79d09c9419be6f410b77d4b16138211fd570525..9cd0a2d4181699d94f73f2af82490e59f23373e2 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 c9abb87a09ea1773bb56cc8c3abb9047937f96bb..1f863e757ee47189e9cef517a09d3045d0f2fd1f 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; }