PCI: Unify ACS quirk desired vs provided checking
Most of the ACS quirks have a similar pattern of: acs_flags &= ~( <controls provided by this device> ); return acs_flags ? 0 : 1; Pull this out into a helper function to simplify the quirks slightly. The helper function is also a convenient place for comments about what the list of ACS controls means. 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:
parent
c8de8ed2dc
commit
7cf2cba43f
@ -4296,6 +4296,24 @@ static void quirk_chelsio_T5_disable_root_port_attributes(struct pci_dev *pdev)
|
|||||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
|
||||||
quirk_chelsio_T5_disable_root_port_attributes);
|
quirk_chelsio_T5_disable_root_port_attributes);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pci_acs_ctrl_enabled - compare desired ACS controls with those provided
|
||||||
|
* by a device
|
||||||
|
* @acs_ctrl_req: Bitmask of desired ACS controls
|
||||||
|
* @acs_ctrl_ena: Bitmask of ACS controls enabled or provided implicitly by
|
||||||
|
* the hardware design
|
||||||
|
*
|
||||||
|
* Return 1 if all ACS controls in the @acs_ctrl_req bitmask are included
|
||||||
|
* in @acs_ctrl_ena, i.e., the device provides all the access controls the
|
||||||
|
* caller desires. Return 0 otherwise.
|
||||||
|
*/
|
||||||
|
static int pci_acs_ctrl_enabled(u16 acs_ctrl_req, u16 acs_ctrl_ena)
|
||||||
|
{
|
||||||
|
if ((acs_ctrl_req & acs_ctrl_ena) == acs_ctrl_req)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AMD has indicated that the devices below do not support peer-to-peer
|
* AMD has indicated that the devices below do not support peer-to-peer
|
||||||
* in any system where they are found in the southbridge with an AMD
|
* in any system where they are found in the southbridge with an AMD
|
||||||
@ -4339,7 +4357,7 @@ static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags)
|
|||||||
/* Filter out flags not applicable to multifunction */
|
/* Filter out flags not applicable to multifunction */
|
||||||
acs_flags &= (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC | PCI_ACS_DT);
|
acs_flags &= (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC | PCI_ACS_DT);
|
||||||
|
|
||||||
return acs_flags & ~(PCI_ACS_RR | PCI_ACS_CR) ? 0 : 1;
|
return pci_acs_ctrl_enabled(acs_flags, PCI_ACS_RR | PCI_ACS_CR);
|
||||||
#else
|
#else
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
#endif
|
#endif
|
||||||
@ -4377,9 +4395,8 @@ static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags)
|
|||||||
* hardware implements and enables equivalent ACS functionality for
|
* hardware implements and enables equivalent ACS functionality for
|
||||||
* these flags.
|
* these flags.
|
||||||
*/
|
*/
|
||||||
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
|
return pci_acs_ctrl_enabled(acs_flags,
|
||||||
|
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
|
||||||
return acs_flags ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pci_quirk_xgene_acs(struct pci_dev *dev, u16 acs_flags)
|
static int pci_quirk_xgene_acs(struct pci_dev *dev, u16 acs_flags)
|
||||||
@ -4389,9 +4406,8 @@ static int pci_quirk_xgene_acs(struct pci_dev *dev, u16 acs_flags)
|
|||||||
* transactions with others, allowing masking out these bits as if they
|
* transactions with others, allowing masking out these bits as if they
|
||||||
* were unimplemented in the ACS capability.
|
* were unimplemented in the ACS capability.
|
||||||
*/
|
*/
|
||||||
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
|
return pci_acs_ctrl_enabled(acs_flags,
|
||||||
|
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
|
||||||
return acs_flags ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4443,17 +4459,16 @@ static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#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)
|
static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags)
|
||||||
{
|
{
|
||||||
if (!pci_quirk_intel_pch_acs_match(dev))
|
if (!pci_quirk_intel_pch_acs_match(dev))
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
|
||||||
if (dev->dev_flags & PCI_DEV_FLAGS_ACS_ENABLED_QUIRK)
|
if (dev->dev_flags & PCI_DEV_FLAGS_ACS_ENABLED_QUIRK)
|
||||||
acs_flags &= ~(INTEL_PCH_ACS_FLAGS);
|
return pci_acs_ctrl_enabled(acs_flags,
|
||||||
|
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
|
||||||
|
|
||||||
return acs_flags ? 0 : 1;
|
return pci_acs_ctrl_enabled(acs_flags, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4468,9 +4483,8 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags)
|
|||||||
*/
|
*/
|
||||||
static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags)
|
static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags)
|
||||||
{
|
{
|
||||||
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
|
return pci_acs_ctrl_enabled(acs_flags,
|
||||||
|
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
|
||||||
return acs_flags ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pci_quirk_al_acs(struct pci_dev *dev, u16 acs_flags)
|
static int pci_quirk_al_acs(struct pci_dev *dev, u16 acs_flags)
|
||||||
@ -4571,7 +4585,7 @@ static int pci_quirk_intel_spt_pch_acs(struct pci_dev *dev, u16 acs_flags)
|
|||||||
|
|
||||||
pci_read_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, &ctrl);
|
pci_read_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, &ctrl);
|
||||||
|
|
||||||
return acs_flags & ~ctrl ? 0 : 1;
|
return pci_acs_ctrl_enabled(acs_flags, ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, u16 acs_flags)
|
static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, u16 acs_flags)
|
||||||
@ -4585,10 +4599,9 @@ static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, u16 acs_flags)
|
|||||||
* perform peer-to-peer with other functions, allowing us to mask out
|
* perform peer-to-peer with other functions, allowing us to mask out
|
||||||
* these bits as if they were unimplemented in the ACS capability.
|
* these bits as if they were unimplemented in the ACS capability.
|
||||||
*/
|
*/
|
||||||
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
|
return pci_acs_ctrl_enabled(acs_flags,
|
||||||
|
PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
|
||||||
PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT);
|
PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT);
|
||||||
|
|
||||||
return acs_flags ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags)
|
static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags)
|
||||||
@ -4599,9 +4612,8 @@ static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags)
|
|||||||
* Allow each Root Port to be in a separate IOMMU group by masking
|
* Allow each Root Port to be in a separate IOMMU group by masking
|
||||||
* SV/RR/CR/UF bits.
|
* SV/RR/CR/UF bits.
|
||||||
*/
|
*/
|
||||||
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
|
return pci_acs_ctrl_enabled(acs_flags,
|
||||||
|
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
|
||||||
return acs_flags ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pci_dev_acs_enabled {
|
static const struct pci_dev_acs_enabled {
|
||||||
@ -4703,6 +4715,17 @@ static const struct pci_dev_acs_enabled {
|
|||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pci_dev_specific_acs_enabled - check whether device provides ACS controls
|
||||||
|
* @dev: PCI device
|
||||||
|
* @acs_flags: Bitmask of desired ACS controls
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* -ENOTTY: No quirk applies to this device; we can't tell whether the
|
||||||
|
* device provides the desired controls
|
||||||
|
* 0: Device does not provide all the desired controls
|
||||||
|
* >0: Device provides all the controls in @acs_flags
|
||||||
|
*/
|
||||||
int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags)
|
int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags)
|
||||||
{
|
{
|
||||||
const struct pci_dev_acs_enabled *i;
|
const struct pci_dev_acs_enabled *i;
|
||||||
|
Loading…
Reference in New Issue
Block a user