Commit 33e6654e authored by leoliu-oc's avatar leoliu-oc
Browse files

ata: libata: disabling PhyRdy Change Interrupt based on actual LPM capability

zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8WYN1


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: default avatarleoliu-oc <leoliu-oc@zhaoxin.com>
parent 87cf6952
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3371,6 +3371,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
			  struct ata_device **r_failed_dev)
{
	struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL;
	struct device *device = ap ? ap->host->dev : NULL;
	struct pci_dev *pdev = (!device || !dev_is_pci(device)) ? NULL : to_pci_dev(device);
	struct ata_eh_context *ehc = &link->eh_context;
	struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
	enum ata_lpm_policy old_policy = link->lpm_policy;
@@ -3379,6 +3381,11 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
	unsigned int err_mask;
	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_NO_PART | ATA_HOST_NO_SSC | ATA_HOST_NO_DEVSLP)))
		link->flags |= ATA_LFLAG_NO_LPM;

	/* if the link or host doesn't do LPM, noop */
	if (!IS_ENABLED(CONFIG_SATA_HOST) ||
	    (link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm))