PCI: Make ACS quirk implementations more uniform

The ACS quirks differ in needless ways, which makes them look more
different than they really are.

Reorder the ACS flags in order of definitions in the spec:

  PCI_ACS_SV   Source Validation
  PCI_ACS_TB   Translation Blocking
  PCI_ACS_RR   P2P Request Redirect
  PCI_ACS_CR   P2P Completion Redirect
  PCI_ACS_UF   Upstream Forwarding
  PCI_ACS_EC   P2P Egress Control
  PCI_ACS_DT   Direct Translated P2P

(PCIe r5.0, sec 7.7.8.2) and use similar code structure in all.  No
functional change intended.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
Bjorn Helgaas 2019-09-05 17:54:42 -05:00
parent f338bb9f01
commit c8de8ed2dc

View File

@ -4366,18 +4366,18 @@ static bool pci_quirk_cavium_acs_match(struct pci_dev *dev)
static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags)
{
if (!pci_quirk_cavium_acs_match(dev))
return -ENOTTY;
/*
* Cavium root ports don't advertise an ACS capability. However,
* Cavium Root Ports don't advertise an ACS capability. However,
* the RTL internally implements similar protection as if ACS had
* Request Redirection, Completion Redirection, Source Validation,
* Source Validation, Request Redirection, Completion Redirection,
* and Upstream Forwarding features enabled. Assert that the
* hardware implements and enables equivalent ACS functionality for
* these flags.
*/
acs_flags &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_SV | PCI_ACS_UF);
if (!pci_quirk_cavium_acs_match(dev))
return -ENOTTY;
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
return acs_flags ? 0 : 1;
}
@ -4395,7 +4395,7 @@ static int pci_quirk_xgene_acs(struct pci_dev *dev, u16 acs_flags)
}
/*
* Many Intel PCH root ports do provide ACS-like features to disable peer
* Many Intel PCH Root Ports do provide ACS-like features to disable peer
* transactions and validate bus numbers in requests, but do not provide an
* actual PCIe ACS capability. This is the list of device IDs known to fall
* into that category as provided by Intel in Red Hat bugzilla 1037684.
@ -4443,37 +4443,34 @@ static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev)
return false;
}
#define INTEL_PCH_ACS_FLAGS (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV)
#define INTEL_PCH_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags)
{
u16 flags = dev->dev_flags & PCI_DEV_FLAGS_ACS_ENABLED_QUIRK ?
INTEL_PCH_ACS_FLAGS : 0;
if (!pci_quirk_intel_pch_acs_match(dev))
return -ENOTTY;
return acs_flags & ~flags ? 0 : 1;
if (dev->dev_flags & PCI_DEV_FLAGS_ACS_ENABLED_QUIRK)
acs_flags &= ~(INTEL_PCH_ACS_FLAGS);
return acs_flags ? 0 : 1;
}
/*
* These QCOM root ports do provide ACS-like features to disable peer
* These QCOM Root Ports do provide ACS-like features to disable peer
* transactions and validate bus numbers in requests, but do not provide an
* actual PCIe ACS capability. Hardware supports source validation but it
* will report the issue as Completer Abort instead of ACS Violation.
* Hardware doesn't support peer-to-peer and each root port is a root
* complex with unique segment numbers. It is not possible for one root
* port to pass traffic to another root port. All PCIe transactions are
* terminated inside the root port.
* Hardware doesn't support peer-to-peer and each Root Port is a Root
* Complex with unique segment numbers. It is not possible for one Root
* Port to pass traffic to another Root Port. All PCIe transactions are
* terminated inside the Root Port.
*/
static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags)
{
u16 flags = (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV);
int ret = acs_flags & ~flags ? 0 : 1;
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
pci_info(dev, "Using QCOM ACS Quirk (%d)\n", ret);
return ret;
return acs_flags ? 0 : 1;
}
static int pci_quirk_al_acs(struct pci_dev *dev, u16 acs_flags)