[PATCH] ata: disable auto activate if the controller does not support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Some SSDs (such as SAMSUNG PM863 and SM863) enable auto activate feature
by default. Now libata only send set feature command to enable auto
activate feature if the controller and disk both support this feature.
But when the controller do not support this feature then the data transfer
failed. Fix this by sending set feature command to disable this feature
if the controller does not support it.

Signed-off-by: Jason Yan <yanaijie@xxxxxxxxxx>
Reported-and-tested-by: Zhou Yupeng <zhouyupeng1@xxxxxxxxxx>
---
 drivers/ata/libata-core.c | 54 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 38 insertions(+), 16 deletions(-)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index cf27f1e1871f..72399c2bd3b1 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2278,6 +2278,41 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
 
 }
 
+static inline int ata_dev_config_aa(struct ata_device *dev, struct ata_port *ap,
+				 char **aa_desc)
+{
+	unsigned int err_mask;
+	char *desc;
+	u8 enable;
+
+	if (dev->horkage & ATA_HORKAGE_BROKEN_FPDMA_AA)
+		return 0;
+
+	if (!ata_id_has_fpdma_aa(dev->id))
+		return 0;
+
+	if (ap->flags & ATA_FLAG_FPDMA_AA) {
+		enable = SETFEATURES_SATA_ENABLE;
+		desc = "enable";
+	} else {
+		enable = SETFEATURES_SATA_DISABLE;
+		desc = "disalbe";
+	}
+
+	err_mask = ata_dev_set_feature(dev, enable, SATA_FPDMA_AA);
+	if (err_mask) {
+		ata_dev_err(dev, "failed to %s AA (error_mask=0x%x)\n",
+			    desc, err_mask);
+		if (err_mask != AC_ERR_DEV) {
+			dev->horkage |= ATA_HORKAGE_BROKEN_FPDMA_AA;
+			return -EIO;
+		}
+	} else
+		*aa_desc = ", AA";
+
+	return 0;
+}
+
 static int ata_dev_config_ncq(struct ata_device *dev,
 			       char *desc, size_t desc_sz)
 {
@@ -2299,22 +2334,9 @@ static int ata_dev_config_ncq(struct ata_device *dev,
 		dev->flags |= ATA_DFLAG_NCQ;
 	}
 
-	if (!(dev->horkage & ATA_HORKAGE_BROKEN_FPDMA_AA) &&
-		(ap->flags & ATA_FLAG_FPDMA_AA) &&
-		ata_id_has_fpdma_aa(dev->id)) {
-		err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_ENABLE,
-			SATA_FPDMA_AA);
-		if (err_mask) {
-			ata_dev_err(dev,
-				    "failed to enable AA (error_mask=0x%x)\n",
-				    err_mask);
-			if (err_mask != AC_ERR_DEV) {
-				dev->horkage |= ATA_HORKAGE_BROKEN_FPDMA_AA;
-				return -EIO;
-			}
-		} else
-			aa_desc = ", AA";
-	}
+	err_mask = ata_dev_config_aa(dev, ap, &aa_desc);
+	if (err_mask)
+		return err_mask;
 
 	if (hdepth >= ddepth)
 		snprintf(desc, desc_sz, "NCQ (depth %d)%s", ddepth, aa_desc);
-- 
2.13.6

--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux