Just in case anybody else is in a hurry and needs a workaround, here's a patch (against 2.6.35-rc5) that kludges all the DMAR mappings to point to the first device. Tested with Cardbus (a USB controller) and Firewire, but don't be surprised if it glues your cat to the carpet or something.
Just in case anybody else is in a hurry and needs a workaround, here's a patch (against 2.6.35-rc5) that kludges all the DMAR mappings to point to the first device. Tested with Cardbus (a USB controller) and Firewire, but don't be surprised if it glues your cat to the carpet or something.
--- a/drivers/ pci/intel- iommu.c 2010-07-13 07:55:33.000000000 +1000 pci/intel- iommu.c 2010-08-03 22:19:09.000000000 +1000
+++ b/drivers/
@@ -2560,10 +2560,12 @@
return 0;
}
+struct pci_dev *ricohdev = 0; map_single( struct device *hwdev, phys_addr_t paddr,
+
static dma_addr_t __intel_
size_t size, int dir, u64 dma_mask)
{
- struct pci_dev *pdev = to_pci_dev(hwdev);
+ struct pci_dev *tmp, *pdev = to_pci_dev(hwdev);
struct dmar_domain *domain;
phys_addr_t start_paddr;
struct iova *iova;
@@ -2574,6 +2576,17 @@
BUG_ON(dir == DMA_NONE);
+ tmp = (pdev-> vendor= =0x1180) ? pdev : pdev->bus->self; =0xe822 || =0xe476) ) { domain_ bus_and_ slot(0, tmp->bus->number, tmp->devfn & ~7); no_mapping( hwdev))
+ if (tmp && tmp->vendor==0x1180 &&
+ (tmp->device=
+ tmp->device==0xe230 ||
+ tmp->device==0xe832 ||
+ tmp->device=
+ if (!ricohdev)
+ ricohdev = pci_get_
+ pdev = ricohdev;
+ }
+
if (iommu_
return paddr;
@@ -2716,7 +2729,7 @@
size_t size, enum dma_data_direction dir,
struct dma_attrs *attrs)
{
- struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_dev *tmp, *pdev = to_pci_dev(dev);
struct dmar_domain *domain;
unsigned long start_pfn, last_pfn;
struct iova *iova;
@@ -2724,6 +2737,15 @@
if (iommu_ no_mapping( dev)) vendor= =0x1180) ? pdev : pdev->bus->self; =0xe822 || =0xe476) ) {
return;
+
+ tmp = (pdev->
+ if (tmp && tmp->vendor==0x1180 &&
+ (tmp->device=
+ tmp->device==0xe230 ||
+ tmp->device==0xe832 ||
+ tmp->device=
+ pdev = ricohdev;
+ }
domain = find_domain(pdev);
BUG_ON(!domain);