mirror of https://gitee.com/openkylin/linux.git
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);
|
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 {
|
static const struct pci_dev_acs_enabled {
|
||||||
u16 vendor;
|
u16 vendor;
|
||||||
u16 device;
|
u16 device;
|
||||||
int (*acs_enabled)(struct pci_dev *dev, u16 acs_flags);
|
int (*acs_enabled)(struct pci_dev *dev, u16 acs_flags);
|
||||||
} pci_dev_acs_enabled[] = {
|
} 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 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue