From 43392d05694299602d8d1784d813f079d372178d Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Mon, 18 Feb 2019 16:04:05 +0800 Subject: [PATCH] ata: disable auto activate if controller do not support euler inclusion category: bugfix bugzilla: 7718 CVE: NA --------------------------- Some SSDs (such as SAMSUNG PM863 or SM863) enabled auto activate but when the controller do not support then the data transfer failed. Fix this by sending set feature command to disable the disk's auto activate feature. Signed-off-by: Jason Yan CC: Zhou Yupeng Signed-off-by: Zhen Lei [yan: cherry-picked from kernel-4.1] Signed-off-by: Jason Yan Reviewed-by: zhengbin Signed-off-by: Yang Yingliang --- drivers/ata/libata-core.c | 53 +++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index da8c63103acc..15ad766f1cf3 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2266,7 +2266,41 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev) dev->flags &= ~ATA_DFLAG_NCQ_PRIO; ata_dev_dbg(dev, "SATA page does not support priority\n"); } +} + +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, @@ -2290,22 +2324,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); -- GitLab