diff options
author | Glauber Costa <gcosta@redhat.com> | 2008-04-08 12:20:55 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-19 13:19:57 -0400 |
commit | 8e0c379718ef32967deea55937895bfc9b493dd8 (patch) | |
tree | 4176210a3359f4d7421a8b7e0cec29e848e8d68a /arch | |
parent | bca5c09663030bdd18ab1b3ccb6671f663c3345a (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')
-rw-r--r-- | arch/x86/kernel/pci-dma.c | 44 | ||||
-rw-r--r-- | arch/x86/kernel/pci-dma_32.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/pci-dma_64.c | 44 |
3 files changed, 45 insertions, 67 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); | |||
14 | const struct dma_mapping_ops *dma_ops; | 14 | const struct dma_mapping_ops *dma_ops; |
15 | EXPORT_SYMBOL(dma_ops); | 15 | EXPORT_SYMBOL(dma_ops); |
16 | 16 | ||
17 | int iommu_sac_force __read_mostly = 0; | ||
18 | |||
17 | #ifdef CONFIG_IOMMU_DEBUG | 19 | #ifdef CONFIG_IOMMU_DEBUG |
18 | int panic_on_overflow __read_mostly = 1; | 20 | int panic_on_overflow __read_mostly = 1; |
19 | int force_iommu __read_mostly = 1; | 21 | int force_iommu __read_mostly = 1; |
@@ -103,6 +105,48 @@ void __init pci_iommu_alloc(void) | |||
103 | } | 105 | } |
104 | #endif | 106 | #endif |
105 | 107 | ||
108 | int dma_supported(struct device *dev, u64 mask) | ||
109 | { | ||
110 | #ifdef CONFIG_PCI | ||
111 | if (mask > 0xffffffff && forbid_dac > 0) { | ||
112 | printk(KERN_INFO "PCI: Disallowing DAC for device %s\n", | ||
113 | dev->bus_id); | ||
114 | return 0; | ||
115 | } | ||
116 | #endif | ||
117 | |||
118 | if (dma_ops->dma_supported) | ||
119 | return dma_ops->dma_supported(dev, mask); | ||
120 | |||
121 | /* Copied from i386. Doesn't make much sense, because it will | ||
122 | only work for pci_alloc_coherent. | ||
123 | The caller just has to use GFP_DMA in this case. */ | ||
124 | if (mask < DMA_24BIT_MASK) | ||
125 | return 0; | ||
126 | |||
127 | /* Tell the device to use SAC when IOMMU force is on. This | ||
128 | allows the driver to use cheaper accesses in some cases. | ||
129 | |||
130 | Problem with this is that if we overflow the IOMMU area and | ||
131 | return DAC as fallback address the device may not handle it | ||
132 | correctly. | ||
133 | |||
134 | As a special case some controllers have a 39bit address | ||
135 | mode that is as efficient as 32bit (aic79xx). Don't force | ||
136 | SAC for these. Assume all masks <= 40 bits are of this | ||
137 | type. Normally this doesn't make any difference, but gives | ||
138 | more gentle handling of IOMMU overflow. */ | ||
139 | if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) { | ||
140 | printk(KERN_INFO "%s: Force SAC with mask %Lx\n", | ||
141 | dev->bus_id, mask); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | return 1; | ||
146 | } | ||
147 | EXPORT_SYMBOL(dma_supported); | ||
148 | |||
149 | |||
106 | static int __init pci_iommu_init(void) | 150 | static int __init pci_iommu_init(void) |
107 | { | 151 | { |
108 | #ifdef CONFIG_CALGARY_IOMMU | 152 | #ifdef CONFIG_CALGARY_IOMMU |
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c index 6543bb30b65d..1d4091af4417 100644 --- a/arch/x86/kernel/pci-dma_32.c +++ b/arch/x86/kernel/pci-dma_32.c | |||
@@ -155,30 +155,6 @@ void *dma_mark_declared_memory_occupied(struct device *dev, | |||
155 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); | 155 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); |
156 | 156 | ||
157 | #ifdef CONFIG_PCI | 157 | #ifdef CONFIG_PCI |
158 | /* Many VIA bridges seem to corrupt data for DAC. Disable it here */ | ||
159 | |||
160 | int | ||
161 | dma_supported(struct device *dev, u64 mask) | ||
162 | { | ||
163 | /* | ||
164 | * we fall back to GFP_DMA when the mask isn't all 1s, | ||
165 | * so we can't guarantee allocations that must be | ||
166 | * within a tighter range than GFP_DMA.. | ||
167 | */ | ||
168 | if (mask < 0x00ffffff) | ||
169 | return 0; | ||
170 | |||
171 | /* Work around chipset bugs */ | ||
172 | if (forbid_dac > 0 && mask > 0xffffffffULL) | ||
173 | return 0; | ||
174 | |||
175 | if (dma_ops->dma_supported) | ||
176 | return dma_ops->dma_supported(dev, mask); | ||
177 | |||
178 | return 1; | ||
179 | } | ||
180 | EXPORT_SYMBOL(dma_supported); | ||
181 | |||
182 | static int check_iommu(char *s) | 158 | static int check_iommu(char *s) |
183 | { | 159 | { |
184 | if (!strcmp(s, "usedac")) { | 160 | if (!strcmp(s, "usedac")) { |
diff --git a/arch/x86/kernel/pci-dma_64.c b/arch/x86/kernel/pci-dma_64.c index 7820675a688a..c80da76e7e61 100644 --- a/arch/x86/kernel/pci-dma_64.c +++ b/arch/x86/kernel/pci-dma_64.c | |||
@@ -24,7 +24,7 @@ EXPORT_SYMBOL(bad_dma_address); | |||
24 | int iommu_bio_merge __read_mostly = 0; | 24 | int iommu_bio_merge __read_mostly = 0; |
25 | EXPORT_SYMBOL(iommu_bio_merge); | 25 | EXPORT_SYMBOL(iommu_bio_merge); |
26 | 26 | ||
27 | static int iommu_sac_force __read_mostly = 0; | 27 | extern int iommu_sac_force; |
28 | 28 | ||
29 | int no_iommu __read_mostly; | 29 | int no_iommu __read_mostly; |
30 | /* Set this to 1 if there is a HW IOMMU in the system */ | 30 | /* Set this to 1 if there is a HW IOMMU in the system */ |
@@ -161,48 +161,6 @@ void dma_free_coherent(struct device *dev, size_t size, | |||
161 | } | 161 | } |
162 | EXPORT_SYMBOL(dma_free_coherent); | 162 | EXPORT_SYMBOL(dma_free_coherent); |
163 | 163 | ||
164 | int dma_supported(struct device *dev, u64 mask) | ||
165 | { | ||
166 | #ifdef CONFIG_PCI | ||
167 | if (mask > 0xffffffff && forbid_dac > 0) { | ||
168 | |||
169 | |||
170 | |||
171 | printk(KERN_INFO "PCI: Disallowing DAC for device %s\n", dev->bus_id); | ||
172 | return 0; | ||
173 | } | ||
174 | #endif | ||
175 | |||
176 | if (dma_ops->dma_supported) | ||
177 | return dma_ops->dma_supported(dev, mask); | ||
178 | |||
179 | /* Copied from i386. Doesn't make much sense, because it will | ||
180 | only work for pci_alloc_coherent. | ||
181 | The caller just has to use GFP_DMA in this case. */ | ||
182 | if (mask < DMA_24BIT_MASK) | ||
183 | return 0; | ||
184 | |||
185 | /* Tell the device to use SAC when IOMMU force is on. This | ||
186 | allows the driver to use cheaper accesses in some cases. | ||
187 | |||
188 | Problem with this is that if we overflow the IOMMU area and | ||
189 | return DAC as fallback address the device may not handle it | ||
190 | correctly. | ||
191 | |||
192 | As a special case some controllers have a 39bit address | ||
193 | mode that is as efficient as 32bit (aic79xx). Don't force | ||
194 | SAC for these. Assume all masks <= 40 bits are of this | ||
195 | type. Normally this doesn't make any difference, but gives | ||
196 | more gentle handling of IOMMU overflow. */ | ||
197 | if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) { | ||
198 | printk(KERN_INFO "%s: Force SAC with mask %Lx\n", dev->bus_id,mask); | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | return 1; | ||
203 | } | ||
204 | EXPORT_SYMBOL(dma_supported); | ||
205 | |||
206 | /* | 164 | /* |
207 | * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter | 165 | * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter |
208 | * documentation. | 166 | * documentation. |