PCI: Claim ACS support for AMD southbridge devices
AMD confirmed that peer-to-peer between these devices is not possible. We can therefore claim that they support a subset of ACS. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Donald Dutile <ddutile@redhat.com>
This commit is contained in:
		
							parent
							
								
									83db7e0bdb
								
							
						
					
					
						commit
						15b100dfd1
					
				| @ -3295,11 +3295,61 @@ struct pci_dev *pci_get_dma_source(struct pci_dev *dev) | ||||
| 	return pci_dev_get(dev); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * 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 | ||||
|  * IOMMU in the system.  Multifunction devices that do not support | ||||
|  * peer-to-peer between functions can claim to support a subset of ACS. | ||||
|  * Such devices effectively enable request redirect (RR) and completion | ||||
|  * redirect (CR) since all transactions are redirected to the upstream | ||||
|  * root complex. | ||||
|  * | ||||
|  * http://permalink.gmane.org/gmane.comp.emulators.kvm.devel/94086
 | ||||
|  * http://permalink.gmane.org/gmane.comp.emulators.kvm.devel/94102
 | ||||
|  * http://permalink.gmane.org/gmane.comp.emulators.kvm.devel/99402
 | ||||
|  * | ||||
|  * 1002:4385 SBx00 SMBus Controller | ||||
|  * 1002:439c SB7x0/SB8x0/SB9x0 IDE Controller | ||||
|  * 1002:4383 SBx00 Azalia (Intel HDA) | ||||
|  * 1002:439d SB7x0/SB8x0/SB9x0 LPC host controller | ||||
|  * 1002:4384 SBx00 PCI to PCI Bridge | ||||
|  * 1002:4399 SB7x0/SB8x0/SB9x0 USB OHCI2 Controller | ||||
|  */ | ||||
| static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags) | ||||
| { | ||||
| #ifdef CONFIG_ACPI | ||||
| 	struct acpi_table_header *header = NULL; | ||||
| 	acpi_status status; | ||||
| 
 | ||||
| 	/* Targeting multifunction devices on the SB (appears on root bus) */ | ||||
| 	if (!dev->multifunction || !pci_is_root_bus(dev->bus)) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	/* The IVRS table describes the AMD IOMMU */ | ||||
| 	status = acpi_get_table("IVRS", 0, &header); | ||||
| 	if (ACPI_FAILURE(status)) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	/* Filter out flags not applicable to multifunction */ | ||||
| 	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; | ||||
| #else | ||||
| 	return -ENODEV; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static const struct pci_dev_acs_enabled { | ||||
| 	u16 vendor; | ||||
| 	u16 device; | ||||
| 	int (*acs_enabled)(struct pci_dev *dev, u16 acs_flags); | ||||
| } pci_dev_acs_enabled[] = { | ||||
| 	{ PCI_VENDOR_ID_ATI, 0x4385, pci_quirk_amd_sb_acs }, | ||||
| 	{ PCI_VENDOR_ID_ATI, 0x439c, pci_quirk_amd_sb_acs }, | ||||
| 	{ PCI_VENDOR_ID_ATI, 0x4383, pci_quirk_amd_sb_acs }, | ||||
| 	{ PCI_VENDOR_ID_ATI, 0x439d, pci_quirk_amd_sb_acs }, | ||||
| 	{ PCI_VENDOR_ID_ATI, 0x4384, pci_quirk_amd_sb_acs }, | ||||
| 	{ PCI_VENDOR_ID_ATI, 0x4399, pci_quirk_amd_sb_acs }, | ||||
| 	{ 0 } | ||||
| }; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user