summaryrefslogtreecommitdiff
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-13 15:30:50 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-13 15:30:50 -0800
commit7b882cb800095f216c9da6b6735d10d26df8168b (patch)
tree4c240a0ecdce63f4c48da2da7e5538facdbd86a5 /drivers/ata/libata-scsi.c
parentb92e09bb5bf4db65aeb8ca0094fdd5142ed54451 (diff)
parent9f56eca3aeeab699a7dbfb397661d2eca4430e94 (diff)
Merge branch 'for-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull another libata patch from Tejun Heo: "One more patch from Adam added. It makes libata skip probing for NCQ prio unless the feature is explicitly requested by the user. This is necessary because some controllers lock up after the optional feature is probed" * 'for-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: ata: avoid probing NCQ Prio Support if not explicitly requested
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;
}