提交 f83af24f 编写于 作者: L LeoLiu-oc 提交者: Zheng Zengkai

ata: Add support for disabling PhyRdy Change Interrupt based on actual LPM capability

zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I40QDN
CVE: NA

----------------------------------------------------------------

The ahci spec mentions that PhyRdy Change Interrupt and Link Power
Management (LPM) do not coexist. However, before enabling LPM,
the driver did not check whether the host supports LPM,
but directly disabled PhyRdy Change Interrupt. Increase the
judgment on the actual support of LPM, and disable PhyRdy Change
Interrupt only when it is supported.
Signed-off-by: NLeoLiu-oc <LeoLiu-oc@zhaoxin.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Acked-by: NJackie Liu <liuyun01@kylinos.cn>
Reviewed-by: NJason Yan <yanaijie@huawei.com>
上级 abe9e1a8
...@@ -1881,6 +1881,17 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1881,6 +1881,17 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
else else
dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n"); dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n");
if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) {
if (hpriv->cap & HOST_CAP_PART)
host->flags |= ATA_HOST_PART;
if (hpriv->cap & HOST_CAP_SSC)
host->flags |= ATA_HOST_SSC;
if (hpriv->cap2 & HOST_CAP2_SDS)
host->flags |= ATA_HOST_DEVSLP;
}
if (pi.flags & ATA_FLAG_EM) if (pi.flags & ATA_FLAG_EM)
ahci_reset_em(host); ahci_reset_em(host);
......
...@@ -3237,6 +3237,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, ...@@ -3237,6 +3237,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
struct ata_device **r_failed_dev) struct ata_device **r_failed_dev)
{ {
struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL; struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL;
struct device *device = ap->host->dev;
struct pci_dev *pdev = (!device || !dev_is_pci(device)) ? NULL : to_pci_dev(device);
struct ata_eh_context *ehc = &link->eh_context; struct ata_eh_context *ehc = &link->eh_context;
struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
enum ata_lpm_policy old_policy = link->lpm_policy; enum ata_lpm_policy old_policy = link->lpm_policy;
...@@ -3245,6 +3247,11 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, ...@@ -3245,6 +3247,11 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
unsigned int err_mask; unsigned int err_mask;
int rc; int rc;
/* if controller does not support lpm, then sets no LPM flags*/
if ((pdev && pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) &&
!(ap->host->flags & (ATA_HOST_PART | ATA_HOST_SSC | ATA_HOST_DEVSLP)))
link->flags |= ATA_LFLAG_NO_LPM;
/* if the link or host doesn't do LPM, noop */ /* if the link or host doesn't do LPM, noop */
if (!IS_ENABLED(CONFIG_SATA_HOST) || if (!IS_ENABLED(CONFIG_SATA_HOST) ||
(link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) (link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm))
......
...@@ -260,6 +260,10 @@ enum { ...@@ -260,6 +260,10 @@ enum {
ATA_HOST_PARALLEL_SCAN = (1 << 2), /* Ports on this host can be scanned in parallel */ ATA_HOST_PARALLEL_SCAN = (1 << 2), /* Ports on this host can be scanned in parallel */
ATA_HOST_IGNORE_ATA = (1 << 3), /* Ignore ATA devices on this host. */ ATA_HOST_IGNORE_ATA = (1 << 3), /* Ignore ATA devices on this host. */
ATA_HOST_PART = (1 << 4), /* Host support partial.*/
ATA_HOST_SSC = (1 << 5), /* Host support slumber.*/
ATA_HOST_DEVSLP = (1 << 6), /* Host support devslp.*/
/* bits 24:31 of host->flags are reserved for LLD specific flags */ /* bits 24:31 of host->flags are reserved for LLD specific flags */
/* various lengths of time */ /* various lengths of time */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册