aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2015-01-13 13:26:50 -0500
committerBjorn Helgaas <bhelgaas@google.com>2015-01-23 16:44:45 -0500
commitd3d2ab43ddae5f958461ac0a9a2b484a68194df5 (patch)
tree60910830d853171b5511653903c53559b9ba768d /drivers/pci/quirks.c
parent6a3763d1734bf133330dc8e246bf794b9e360e8a (diff)
PCI: Add DMA alias quirk for Adaptec 3405
The Adaptec 3405 is actually an Intel 80333 I/O processor where the exposed device at 0e.0 is actually the address translation unit of the I/O processor and a hidden, private device at 01.0 masters the DMA for the device. Create a fixed alias between the exposed and hidden devfn so we can enable the IOMMU. Scenarios like this are potentially likely for any device incorporating this I/O processor, so this little bit of abstraction with the fixed alias table should make future additions trivial. Without this fix, booting a system with the Intel IOMMU enabled and an Adaptec 3405 at 02:0e.0 results in a flood of errors like this: dmar: DRHD: handling fault status reg 3 dmar: DMAR:[DMA Write] Request device [02:01.0] fault addr ffbff000 DMAR:[fault reason 02] Present bit in context entry is clear [bhelgaas: changelog, comment] Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> CC: Adaptec OEM Raid Solutions <aacraid@adaptec.com>
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r--drivers/pci/quirks.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 3fb378aa7c53..45bd8704c99d 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3563,6 +3563,44 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON,
3563 quirk_dma_func1_alias); 3563 quirk_dma_func1_alias);
3564 3564
3565/* 3565/*
3566 * Some devices DMA with the wrong devfn, not just the wrong function.
3567 * quirk_fixed_dma_alias() uses this table to create fixed aliases, where
3568 * the alias is "fixed" and independent of the device devfn.
3569 *
3570 * For example, the Adaptec 3405 is a PCIe card with an Intel 80333 I/O
3571 * processor. To software, this appears as a PCIe-to-PCI/X bridge with a
3572 * single device on the secondary bus. In reality, the single exposed
3573 * device at 0e.0 is the Address Translation Unit (ATU) of the controller
3574 * that provides a bridge to the internal bus of the I/O processor. The
3575 * controller supports private devices, which can be hidden from PCI config
3576 * space. In the case of the Adaptec 3405, a private device at 01.0
3577 * appears to be the DMA engine, which therefore needs to become a DMA
3578 * alias for the device.
3579 */
3580static const struct pci_device_id fixed_dma_alias_tbl[] = {
3581 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285,
3582 PCI_VENDOR_ID_ADAPTEC2, 0x02bb), /* Adaptec 3405 */
3583 .driver_data = PCI_DEVFN(1, 0) },
3584 { 0 }
3585};
3586
3587static void quirk_fixed_dma_alias(struct pci_dev *dev)
3588{
3589 const struct pci_device_id *id;
3590
3591 id = pci_match_id(fixed_dma_alias_tbl, dev);
3592 if (id) {
3593 dev->dma_alias_devfn = id->driver_data;
3594 dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;
3595 dev_info(&dev->dev, "Enabling fixed DMA alias to %02x.%d\n",
3596 PCI_SLOT(dev->dma_alias_devfn),
3597 PCI_FUNC(dev->dma_alias_devfn));
3598 }
3599}
3600
3601DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADAPTEC2, 0x0285, quirk_fixed_dma_alias);
3602
3603/*
3566 * A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in 3604 * A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in
3567 * using the wrong DMA alias for the device. Some of these devices can be 3605 * using the wrong DMA alias for the device. Some of these devices can be
3568 * used as either forward or reverse bridges, so we need to test whether the 3606 * used as either forward or reverse bridges, so we need to test whether the