Merge tag 'omap-for-v3.16/l3-noc-signed' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / drivers / ata / libata-scsi.c
index 377eb889f555dd2029c46a01254a3a204744ac81..ef8567de6a7515b45631f4a06f3447fe0604f0b3 100644 (file)
@@ -111,12 +111,14 @@ static const char *ata_lpm_policy_names[] = {
        [ATA_LPM_MIN_POWER]     = "min_power",
 };
 
-static ssize_t ata_scsi_lpm_store(struct device *dev,
+static ssize_t ata_scsi_lpm_store(struct device *device,
                                  struct device_attribute *attr,
                                  const char *buf, size_t count)
 {
-       struct Scsi_Host *shost = class_to_shost(dev);
+       struct Scsi_Host *shost = class_to_shost(device);
        struct ata_port *ap = ata_shost_to_port(shost);
+       struct ata_link *link;
+       struct ata_device *dev;
        enum ata_lpm_policy policy;
        unsigned long flags;
 
@@ -132,10 +134,20 @@ static ssize_t ata_scsi_lpm_store(struct device *dev,
                return -EINVAL;
 
        spin_lock_irqsave(ap->lock, flags);
+
+       ata_for_each_link(link, ap, EDGE) {
+               ata_for_each_dev(dev, &ap->link, ENABLED) {
+                       if (dev->horkage & ATA_HORKAGE_NOLPM) {
+                               count = -EOPNOTSUPP;
+                               goto out_unlock;
+                       }
+               }
+       }
+
        ap->target_lpm_policy = policy;
        ata_port_schedule_eh(ap);
+out_unlock:
        spin_unlock_irqrestore(ap->lock, flags);
-
        return count;
 }