aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2008-09-24 07:48:35 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-25 05:02:25 -0400
commit9f6ac57729724b58df81ca5dc005326759a806fe (patch)
treed9ee77c4518d83582bf1de1acf43e1834932f5f3 /arch
parentafa9fdc2f5f8e4d98f3e77bfa204412cbc181346 (diff)
x86: export pci-nommu's alloc_coherent
This patch exports nommu_alloc_coherent (renamed dma_generic_alloc_coherent). GART needs this function. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/pci-dma.c31
-rw-r--r--arch/x86/kernel/pci-nommu.c39
2 files changed, 32 insertions, 38 deletions
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 0a1408abcc62..4e612d20170a 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -134,6 +134,37 @@ unsigned long iommu_num_pages(unsigned long addr, unsigned long len)
134EXPORT_SYMBOL(iommu_num_pages); 134EXPORT_SYMBOL(iommu_num_pages);
135#endif 135#endif
136 136
137void *dma_generic_alloc_coherent(struct device *dev, size_t size,
138 dma_addr_t *dma_addr, gfp_t flag)
139{
140 unsigned long dma_mask;
141 struct page *page;
142 dma_addr_t addr;
143
144 dma_mask = dma_alloc_coherent_mask(dev, flag);
145
146 flag |= __GFP_ZERO;
147again:
148 page = alloc_pages_node(dev_to_node(dev), flag, get_order(size));
149 if (!page)
150 return NULL;
151
152 addr = page_to_phys(page);
153 if (!is_buffer_dma_capable(dma_mask, addr, size)) {
154 __free_pages(page, get_order(size));
155
156 if (dma_mask < DMA_32BIT_MASK && !(flag & GFP_DMA)) {
157 flag = (flag & ~GFP_DMA32) | GFP_DMA;
158 goto again;
159 }
160
161 return NULL;
162 }
163
164 *dma_addr = addr;
165 return page_address(page);
166}
167
137/* 168/*
138 * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter 169 * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter
139 * documentation. 170 * documentation.
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index 1c1c98a31d57..c70ab5a5d4c8 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -72,43 +72,6 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
72 return nents; 72 return nents;
73} 73}
74 74
75static void *
76nommu_alloc_coherent(struct device *hwdev, size_t size,
77 dma_addr_t *dma_addr, gfp_t gfp)
78{
79 unsigned long dma_mask;
80 int node;
81 struct page *page;
82 dma_addr_t addr;
83
84 dma_mask = dma_alloc_coherent_mask(hwdev, gfp);
85
86 gfp |= __GFP_ZERO;
87
88 node = dev_to_node(hwdev);
89again:
90 page = alloc_pages_node(node, gfp, get_order(size));
91 if (!page)
92 return NULL;
93
94 addr = page_to_phys(page);
95 if (!is_buffer_dma_capable(dma_mask, addr, size) && !(gfp & GFP_DMA)) {
96 free_pages((unsigned long)page_address(page), get_order(size));
97 gfp |= GFP_DMA;
98 goto again;
99 }
100
101 if (check_addr("alloc_coherent", hwdev, addr, size)) {
102 *dma_addr = addr;
103 flush_write_buffers();
104 return page_address(page);
105 }
106
107 free_pages((unsigned long)page_address(page), get_order(size));
108
109 return NULL;
110}
111
112static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr, 75static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
113 dma_addr_t dma_addr) 76 dma_addr_t dma_addr)
114{ 77{
@@ -116,7 +79,7 @@ static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
116} 79}
117 80
118struct dma_mapping_ops nommu_dma_ops = { 81struct dma_mapping_ops nommu_dma_ops = {
119 .alloc_coherent = nommu_alloc_coherent, 82 .alloc_coherent = dma_generic_alloc_coherent,
120 .free_coherent = nommu_free_coherent, 83 .free_coherent = nommu_free_coherent,
121 .map_single = nommu_map_single, 84 .map_single = nommu_map_single,
122 .map_sg = nommu_map_sg, 85 .map_sg = nommu_map_sg,