1 #include <linux/dma-mapping.h>
2 #include <linux/dmar.h>
3 #include <linux/bootmem.h>
6 #include <xen/gnttab.h>
11 #include <asm/swiotlb.h>
12 #include <asm/tlbflush.h>
13 #include <asm/gnttab_dma.h>
16 #define IOMMU_BUG_ON(test) \
18 if (unlikely(test)) { \
19 printk(KERN_ALERT "Fatal DMA error! " \
20 "Please use 'swiotlb=force'\n"); \
26 gnttab_map_sg(struct device *hwdev, struct scatterlist *sgl, int nents,
27 enum dma_data_direction dir, struct dma_attrs *attrs)
30 struct scatterlist *sg;
32 WARN_ON(nents == 0 || sgl->length == 0);
34 for_each_sg(sgl, sg, nents, i) {
37 gnttab_dma_map_page(sg_page(sg)) + sg->offset;
38 sg->dma_length = sg->length;
39 IOMMU_BUG_ON(!dma_capable(
40 hwdev, sg->dma_address, sg->length));
41 IOMMU_BUG_ON(range_straddles_page_boundary(
42 page_to_pseudophys(sg_page(sg)) + sg->offset,
50 gnttab_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nents,
51 enum dma_data_direction dir, struct dma_attrs *attrs)
54 struct scatterlist *sg;
56 for_each_sg(sgl, sg, nents, i)
57 gnttab_dma_unmap_page(sg->dma_address);
61 gnttab_map_page(struct device *dev, struct page *page, unsigned long offset,
62 size_t size, enum dma_data_direction dir,
63 struct dma_attrs *attrs)
69 dma = gnttab_dma_map_page(page) + offset;
70 IOMMU_BUG_ON(range_straddles_page_boundary(page_to_pseudophys(page) +
72 IOMMU_BUG_ON(!dma_capable(dev, dma, size));
78 gnttab_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
79 enum dma_data_direction dir, struct dma_attrs *attrs)
81 gnttab_dma_unmap_page(dma_addr);
84 static void nommu_sync_single_for_device(struct device *dev,
85 dma_addr_t addr, size_t size,
86 enum dma_data_direction dir)
88 flush_write_buffers();
92 static void nommu_sync_sg_for_device(struct device *dev,
93 struct scatterlist *sg, int nelems,
94 enum dma_data_direction dir)
96 flush_write_buffers();
99 static int nommu_dma_supported(struct device *hwdev, u64 mask)
104 struct dma_map_ops nommu_dma_ops = {
105 .alloc_coherent = dma_generic_alloc_coherent,
106 .free_coherent = dma_generic_free_coherent,
107 .map_page = gnttab_map_page,
108 .unmap_page = gnttab_unmap_page,
109 .map_sg = gnttab_map_sg,
110 .unmap_sg = gnttab_unmap_sg,
111 .sync_single_for_device = nommu_sync_single_for_device,
112 .sync_sg_for_device = nommu_sync_sg_for_device,
113 .dma_supported = nommu_dma_supported,