Skip to content

Commit 7cf2cba

Browse files
committed
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 <[email protected]> Reviewed-by: Logan Gunthorpe <[email protected]> Reviewed-by: Alex Williamson <[email protected]>
1 parent c8de8ed commit 7cf2cba

File tree

1 file changed

+45
-22
lines changed

1 file changed

+45
-22
lines changed

drivers/pci/quirks.c

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4296,6 +4296,24 @@ static void quirk_chelsio_T5_disable_root_port_attributes(struct pci_dev *pdev)
42964296
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
42974297
quirk_chelsio_T5_disable_root_port_attributes);
42984298

4299+
/*
4300+
* pci_acs_ctrl_enabled - compare desired ACS controls with those provided
4301+
* by a device
4302+
* @acs_ctrl_req: Bitmask of desired ACS controls
4303+
* @acs_ctrl_ena: Bitmask of ACS controls enabled or provided implicitly by
4304+
* the hardware design
4305+
*
4306+
* Return 1 if all ACS controls in the @acs_ctrl_req bitmask are included
4307+
* in @acs_ctrl_ena, i.e., the device provides all the access controls the
4308+
* caller desires. Return 0 otherwise.
4309+
*/
4310+
static int pci_acs_ctrl_enabled(u16 acs_ctrl_req, u16 acs_ctrl_ena)
4311+
{
4312+
if ((acs_ctrl_req & acs_ctrl_ena) == acs_ctrl_req)
4313+
return 1;
4314+
return 0;
4315+
}
4316+
42994317
/*
43004318
* AMD has indicated that the devices below do not support peer-to-peer
43014319
* 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)
43394357
/* Filter out flags not applicable to multifunction */
43404358
acs_flags &= (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC | PCI_ACS_DT);
43414359

4342-
return acs_flags & ~(PCI_ACS_RR | PCI_ACS_CR) ? 0 : 1;
4360+
return pci_acs_ctrl_enabled(acs_flags, PCI_ACS_RR | PCI_ACS_CR);
43434361
#else
43444362
return -ENODEV;
43454363
#endif
@@ -4377,9 +4395,8 @@ static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags)
43774395
* hardware implements and enables equivalent ACS functionality for
43784396
* these flags.
43794397
*/
4380-
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
4381-
4382-
return acs_flags ? 0 : 1;
4398+
return pci_acs_ctrl_enabled(acs_flags,
4399+
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
43834400
}
43844401

43854402
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)
43894406
* transactions with others, allowing masking out these bits as if they
43904407
* were unimplemented in the ACS capability.
43914408
*/
4392-
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
4393-
4394-
return acs_flags ? 0 : 1;
4409+
return pci_acs_ctrl_enabled(acs_flags,
4410+
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
43954411
}
43964412

43974413
/*
@@ -4443,17 +4459,16 @@ static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev)
44434459
return false;
44444460
}
44454461

4446-
#define INTEL_PCH_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
4447-
44484462
static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags)
44494463
{
44504464
if (!pci_quirk_intel_pch_acs_match(dev))
44514465
return -ENOTTY;
44524466

44534467
if (dev->dev_flags & PCI_DEV_FLAGS_ACS_ENABLED_QUIRK)
4454-
acs_flags &= ~(INTEL_PCH_ACS_FLAGS);
4468+
return pci_acs_ctrl_enabled(acs_flags,
4469+
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
44554470

4456-
return acs_flags ? 0 : 1;
4471+
return pci_acs_ctrl_enabled(acs_flags, 0);
44574472
}
44584473

44594474
/*
@@ -4468,9 +4483,8 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags)
44684483
*/
44694484
static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags)
44704485
{
4471-
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
4472-
4473-
return acs_flags ? 0 : 1;
4486+
return pci_acs_ctrl_enabled(acs_flags,
4487+
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
44744488
}
44754489

44764490
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)
45714585

45724586
pci_read_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, &ctrl);
45734587

4574-
return acs_flags & ~ctrl ? 0 : 1;
4588+
return pci_acs_ctrl_enabled(acs_flags, ctrl);
45754589
}
45764590

45774591
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)
45854599
* perform peer-to-peer with other functions, allowing us to mask out
45864600
* these bits as if they were unimplemented in the ACS capability.
45874601
*/
4588-
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
4589-
PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT);
4590-
4591-
return acs_flags ? 0 : 1;
4602+
return pci_acs_ctrl_enabled(acs_flags,
4603+
PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
4604+
PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT);
45924605
}
45934606

45944607
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)
45994612
* Allow each Root Port to be in a separate IOMMU group by masking
46004613
* SV/RR/CR/UF bits.
46014614
*/
4602-
acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
4603-
4604-
return acs_flags ? 0 : 1;
4615+
return pci_acs_ctrl_enabled(acs_flags,
4616+
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
46054617
}
46064618

46074619
static const struct pci_dev_acs_enabled {
@@ -4703,6 +4715,17 @@ static const struct pci_dev_acs_enabled {
47034715
{ 0 }
47044716
};
47054717

4718+
/*
4719+
* pci_dev_specific_acs_enabled - check whether device provides ACS controls
4720+
* @dev: PCI device
4721+
* @acs_flags: Bitmask of desired ACS controls
4722+
*
4723+
* Returns:
4724+
* -ENOTTY: No quirk applies to this device; we can't tell whether the
4725+
* device provides the desired controls
4726+
* 0: Device does not provide all the desired controls
4727+
* >0: Device provides all the controls in @acs_flags
4728+
*/
47064729
int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags)
47074730
{
47084731
const struct pci_dev_acs_enabled *i;

0 commit comments

Comments
 (0)