aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn/pci
diff options
context:
space:
mode:
authorArthur Kepner <akepner@sgi.com>2008-04-29 04:00:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:12 -0400
commit309df0c503c35fbb5a09537fcbb1f4967b9ca489 (patch)
tree56a9df627a229bd64b934608b5f84d20bdaabf3a /arch/ia64/sn/pci
parenta75b0a2f68d3937f96ed39525e4750601483e3b4 (diff)
dma/ia64: update ia64 machvecs, swiotlb.c
Change all ia64 machvecs to use the new dma_*map*_attrs() interfaces. Implement the old dma_*map_*() interfaces in terms of the corresponding new interfaces. For ia64/sn, make use of one dma attribute, DMA_ATTR_WRITE_BARRIER. Introduce swiotlb_*map*_attrs() functions. Signed-off-by: Arthur Kepner <akepner@sgi.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Jes Sorensen <jes@sgi.com> Cc: Randy Dunlap <randy.dunlap@oracle.com> Cc: Roland Dreier <rdreier@cisco.com> Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Cc: David Miller <davem@davemloft.net> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Grant Grundler <grundler@parisc-linux.org> Cc: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/ia64/sn/pci')
-rw-r--r--arch/ia64/sn/pci/pci_dma.c81
1 files changed, 60 insertions, 21 deletions
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 18b94b792d54..52175af299a0 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/dma-attrs.h>
13#include <asm/dma.h> 14#include <asm/dma.h>
14#include <asm/sn/intr.h> 15#include <asm/sn/intr.h>
15#include <asm/sn/pcibus_provider_defs.h> 16#include <asm/sn/pcibus_provider_defs.h>
@@ -149,11 +150,12 @@ void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
149EXPORT_SYMBOL(sn_dma_free_coherent); 150EXPORT_SYMBOL(sn_dma_free_coherent);
150 151
151/** 152/**
152 * sn_dma_map_single - map a single page for DMA 153 * sn_dma_map_single_attrs - map a single page for DMA
153 * @dev: device to map for 154 * @dev: device to map for
154 * @cpu_addr: kernel virtual address of the region to map 155 * @cpu_addr: kernel virtual address of the region to map
155 * @size: size of the region 156 * @size: size of the region
156 * @direction: DMA direction 157 * @direction: DMA direction
158 * @attrs: optional dma attributes
157 * 159 *
158 * Map the region pointed to by @cpu_addr for DMA and return the 160 * Map the region pointed to by @cpu_addr for DMA and return the
159 * DMA address. 161 * DMA address.
@@ -163,42 +165,59 @@ EXPORT_SYMBOL(sn_dma_free_coherent);
163 * no way of saving the dmamap handle from the alloc to later free 165 * no way of saving the dmamap handle from the alloc to later free
164 * (which is pretty much unacceptable). 166 * (which is pretty much unacceptable).
165 * 167 *
168 * mappings with the DMA_ATTR_WRITE_BARRIER get mapped with
169 * dma_map_consistent() so that writes force a flush of pending DMA.
170 * (See "SGI Altix Architecture Considerations for Linux Device Drivers",
171 * Document Number: 007-4763-001)
172 *
166 * TODO: simplify our interface; 173 * TODO: simplify our interface;
167 * figure out how to save dmamap handle so can use two step. 174 * figure out how to save dmamap handle so can use two step.
168 */ 175 */
169dma_addr_t sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size, 176dma_addr_t sn_dma_map_single_attrs(struct device *dev, void *cpu_addr,
170 int direction) 177 size_t size, int direction,
178 struct dma_attrs *attrs)
171{ 179{
172 dma_addr_t dma_addr; 180 dma_addr_t dma_addr;
173 unsigned long phys_addr; 181 unsigned long phys_addr;
174 struct pci_dev *pdev = to_pci_dev(dev); 182 struct pci_dev *pdev = to_pci_dev(dev);
175 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); 183 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
184 int dmabarr;
185
186 dmabarr = dma_get_attr(DMA_ATTR_WRITE_BARRIER, attrs);
176 187
177 BUG_ON(dev->bus != &pci_bus_type); 188 BUG_ON(dev->bus != &pci_bus_type);
178 189
179 phys_addr = __pa(cpu_addr); 190 phys_addr = __pa(cpu_addr);
180 dma_addr = provider->dma_map(pdev, phys_addr, size, SN_DMA_ADDR_PHYS); 191 if (dmabarr)
192 dma_addr = provider->dma_map_consistent(pdev, phys_addr,
193 size, SN_DMA_ADDR_PHYS);
194 else
195 dma_addr = provider->dma_map(pdev, phys_addr, size,
196 SN_DMA_ADDR_PHYS);
197
181 if (!dma_addr) { 198 if (!dma_addr) {
182 printk(KERN_ERR "%s: out of ATEs\n", __func__); 199 printk(KERN_ERR "%s: out of ATEs\n", __func__);
183 return 0; 200 return 0;
184 } 201 }
185 return dma_addr; 202 return dma_addr;
186} 203}
187EXPORT_SYMBOL(sn_dma_map_single); 204EXPORT_SYMBOL(sn_dma_map_single_attrs);
188 205
189/** 206/**
190 * sn_dma_unmap_single - unamp a DMA mapped page 207 * sn_dma_unmap_single_attrs - unamp a DMA mapped page
191 * @dev: device to sync 208 * @dev: device to sync
192 * @dma_addr: DMA address to sync 209 * @dma_addr: DMA address to sync
193 * @size: size of region 210 * @size: size of region
194 * @direction: DMA direction 211 * @direction: DMA direction
212 * @attrs: optional dma attributes
195 * 213 *
196 * This routine is supposed to sync the DMA region specified 214 * This routine is supposed to sync the DMA region specified
197 * by @dma_handle into the coherence domain. On SN, we're always cache 215 * by @dma_handle into the coherence domain. On SN, we're always cache
198 * coherent, so we just need to free any ATEs associated with this mapping. 216 * coherent, so we just need to free any ATEs associated with this mapping.
199 */ 217 */
200void sn_dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, 218void sn_dma_unmap_single_attrs(struct device *dev, dma_addr_t dma_addr,
201 int direction) 219 size_t size, int direction,
220 struct dma_attrs *attrs)
202{ 221{
203 struct pci_dev *pdev = to_pci_dev(dev); 222 struct pci_dev *pdev = to_pci_dev(dev);
204 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); 223 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
@@ -207,19 +226,21 @@ void sn_dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
207 226
208 provider->dma_unmap(pdev, dma_addr, direction); 227 provider->dma_unmap(pdev, dma_addr, direction);
209} 228}
210EXPORT_SYMBOL(sn_dma_unmap_single); 229EXPORT_SYMBOL(sn_dma_unmap_single_attrs);
211 230
212/** 231/**
213 * sn_dma_unmap_sg - unmap a DMA scatterlist 232 * sn_dma_unmap_sg_attrs - unmap a DMA scatterlist
214 * @dev: device to unmap 233 * @dev: device to unmap
215 * @sg: scatterlist to unmap 234 * @sg: scatterlist to unmap
216 * @nhwentries: number of scatterlist entries 235 * @nhwentries: number of scatterlist entries
217 * @direction: DMA direction 236 * @direction: DMA direction
237 * @attrs: optional dma attributes
218 * 238 *
219 * Unmap a set of streaming mode DMA translations. 239 * Unmap a set of streaming mode DMA translations.
220 */ 240 */
221void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, 241void sn_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl,
222 int nhwentries, int direction) 242 int nhwentries, int direction,
243 struct dma_attrs *attrs)
223{ 244{
224 int i; 245 int i;
225 struct pci_dev *pdev = to_pci_dev(dev); 246 struct pci_dev *pdev = to_pci_dev(dev);
@@ -234,25 +255,34 @@ void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
234 sg->dma_length = 0; 255 sg->dma_length = 0;
235 } 256 }
236} 257}
237EXPORT_SYMBOL(sn_dma_unmap_sg); 258EXPORT_SYMBOL(sn_dma_unmap_sg_attrs);
238 259
239/** 260/**
240 * sn_dma_map_sg - map a scatterlist for DMA 261 * sn_dma_map_sg_attrs - map a scatterlist for DMA
241 * @dev: device to map for 262 * @dev: device to map for
242 * @sg: scatterlist to map 263 * @sg: scatterlist to map
243 * @nhwentries: number of entries 264 * @nhwentries: number of entries
244 * @direction: direction of the DMA transaction 265 * @direction: direction of the DMA transaction
266 * @attrs: optional dma attributes
267 *
268 * mappings with the DMA_ATTR_WRITE_BARRIER get mapped with
269 * dma_map_consistent() so that writes force a flush of pending DMA.
270 * (See "SGI Altix Architecture Considerations for Linux Device Drivers",
271 * Document Number: 007-4763-001)
245 * 272 *
246 * Maps each entry of @sg for DMA. 273 * Maps each entry of @sg for DMA.
247 */ 274 */
248int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries, 275int sn_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
249 int direction) 276 int nhwentries, int direction, struct dma_attrs *attrs)
250{ 277{
251 unsigned long phys_addr; 278 unsigned long phys_addr;
252 struct scatterlist *saved_sg = sgl, *sg; 279 struct scatterlist *saved_sg = sgl, *sg;
253 struct pci_dev *pdev = to_pci_dev(dev); 280 struct pci_dev *pdev = to_pci_dev(dev);
254 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); 281 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
255 int i; 282 int i;
283 int dmabarr;
284
285 dmabarr = dma_get_attr(DMA_ATTR_WRITE_BARRIER, attrs);
256 286
257 BUG_ON(dev->bus != &pci_bus_type); 287 BUG_ON(dev->bus != &pci_bus_type);
258 288
@@ -260,11 +290,19 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries,
260 * Setup a DMA address for each entry in the scatterlist. 290 * Setup a DMA address for each entry in the scatterlist.
261 */ 291 */
262 for_each_sg(sgl, sg, nhwentries, i) { 292 for_each_sg(sgl, sg, nhwentries, i) {
293 dma_addr_t dma_addr;
263 phys_addr = SG_ENT_PHYS_ADDRESS(sg); 294 phys_addr = SG_ENT_PHYS_ADDRESS(sg);
264 sg->dma_address = provider->dma_map(pdev, 295 if (dmabarr)
265 phys_addr, sg->length, 296 dma_addr = provider->dma_map_consistent(pdev,
266 SN_DMA_ADDR_PHYS); 297 phys_addr,
298 sg->length,
299 SN_DMA_ADDR_PHYS);
300 else
301 dma_addr = provider->dma_map(pdev, phys_addr,
302 sg->length,
303 SN_DMA_ADDR_PHYS);
267 304
305 sg->dma_address = dma_addr;
268 if (!sg->dma_address) { 306 if (!sg->dma_address) {
269 printk(KERN_ERR "%s: out of ATEs\n", __func__); 307 printk(KERN_ERR "%s: out of ATEs\n", __func__);
270 308
@@ -272,7 +310,8 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries,
272 * Free any successfully allocated entries. 310 * Free any successfully allocated entries.
273 */ 311 */
274 if (i > 0) 312 if (i > 0)
275 sn_dma_unmap_sg(dev, saved_sg, i, direction); 313 sn_dma_unmap_sg_attrs(dev, saved_sg, i,
314 direction, attrs);
276 return 0; 315 return 0;
277 } 316 }
278 317
@@ -281,7 +320,7 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries,
281 320
282 return nhwentries; 321 return nhwentries;
283} 322}
284EXPORT_SYMBOL(sn_dma_map_sg); 323EXPORT_SYMBOL(sn_dma_map_sg_attrs);
285 324
286void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, 325void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
287 size_t size, int direction) 326 size_t size, int direction)