Skip to content

Commit a8463d4

Browse files
borntraegermstsirkin
authored andcommitted
dma: Provide simple noop dma ops
We are going to require dma_ops for several common drivers, even for systems that do have an identity mapping. Lets provide some minimal no-op dma_ops that can be used for that purpose. Signed-off-by: Christian Borntraeger <[email protected]> Reviewed-by: Joerg Roedel <[email protected]> Signed-off-by: Andy Lutomirski <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent e1f33be commit a8463d4

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

include/linux/dma-mapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ struct dma_map_ops {
7070
int is_phys;
7171
};
7272

73+
extern struct dma_map_ops dma_noop_ops;
74+
7375
#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
7476

7577
#define DMA_MASK_NONE 0x0ULL

lib/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
1818
obj-$(CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS) += usercopy.o
1919
lib-$(CONFIG_MMU) += ioremap.o
2020
lib-$(CONFIG_SMP) += cpumask.o
21+
lib-$(CONFIG_HAS_DMA) += dma-noop.o
2122

2223
lib-y += kobject.o klist.o
2324
obj-y += lockref.o

lib/dma-noop.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* lib/dma-noop.c
3+
*
4+
* Simple DMA noop-ops that map 1:1 with memory
5+
*/
6+
#include <linux/export.h>
7+
#include <linux/mm.h>
8+
#include <linux/dma-mapping.h>
9+
#include <linux/scatterlist.h>
10+
11+
static void *dma_noop_alloc(struct device *dev, size_t size,
12+
dma_addr_t *dma_handle, gfp_t gfp,
13+
struct dma_attrs *attrs)
14+
{
15+
void *ret;
16+
17+
ret = (void *)__get_free_pages(gfp, get_order(size));
18+
if (ret)
19+
*dma_handle = virt_to_phys(ret);
20+
return ret;
21+
}
22+
23+
static void dma_noop_free(struct device *dev, size_t size,
24+
void *cpu_addr, dma_addr_t dma_addr,
25+
struct dma_attrs *attrs)
26+
{
27+
free_pages((unsigned long)cpu_addr, get_order(size));
28+
}
29+
30+
static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
31+
unsigned long offset, size_t size,
32+
enum dma_data_direction dir,
33+
struct dma_attrs *attrs)
34+
{
35+
return page_to_phys(page) + offset;
36+
}
37+
38+
static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
39+
enum dma_data_direction dir, struct dma_attrs *attrs)
40+
{
41+
int i;
42+
struct scatterlist *sg;
43+
44+
for_each_sg(sgl, sg, nents, i) {
45+
void *va;
46+
47+
BUG_ON(!sg_page(sg));
48+
va = sg_virt(sg);
49+
sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va);
50+
sg_dma_len(sg) = sg->length;
51+
}
52+
53+
return nents;
54+
}
55+
56+
static int dma_noop_mapping_error(struct device *dev, dma_addr_t dma_addr)
57+
{
58+
return 0;
59+
}
60+
61+
static int dma_noop_supported(struct device *dev, u64 mask)
62+
{
63+
return 1;
64+
}
65+
66+
struct dma_map_ops dma_noop_ops = {
67+
.alloc = dma_noop_alloc,
68+
.free = dma_noop_free,
69+
.map_page = dma_noop_map_page,
70+
.map_sg = dma_noop_map_sg,
71+
.mapping_error = dma_noop_mapping_error,
72+
.dma_supported = dma_noop_supported,
73+
};
74+
75+
EXPORT_SYMBOL(dma_noop_ops);

0 commit comments

Comments
 (0)