summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
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;
}