Messages in this thread Patch in this message | | | From | Joerg Roedel <> | Subject | [PATCH 9/9] x86/iommu: use dma_ops_list in get_dma_ops | Date | Mon, 22 Sep 2008 20:21:21 +0200 |
| |
This patch enables stackable dma_ops on x86. To do this, it also enables the per-device dma_ops on i386.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> --- arch/x86/kernel/pci-dma.c | 26 ++++++++++++++++++++++++++ include/asm-x86/device.h | 6 +++--- include/asm-x86/dma-mapping.h | 14 +++++++------- 3 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index b990fb6..2e517c2 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -82,6 +82,32 @@ void x86_register_dma_ops(struct dma_mapping_ops *ops, write_unlock_irqrestore(&dma_ops_list_lock, flags); } +struct dma_mapping_ops *find_dma_ops_for_device(struct device *dev) +{ + int i; + unsigned long flags; + struct dma_mapping_ops *entry, *ops = NULL; + + read_lock_irqsave(&dma_ops_list_lock, flags); + + for (i = 0; i < DMA_OPS_TYPE_MAX; ++i) + list_for_each_entry(entry, &dma_ops_list[i], list) { + if (!entry->device_supported) + continue; + if (entry->device_supported(dev)) { + ops = entry; + goto out; + } + } +out: + read_unlock_irqrestore(&dma_ops_list_lock, flags); + + BUG_ON(ops == NULL); + + return ops; +} +EXPORT_SYMBOL(find_dma_ops_for_device); + int dma_set_mask(struct device *dev, u64 mask) { if (!dev->dma_mask || !dma_supported(dev, mask)) diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h index 3c034f4..9ed12e3 100644 --- a/include/asm-x86/device.h +++ b/include/asm-x86/device.h @@ -5,9 +5,9 @@ struct dev_archdata { #ifdef CONFIG_ACPI void *acpi_handle; #endif -#ifdef CONFIG_X86_64 -struct dma_mapping_ops *dma_ops; -#endif + + struct dma_mapping_ops *dma_ops; + #ifdef CONFIG_DMAR void *iommu; /* hook for IOMMU specific extension */ #endif diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h index 128786b..83d6d7f 100644 --- a/include/asm-x86/dma-mapping.h +++ b/include/asm-x86/dma-mapping.h @@ -82,19 +82,19 @@ enum dma_ops_driver_type { extern void x86_register_dma_ops(struct dma_mapping_ops *ops, enum dma_ops_driver_type type); +extern struct dma_mapping_ops *find_dma_ops_for_device(struct device *dev); extern struct dma_mapping_ops *dma_ops; static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) { -#ifdef CONFIG_X86_32 - return dma_ops; -#else - if (unlikely(!dev) || !dev->archdata.dma_ops) + if (unlikely(!dev)) return dma_ops; - else - return dev->archdata.dma_ops; -#endif + + if (unlikely(!dev->archdata.dma_ops)) + dev->archdata.dma_ops = find_dma_ops_for_device(dev); + + return dev->archdata.dma_ops; } /* Make sure we keep the same behaviour */ -- 1.5.6.4
| |