summaryrefslogtreecommitdiff
path: root/arch/x86/kernel/pci-dma.c
diff options
context:
space:
mode:
authorGlauber Costa <gcosta@redhat.com>2008-04-08 13:20:55 -0300
committerIngo Molnar <mingo@elte.hu>2008-04-19 19:19:57 +0200
commit8e0c379718ef32967deea55937895bfc9b493dd8 (patch)
tree4176210a3359f4d7421a8b7e0cec29e848e8d68a /arch/x86/kernel/pci-dma.c
parentbca5c09663030bdd18ab1b3ccb6671f663c3345a (diff)
x86: merge dma_supported
The code for both arches are very similar, so this patch merge them. Signed-off-by: Glauber Costa <gcosta@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/pci-dma.c')
-rw-r--r--arch/x86/kernel/pci-dma.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 48cccbe51aa5..7d3bd652c36f 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -14,6 +14,8 @@ EXPORT_SYMBOL(forbid_dac);
const struct dma_mapping_ops *dma_ops;
EXPORT_SYMBOL(dma_ops);
+int iommu_sac_force __read_mostly = 0;
+
#ifdef CONFIG_IOMMU_DEBUG
int panic_on_overflow __read_mostly = 1;
int force_iommu __read_mostly = 1;
@@ -103,6 +105,48 @@ void __init pci_iommu_alloc(void)
}
#endif
+int dma_supported(struct device *dev, u64 mask)
+{
+#ifdef CONFIG_PCI
+ if (mask > 0xffffffff && forbid_dac > 0) {
+ printk(KERN_INFO "PCI: Disallowing DAC for device %s\n",
+ dev->bus_id);
+ return 0;
+ }
+#endif
+
+ if (dma_ops->dma_supported)
+ return dma_ops->dma_supported(dev, mask);
+
+ /* Copied from i386. Doesn't make much sense, because it will
+ only work for pci_alloc_coherent.
+ The caller just has to use GFP_DMA in this case. */
+ if (mask < DMA_24BIT_MASK)
+ return 0;
+
+ /* Tell the device to use SAC when IOMMU force is on. This
+ allows the driver to use cheaper accesses in some cases.
+
+ Problem with this is that if we overflow the IOMMU area and
+ return DAC as fallback address the device may not handle it
+ correctly.
+
+ As a special case some controllers have a 39bit address
+ mode that is as efficient as 32bit (aic79xx). Don't force
+ SAC for these. Assume all masks <= 40 bits are of this
+ type. Normally this doesn't make any difference, but gives
+ more gentle handling of IOMMU overflow. */
+ if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) {
+ printk(KERN_INFO "%s: Force SAC with mask %Lx\n",
+ dev->bus_id, mask);
+ return 0;
+ }
+
+ return 1;
+}
+EXPORT_SYMBOL(dma_supported);
+
+
static int __init pci_iommu_init(void)
{
#ifdef CONFIG_CALGARY_IOMMU