mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									6a3763d173
								
							
						
					
					
						commit
						d3d2ab43dd
					
				
					 1 changed files with 38 additions and 0 deletions
				
			
		| 
						 | 
					@ -3562,6 +3562,44 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON,
 | 
				
			||||||
			 PCI_DEVICE_ID_JMICRON_JMB388_ESD,
 | 
								 PCI_DEVICE_ID_JMICRON_JMB388_ESD,
 | 
				
			||||||
			 quirk_dma_func1_alias);
 | 
								 quirk_dma_func1_alias);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Some devices DMA with the wrong devfn, not just the wrong function.
 | 
				
			||||||
 | 
					 * quirk_fixed_dma_alias() uses this table to create fixed aliases, where
 | 
				
			||||||
 | 
					 * the alias is "fixed" and independent of the device devfn.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * For example, the Adaptec 3405 is a PCIe card with an Intel 80333 I/O
 | 
				
			||||||
 | 
					 * processor.  To software, this appears as a PCIe-to-PCI/X bridge with a
 | 
				
			||||||
 | 
					 * single device on the secondary bus.  In reality, the single exposed
 | 
				
			||||||
 | 
					 * device at 0e.0 is the Address Translation Unit (ATU) of the controller
 | 
				
			||||||
 | 
					 * that provides a bridge to the internal bus of the I/O processor.  The
 | 
				
			||||||
 | 
					 * controller supports private devices, which can be hidden from PCI config
 | 
				
			||||||
 | 
					 * space.  In the case of the Adaptec 3405, a private device at 01.0
 | 
				
			||||||
 | 
					 * appears to be the DMA engine, which therefore needs to become a DMA
 | 
				
			||||||
 | 
					 * alias for the device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static const struct pci_device_id fixed_dma_alias_tbl[] = {
 | 
				
			||||||
 | 
						{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285,
 | 
				
			||||||
 | 
								 PCI_VENDOR_ID_ADAPTEC2, 0x02bb), /* Adaptec 3405 */
 | 
				
			||||||
 | 
						  .driver_data = PCI_DEVFN(1, 0) },
 | 
				
			||||||
 | 
						{ 0 }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void quirk_fixed_dma_alias(struct pci_dev *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct pci_device_id *id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						id = pci_match_id(fixed_dma_alias_tbl, dev);
 | 
				
			||||||
 | 
						if (id) {
 | 
				
			||||||
 | 
							dev->dma_alias_devfn = id->driver_data;
 | 
				
			||||||
 | 
							dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;
 | 
				
			||||||
 | 
							dev_info(&dev->dev, "Enabling fixed DMA alias to %02x.%d\n",
 | 
				
			||||||
 | 
								 PCI_SLOT(dev->dma_alias_devfn),
 | 
				
			||||||
 | 
								 PCI_FUNC(dev->dma_alias_devfn));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADAPTEC2, 0x0285, quirk_fixed_dma_alias);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in
 | 
					 * A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in
 | 
				
			||||||
 * using the wrong DMA alias for the device.  Some of these devices can be
 | 
					 * using the wrong DMA alias for the device.  Some of these devices can be
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue