2 * Copyright © 2016 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 #include "mock_dmabuf.h"
27 static struct sg_table
*mock_map_dma_buf(struct dma_buf_attachment
*attachment
,
28 enum dma_data_direction dir
)
30 struct mock_dmabuf
*mock
= to_mock(attachment
->dmabuf
);
32 struct scatterlist
*sg
;
35 st
= kmalloc(sizeof(*st
), GFP_KERNEL
);
37 return ERR_PTR(-ENOMEM
);
39 err
= sg_alloc_table(st
, mock
->npages
, GFP_KERNEL
);
44 for (i
= 0; i
< mock
->npages
; i
++) {
45 sg_set_page(sg
, mock
->pages
[i
], PAGE_SIZE
, 0);
49 if (!dma_map_sg(attachment
->dev
, st
->sgl
, st
->nents
, dir
)) {
63 static void mock_unmap_dma_buf(struct dma_buf_attachment
*attachment
,
65 enum dma_data_direction dir
)
67 dma_unmap_sg(attachment
->dev
, st
->sgl
, st
->nents
, dir
);
72 static void mock_dmabuf_release(struct dma_buf
*dma_buf
)
74 struct mock_dmabuf
*mock
= to_mock(dma_buf
);
77 for (i
= 0; i
< mock
->npages
; i
++)
78 put_page(mock
->pages
[i
]);
83 static void *mock_dmabuf_vmap(struct dma_buf
*dma_buf
)
85 struct mock_dmabuf
*mock
= to_mock(dma_buf
);
87 return vm_map_ram(mock
->pages
, mock
->npages
, 0, PAGE_KERNEL
);
90 static void mock_dmabuf_vunmap(struct dma_buf
*dma_buf
, void *vaddr
)
92 struct mock_dmabuf
*mock
= to_mock(dma_buf
);
94 vm_unmap_ram(vaddr
, mock
->npages
);
97 static void *mock_dmabuf_kmap_atomic(struct dma_buf
*dma_buf
, unsigned long page_num
)
99 struct mock_dmabuf
*mock
= to_mock(dma_buf
);
101 return kmap_atomic(mock
->pages
[page_num
]);
104 static void mock_dmabuf_kunmap_atomic(struct dma_buf
*dma_buf
, unsigned long page_num
, void *addr
)
109 static void *mock_dmabuf_kmap(struct dma_buf
*dma_buf
, unsigned long page_num
)
111 struct mock_dmabuf
*mock
= to_mock(dma_buf
);
113 return kmap(mock
->pages
[page_num
]);
116 static void mock_dmabuf_kunmap(struct dma_buf
*dma_buf
, unsigned long page_num
, void *addr
)
118 struct mock_dmabuf
*mock
= to_mock(dma_buf
);
120 return kunmap(mock
->pages
[page_num
]);
123 static int mock_dmabuf_mmap(struct dma_buf
*dma_buf
, struct vm_area_struct
*vma
)
128 static const struct dma_buf_ops mock_dmabuf_ops
= {
129 .map_dma_buf
= mock_map_dma_buf
,
130 .unmap_dma_buf
= mock_unmap_dma_buf
,
131 .release
= mock_dmabuf_release
,
132 .map
= mock_dmabuf_kmap
,
133 .map_atomic
= mock_dmabuf_kmap_atomic
,
134 .unmap
= mock_dmabuf_kunmap
,
135 .unmap_atomic
= mock_dmabuf_kunmap_atomic
,
136 .mmap
= mock_dmabuf_mmap
,
137 .vmap
= mock_dmabuf_vmap
,
138 .vunmap
= mock_dmabuf_vunmap
,
141 static struct dma_buf
*mock_dmabuf(int npages
)
143 struct mock_dmabuf
*mock
;
144 DEFINE_DMA_BUF_EXPORT_INFO(exp_info
);
145 struct dma_buf
*dmabuf
;
148 mock
= kmalloc(sizeof(*mock
) + npages
* sizeof(struct page
*),
151 return ERR_PTR(-ENOMEM
);
153 mock
->npages
= npages
;
154 for (i
= 0; i
< npages
; i
++) {
155 mock
->pages
[i
] = alloc_page(GFP_KERNEL
);
160 exp_info
.ops
= &mock_dmabuf_ops
;
161 exp_info
.size
= npages
* PAGE_SIZE
;
162 exp_info
.flags
= O_CLOEXEC
;
163 exp_info
.priv
= mock
;
165 dmabuf
= dma_buf_export(&exp_info
);
173 put_page(mock
->pages
[i
]);
175 return ERR_PTR(-ENOMEM
);