summaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c38
1 files changed, 21 insertions, 17 deletions
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,
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;
}