Merge branch 'for-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Dec 2016 23:30:50 +0000 (15:30 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Dec 2016 23:30:50 +0000 (15:30 -0800)
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

1  2 
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c

@@@ -129,7 -129,7 +129,7 @@@ static int ata_force_tbl_size
  static char ata_force_param_buf[PAGE_SIZE] __initdata;
  /* param_buf is thrown away after initialization, disallow read */
  module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0);
 -MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/kernel-parameters.txt for details)");
 +MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/admin-guide/kernel-parameters.rst for details)");
  
  static int atapi_enabled = 1;
  module_param(atapi_enabled, int, 0444);
@@@ -787,7 -787,7 +787,7 @@@ int ata_build_rw_tf(struct ata_taskfil
                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 +2168,11 @@@ static void ata_dev_config_ncq_prio(str
        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,
                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");
+       }
  
  }
  
@@@ -272,7 -272,8 +272,8 @@@ DEVICE_ATTR(unload_heads, S_IRUGO | S_I
  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 +306,6 @@@ static ssize_t ata_ncq_prio_enable_stor
        struct ata_port *ap;
        struct ata_device *dev;
        long int input;
-       unsigned long flags;
        int rc;
  
        rc = kstrtol(buf, 10, &input);
                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;
  }
  
@@@ -1163,7 -1167,7 +1167,7 @@@ static void ata_gen_passthru_sense(stru
                desc[1] = tf->command; /* status */
                desc[2] = tf->device;
                desc[3] = tf->nsect;
 -              desc[0] = 0;
 +              desc[7] = 0;
                if (tf->flags & ATA_TFLAG_LBA48)  {
                        desc[8] |= 0x80;
                        if (tf->hob_nsect)
@@@ -1234,7 -1238,6 +1238,7 @@@ static void ata_scsi_sdev_config(struc
  {
        sdev->use_10_for_rw = 1;
        sdev->use_10_for_ms = 1;
 +      sdev->no_write_same = 1;
  
        /* Schedule policy is determined by ->qc_defer() callback and
         * it needs to see every deferred qc.  Set dev_blocked to 1 to