@@ -4296,6 +4296,24 @@ static void quirk_chelsio_T5_disable_root_port_attributes(struct pci_dev *pdev)
4296
4296
DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_CHELSIO , PCI_ANY_ID ,
4297
4297
quirk_chelsio_T5_disable_root_port_attributes );
4298
4298
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
+
4299
4317
/*
4300
4318
* AMD has indicated that the devices below do not support peer-to-peer
4301
4319
* 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)
4339
4357
/* Filter out flags not applicable to multifunction */
4340
4358
acs_flags &= (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC | PCI_ACS_DT );
4341
4359
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 );
4343
4361
#else
4344
4362
return - ENODEV ;
4345
4363
#endif
@@ -4377,9 +4395,8 @@ static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags)
4377
4395
* hardware implements and enables equivalent ACS functionality for
4378
4396
* these flags.
4379
4397
*/
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 );
4383
4400
}
4384
4401
4385
4402
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)
4389
4406
* transactions with others, allowing masking out these bits as if they
4390
4407
* were unimplemented in the ACS capability.
4391
4408
*/
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 );
4395
4411
}
4396
4412
4397
4413
/*
@@ -4443,17 +4459,16 @@ static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev)
4443
4459
return false;
4444
4460
}
4445
4461
4446
- #define INTEL_PCH_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
4447
-
4448
4462
static int pci_quirk_intel_pch_acs (struct pci_dev * dev , u16 acs_flags )
4449
4463
{
4450
4464
if (!pci_quirk_intel_pch_acs_match (dev ))
4451
4465
return - ENOTTY ;
4452
4466
4453
4467
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 );
4455
4470
4456
- return acs_flags ? 0 : 1 ;
4471
+ return pci_acs_ctrl_enabled ( acs_flags , 0 ) ;
4457
4472
}
4458
4473
4459
4474
/*
@@ -4468,9 +4483,8 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags)
4468
4483
*/
4469
4484
static int pci_quirk_qcom_rp_acs (struct pci_dev * dev , u16 acs_flags )
4470
4485
{
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 );
4474
4488
}
4475
4489
4476
4490
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)
4571
4585
4572
4586
pci_read_config_dword (dev , pos + INTEL_SPT_ACS_CTRL , & ctrl );
4573
4587
4574
- return acs_flags & ~ ctrl ? 0 : 1 ;
4588
+ return pci_acs_ctrl_enabled ( acs_flags , ctrl ) ;
4575
4589
}
4576
4590
4577
4591
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)
4585
4599
* perform peer-to-peer with other functions, allowing us to mask out
4586
4600
* these bits as if they were unimplemented in the ACS capability.
4587
4601
*/
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 );
4592
4605
}
4593
4606
4594
4607
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)
4599
4612
* Allow each Root Port to be in a separate IOMMU group by masking
4600
4613
* SV/RR/CR/UF bits.
4601
4614
*/
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 );
4605
4617
}
4606
4618
4607
4619
static const struct pci_dev_acs_enabled {
@@ -4703,6 +4715,17 @@ static const struct pci_dev_acs_enabled {
4703
4715
{ 0 }
4704
4716
};
4705
4717
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
+ */
4706
4729
int pci_dev_specific_acs_enabled (struct pci_dev * dev , u16 acs_flags )
4707
4730
{
4708
4731
const struct pci_dev_acs_enabled * i ;
0 commit comments